This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
I am trying to run unit tests written with CppUTest on the simulator and then the actual target. I am forced to use CCS 3.3.38 because my company uses it, and I am using Code Generation Tools v5.2.4.
After figuring out a whole slate of problems on my own (ranging from memory map to choosing the correct addressing mode in the simulator), I finally got stuck because of a strange crash I get in malloc(). I am linking rts2800_ml_eh.lib, because I need the large memory model, as well as exceptions, for CppUTest.
I single-stepped into malloc() in assembler, where this code can be found just before the crash:
32D9E3 06A6 MOVL ACC,@XAR6
32D9E4 0901 ADDB ACC,#1
32D9E5 86A9 MOVL XAR2,@ACC
32D9E6 761F MOVW DP,#0x4095
32D9E8 C53C MOVL XAR7,@60 ; what exactly is this supposed to do?
32D9E9 3E67 LCR *XAR7 ; jumps to address 0x000000 and subsequently crashes
It seems little wonder that it crashes upon the LCR instruction. From what I can assertain, probably a call to _lock() should be in this place.
I am not very familiar with this particular assembler dialect, but I would take the statement just before to mean "load the address contained in the fixed location 60 (dec) into XAR7". There is, however, nothing useful at that address (0x00000000) and why should there be? Unless _lock() and _unlock() have been registered (in which case they would point to the functions concerned), they should point to _nop() -- also a function and not a fixed address.
There are many more similar accesses to addresses contained at @56, @58 and @60 throughout the code generated from memory.c. There is nothing in the C code to suggest anything is read from any fixed address, e.g. like the interrupt table.
What is happening here? Should there be anything at 56..60 dec (0x0038..0x003C)?
How do I know that the library has been initialized correctly? After doing "Reset CPU" in the simulator, SP is set to 0x0000. I find that strange, since my .cmd file says:
PAGE 1 : /* Data Memory */
RAMM : origin = 0x000080, length = 0x000800
/* ... */
.stack : RUN = RAMM,
RUN_START(_HWI_STKBOTTOM),
RUN_END(_HWI_STKTOP),
PAGE = 1
I would take this to mean that SP should be 0x0080 not 0x0000?
Your help would be much appreciated, also what I might be missing and any relevant documents (spru514 and spru430 have not helped me so far).
Thanks a lot
Arnd
P.S. spru430 does not do a particularly good job defining the '@'-operator. One can infer that @var means "the contents of var" mostly from comments in example code, from which I would conclude that @number means the contents at that address. However, when I change the value in the debugger before executing the instruction, XAR7 does not contain the new value, even though memory does.
Hello Arnd,
You interpreted the address wrong. You have to consider the data page load.
Data Page = 0x4095
Adress = DataPage * 64 + relativeAdress = 0x4095 * 64 + 60 = 0x10257C
Makes this address more sense? Which MCU are you using?
A got overview about the addresses will give the compiled *.map file. I guess there is something wrong with stack or heap.
Regards,
Matt
Hello Matt,
Thanks a lot. This makes totally sense (I did try an offset of 60 from 0x4095 but didn't realize I had to multiply the value in DP by 64...).
Bingo -- I come out at _lock! Which is set to 0x00000000. Clearly, I seem to be have an initialization isssue.
Given the source code I saw in _lock.c, this is unexpected nevertheless:
_CODE_ACCESS void _nop()
{
/* Do nothing. */
}
_DATA_ACCESS void (* _lock)() = _nop;
_DATA_ACCESS void (*_unlock)() = _nop;
Instead of being initialized to an empty function, as the code would imply, it is obviously initialized to zero.
I explicitly initialized _lock and _unlock to point to _nop() in my main.cpp:
#include <_lock.h>
int main(int argc, char** argv)
{
std::_lock = std::_nop; /* initialize _lock() and _unlock() */
std::_unlock = std::_nop;
/* ... */
}
The crash went away. What remains is an uneasy feeling about RTS initialization. Something seems to be wrong.
By the way, these unit tests have run successfully under Windows/MinGW and they worked correctly (writing results into a RAM buffer) on the IAR Embedded Workbench for ARM simulator, with no modifications and no need to debug.
The C28335 on the other hand not only takes a lot of detailed linker and simulator setup, but I actually find myself adding strange initialization code and debugging run time libraries in Assembler...
Clearly, this is no MCU for the faint-hearted...
Regards,
Arnd
Looking back at this problem after some time I realize that the initialization issue I was facing was with the startup code - c_int00 not being executed.
In order for this to be properly linked and executed, I had to enable the -c linker option, after which the root cause for the above problems went away.