|
From: | David Brown |
Subject: | [avr-gcc-list] Re: Allocating variables to a fixed address |
Date: | Tue, 12 May 2009 12:23:26 +0200 |
User-agent: | Thunderbird 2.0.0.21 (Windows/20090302) |
Robert von Knobloch wrote:
David Kelly wrote:On Mon, May 11, 2009 at 08:21:37AM -0600, Weddington, Eric wrote:Sounds to me as if you are making the "bootloader" too big andshould simply link an entire application for every possible target. What you are doing would make more sense if the loadablemodules could run out of RAM.That would be no use, the loadables must be non-volatile. This is a tester that will be sent to a factory (somewhere). When a new product is to be tested, I can e-mail them the test routine which they then burn into flash (each of these is 0x900 bytes, there can be up to 0x0a of them).Why is this method superior to having a regular bootloader, and you have N applications, where each application is the individual test routine and the common portion? Why do you have create this custom interface which has its own set of problems? Alternatively, creating a custom Makefile to handle building 10 different applications is certainly easier in comparison.I agree, thats how I would handle it. Either build a custom linked application for each customer or provide the customer with the tools to build one of their own. What he is trying to do is in effect create a run time program linker.Eric, David etc., Thanks for the suggestions but it seems I haven't explained the problem properly.
I think you gave enough information, and Stu's (and my) other post gave a good way to implement your requirements. It might mean more changes to your code than you'd like at this stage. But the key idea is to have only a single address that must be fixed and known to both sides - functions are accessed via a table of pointers at this address (or even pointed to from this address), and global data is accessed as a struct whose address is determined by one of these functions. This adds a little overhead, but it keeps everything flexible and with a minimum of fixed addresses. It also avoids all issues with assembly (or C) jump tables, optimisations and inlines, variable initialisations, etc.
The end users of this equipment will be factory operators who cannot compile, link or do any of these software things. Thus I have developed an extremely simple (read idiot-proof [i hope]) interface to use with a terminal program (minicom, teraterm etc.). This is far more simple than any existing boot loader (OK, I *could* write my own, but I'm too far along now). The loadable elements are small (0x900) and will only ever be updated one at a time. If I compiled and linked the whole lot, then each small change would requite the sending & loading of 64k of code, which I think is much too much for these people (and, for compatibilty with modern PCs, the comms. is run over a USB virtual RS-232 port which produces far too many serial errors for my liking - but that's another issue).
I understand why you might want to keep these modules small.On the other hand, if you are getting serial errors using an USB to RS-232 converter, you have other problems - I have systems that regularly transfer megabytes of program code (not on an AVR!) at over 1 MBaud via these devices. Typical causes of USB to RS-232 problems include use of a broken terminal program (i.e., hyperterminal - it's a piece of <beep>), reliance on hardware handshaking, reliance on careful timing (timing is unreliable via a converter), poorly matched baud rates, dodgy cables, or bad hardware. Your problem here needs identifying and fixing - regardless of how you want to send the code.
I have the entire application written and am knocking the last bugs out now. I confess that GCC seems to me to be mostly something to fight with, perhaps I have been spoiled in the past using manufacturer's C compliers that were tailored especially for the target.
Most experienced gcc users find the opposite to be true - they find commercial compilers irritatingly limited after the flexibility of gcc and related tools. But it's not always easy to find exactly how to do things with any given tool.
I simply require a way to fix absolutely this jump table in memory. Whether I write it in C or assembler seems to me to be irrelevant, as is using an array of pointer to functions, because I still have the problem of fixing these at absolute addresses. If anyone knows a way to do this, I would very much appreciate it.
Put the code you want into a specific section (such as ".jumptable"), and add the compiler flag "-Wl,--section-start=.jumptable=0x0100" to put the code at a specific address.
Use an array of pointers to functions, not the functions themselves, because that's the only way you can be sure of the sizes and offsets.
Many thanks for all the input, Robert.
[Prev in Thread] | Current Thread | [Next in Thread] |