Is it possible to force the compiler (with a directive or something) to store a specific part of the code in a predefined area in the memory? What I want to do is to be able to calculate a checksum of some specific functions in my code, so I later can prove that they are unchanged since the last build. My thought is that if I know in which memory area these functions are located then I can simply calculate a checksum of this area. Any ideas, someone?
Hello again... I thik this can help me: http://www.keil.com/support/docs/2215.htm What do you think, anyone? / Rasmus
I thik this can help me: http://www.keil.com/support/docs/2215.htm That will be required but you may still get in trouble because of the linker moving variables. The linker will have an affect regardless of where you locate the critical code. I do not know how memory squeezed you are, but there is one solution to keeping objects constant. EACH and EVERY (global or local) variable in the critical area must be global this is raquired regardless of method and declared as extern ONLY my method below. These variables must be permanently located at absolute addresses in an assembler module. There are means (I think) for locating variables at fixed addresses in C, but the above assembler method serves me for fixed location variables. Erik
Erik, I'm afraid I don't quite understand you. Our source code is loaded into a flash EEPROM and executed from there. Variables are allocated space and stored in the RAM memory, so, how can that affect a dedicated section in the flash… or am I completely lost now… late afternoon J If I look in the target set up, it looks something like this:
FCODE(0x10000-0x4FFFF),FDATA(0x100000 - 0x130000)
Rasmus, there is some confusion here. You are referring to your source code being loaded into flash EEPROM. But 'source code' usually means text files with code in the C programming language, which are subsequently passed to a compiler and linker to obtain executable code, which is in turn loaded into flash EEPROM. So either you implemented some kind of high level language interpreter in your application or 'source code' means something different. It seems that Erik assumed that the code you were referring to was in the form of library files (*.LIB) to be fed to the linker. But from your posts it looks like the code is in a different form, and I have no idea what that form might be... - mike
It seems that Erik assumed that the code you were referring to was in the form of library files (*.LIB) to be fed to the linker. Mike has it almost right I thought .lib or .obj. Variables are allocated space and stored in the RAM memory, so, how can that affect a dedicated section in the flash When the linker process an object file, it will modify the instructions with the actual address of the variables as assigned by the linker. If a module outside the "protected code" is changed, the addresses assigned to the variables in the "protected code" will most likely change making the flash image different. Erik
Yes, sorry, I was expressing my self incorrectly. This issue is about calculating a checksum of the executable code when loaded into the flash memory. The purpose is to be able to in runtime ask the firmware to calculate and return the checksum (via the user interface). So, Erik, I still don't understand, if I tell the linker, variable data shall be stored in this area (RAM) and the code shall be stored in that area (FLASH) how can then variables outside the "protected code" affect the protected code area in the flash? My thought was that only executable code is stored in the flash, not variables, and that is also what I want to calculate the checksum on, the specific area of executable code in the flash. This is my L166 locate settings: NDATA(0x130000-0x133FFF) , NDATA0(0x130000 - 0x133FFF), FCODE(0x10000-0x4FFFF), FDATA(0x100000 - 0x130000), FDATA0(0x100000 -0x130000), HDATA(0x100000 - 0x130000), FCONST(0x10000 - 0x4FFFF), IDATA(0xF800-0xFDFF) , IDATA0(0xF800- 0xFDFF), ICODE(0x10000-0x4FFFF), NCONST(0x10000 - 0x13FFF) So I can't see how changes in data sections can affect the code sections.
So, Erik, I still don't understand, if I tell the linker, variable data shall be stored in this area (RAM) and the code shall be stored in that area (FLASH) how can then variables outside the "protected code" affect the protected code area in the flash? OK, let's try an example your checksummed code use a RAM variable called CSram. The linker locate it at, say 0x43. so the linker modify the code mov a,CSram = E500 (00 becauee unknown) to E543. Now you modify your "flexible" code and add some variables, one of which the linker locate at 0x40. this moves CSram to 0x44 so the location in the checksummed code that used to read E543 now read E544 thus, although the code is the same the hex image is different. Erik
Ok, I understand now, examples are great! (I don't understand why it took me so long…) But what if I do as you suggested in a earlier post,These variables must be permanently located at absolute addresses in an assembler module. By the way, I am still not so familiarly with the platform and the environment. I have problems with finding out the address area for the external flash EEPROM. Do you have any idea of how I can find that out? Anyway, thanks for your help / Rasmus
If you locate the code and the variables it references at fixed addresses, you have a chance of getting same binary image every time you link your program. This is not guaranteed though. The linker has the right to do optimizations like replacing absolute jumps with relative ones, reorder sections as it sees fit and so on. You have to keep an eye on those. But with some luck you could get away with it. Of course, the fixed code should be in a compiled form (.OBJ or .LIB), because the compiler output is even more sensitive to command line switches, compiler version and who knows what else. These variables must be permanently located at absolute addresses in an assembler module. You don't have to use assembler to locate your variables at fixed addresses. There are linker controls which allow you to do that: http://www.keil.com/support/docs/586.htm Same goes for locating code. If the code is contained in several .C files, you can combine them into a class using the RENAMECLASS compiler directive: http://www.keil.com/support/man/docs/c166/c166_renameclass.htm I have problems with finding out the address area for the external flash EEPROM. Hopefully you have the schematic diagram for your board. If not, you will have to figure out how the external EEPROM is wired to the MCU (address, data and chip select lines). This should give you enough information to figure out what addresses you can allocate for the EEPROM. Regards, - mike
The linker has the right to do optimizations like replacing absolute jumps with relative ones, reorder sections as it sees fit and so on. You have to keep an eye on those. But with some luck you could get away with it. someone please confirm/define: with optimization set no higher than x, the linker will not replace opcodes. You don't have to use assembler to locate your variables at fixed addresses. Read my post, I said the same just that using assembler is a whole lot easier (you do not have to define the location of each and every) Erik
"(you do not have to define the location of each and every)" Each and every what?
Each and every what? Variable sorry, got a phone call Erik
"Each and every what? Variable" You don't need to with 'C' either. Take a look at the "ORDER" directive.
OK, ORDER and specify the addr of the 1st should do it. Erik