g21k, runtime header and architecture file (ADSP21xxx)

Hi all,

I now think I don't understand how the C Tools from ADI work and I thought if I write down my understandings maybe somebody can pin point where is my simple model wrong (quoted test below is from "C Tools Manual").

The C tools from ADI are a set of three elements:

- The G21K C Compiler > - A Runtime Library of C Functions > - The CBUG C Source-Level Debugger

Let's forget about the CBUG and just look at the first two. The G21k is a GCC port to the ADSP21xxx architecture and is essentially a utility to call various other parts (compiler, assembler, linker, ...).

The Runtime Library is a set of functions that allow signal handling and floating point operations.

Now, when the g21k is invoked it will need the "runtime header" and the "architecture file":

The runtime header controls initialization of the C > runtime environment and interrupt handling. Aspects of the runtime > environment (such as code and data placement, stack and heap > placement, and target wait states and banks) are controlled by the > architecture file.

and the whole compilation procedure is broken in several stages:

1. C Preprocessing runs the C preprocessor on the source file. Comments > are removed, macros are expanded, conditional compilation and file > inclusion are handled.

I don't see how the architecture file is used here. But maybe the header can be used if there are macros to be expanded and/or conditional compilation flags.

2. Compiling translates C language into assembly language. Command line > switches control compile-time options, such as the inclusion of > debugging information and degree of optimization..

No use of the architecture file.

3. Assembly Preprocessing runs the C preprocessor on the assembly > source file. See item 1, above in this list.

Again no use of the architecture file (at least I don't see how it can be used here).

4. Assembling translates assembly language into object code.

Here the objects are COFF objects and if cdump21k (similar to objdump on a GNU/Linux system) is used at this point we can see how the program memory instructions are stored in a section called seg_pmco, while the data is stored in a section called seg_dmda.

Unless otherwise instructed (option -mpmcode) the g21k will put code in seg_pmco and data in seg_dmda. There is the possibility that data is stored in program memory if C language extensions are used in the code. We can ignore this for the sake of this discussion.

seg_pmco and seg_dmda are directives defined in the architecture files, but at this point all objects are living in a 'limbo' waiting for being linked together and be part of the executable. Since the object code will be "relocated" by the linker (this is just my guess), it is necessary to know in which segment it should reside, therefore I think the architecture file is used in this step.

5. Linking combines individual source object files, the runtime header, and > object files from libraries into a single executable. Addresses for objects > are assigned and references are resolved to form a single executable file.

In stage 5. the directives of the architecture file will be followed to place all the previously defined section of seg_pmco and seg_dmda together, plus the seg_rth (defined in the runtime header) and the seg_init.

The runtime header provides interrupt handling, including chip reset. > When the target processor is reset, the runtime header makes calls to > routines in the C runtime library to initialize the C runtime > environment and set the state of the hardware.

Here the Manual is referring to ___lib_setup_hardware, ___lib_setup_processor, ___lib_setup_environment, which are used on reset and they make use of data residing in seg_init.

Here there's something I completely failed to understand so far: in the runtime header there are instructions which are delayed branch jumps to ___lib_int_table that I am naively assuming it will "map" my interrupt service routines which are residing (I think) in the seg_pmco segment, so that when an interrupt is latched, if the interrupt is not masked, the program execution is interrupted and instruction are fetched from the interrupt vector table which will eventually jump to my interrupt service routine (plus some stack push operations).

But where is the ___lib_int_table residing? how does it know where are my interrupt handlers? The reason for these questions is that on the hardware I am working on the seg_init and seg_rth are located in a protected area of the flash, which does not correspond to my current program, nevertheless I believe that my interrupt service routines are still mapped correctly, so I was wondering how is this possible.

The architecture file describes the software and hardware > configuration of your system. Architecture file directives specify the > placement and naming of elements of the runtime memory > environment such as the locations of the C runtime stack, runtime > header, heap, and code and data spaces

That looks pretty simple, I have my code and it will end up in seg_pmco in the location I asked for in the architecture file, the heap and the stack will be used only in a specific area of the DM and everybody is happy.

Now, I'm compiling with the before mentioned option -mpmcode=pm_main because the seg_pmco of my architecture file is pointing to a protected area of the flash and I need my code to end up somewhere else, but when I do this the code looks like "broken" in two segments, one in the seg_pmco and the other in the pm_main. This is quite a surprise to me because I had the naive idea that everything would have ended up in the pm_main. But now that I'm thinking, the whole library has been compiled with seg_pmco as the default segment and I'm assuming that every library function would end up in my seg_pmco segment. So what the heck is left in my pm_main segment then?

Since I have to load the program into the dsp through a lengthy chain of protocols (TCP/IP, NASA-CDP, CCSDS, 1553, CANbus, RS232...bingo!) and through a custom built boot loader which is capable to receive telecommands, I need to know how to stitch together all these segments and write them to the PM/DM in the proper location. I am assuming that the "proper location" would be the one that it is specified in the architecture file and/or the coff dump, so I can get all my segments of pm and dm and write them accordingly.

Someone may suggest to change the architecture file such that I can throw away the need of an -mpmcode switch, to start with. But I fear that doing so I will screw up badly since the boot loader has been created with the current architecture file and I'm not convinced I can move segments around that easily.

Another culprit is that the folks who did the boot loader implemented it such that there's no way to jump to a pm location, therefore the procedure to upload a new software would be to copy it in the pm and then let the boot loader copy it into the flash. At this point the command to boot the sector just written will copy it to pm and then jump to the correspondent pm address. I still haven't understood what happen to the data memory at this point, given that the seg_dmda is supposed to hold

data memory global variables and string literals/ > default location of static variables

but the boot loader does not care about initializing the data memory. So what about the newly loaded program? It is evident in the coff dump that seg_dmda is full of stuff. The previous team that was working on the software used to do the pm dump from the program loaded with a jtag and then uploaded onboard with the boot loader. But they never took care about the data memory. Well, I must say the previous team was dismissed because the software does not work "as expected"... (ouch).

Ok, I'm sorry about the lengthiness of this post but at least while writing it I sorted out many details going through the Manual. Hope somebody else would find the time to straighten my thoughts in case their too far off the road.

Al

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
 Click to see the full signature
Reply to
alb
Loading thread data ...
[snip a billion lines]

Isn't VisualDSP only like $2000 ??? I can't believe after all this that it wouldn't be worth it to just invent in the AD compilers?

Years ago I built g21k and decided it was not worth it in terms of productivity. ie. fighting the build environment vs. the actual problem.

I know the inventment seem high at first but VisualDSP with a board which implements BTC can be invaluable.

Mark DeArman

Reply to
Mac Decman

IMHO understanding how something works is always worth it. At least being aware about the culprits will empower you with the possibility to choose. I cannot argue against your proposal to switch to VisualDSP, but I am afraid that your answer is far off topic. I haven't asked for an alternative and the motives behind using g21k haven't (intentionally) being explained either.

Now If you are asking for an explanation, that's a whole different topic which has nothing to do with the technical details I was interested into, but I will be more than happy to share my reasons if you really like to listen to them.

I am happy you decided what's best for you, I can ensure you I did the same and I am also aware that any choice might be the wrong one.

you decided to invest money to enable you to proceed and I respect your choice, I dediced to invest time. And by the way, I think I would be asking the very same questions about VisualDSP, since I need to understand how the tools work (not *if* they work at all).

Reply to
alb

Well I was not aware that usenet had a strict question/answer format. I was just asking a question as a point of discussion.

Fair answer, I have a hard time deciding between time and money myself a lot of the time. Especially if it is an area I have a lot of interest in and I think the project would be fun!

Mark DeArman

Reply to
Mac Decman

Mac Decman writes: [...]

The g21k *is* an AD compiler, nobody is inventing a compiler here. The point that made it attractive to me was the license type and the possibility to use it in a *nix environment. On top of it, I believe that I - in principle

- can figure out how the compiler works looking at the code directly, something impossible with a product like VisualDSP.

I agree I probably should have asked my questions in a bit more straight forward way. So probably here they are:

  1. how the runtime environment knows where my interrupt handlers reside in the Program Memory?
  2. which process in the runtime environment is taking care of configuring the data memory? Do I need to explicitly configure the data memory before running the program?

Al

Reply to
alb

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.