Ok, attached is a project exhibiting the problem. I've run this both on the target hardware and in the simulator. On the hardware, it reads from address 0 (or an offset from it). In the simulator, it fails within queue_pop() on an unitialized memory access during the computation of the 'src' pointer.
I used the volatile pointer (const unsigned char * volatile src) and indeed the compiler did not optimize away 'src' so I can see it in the debugger. And it indeed holds NULL.
Note that I ran this code initially with the default compiler options as setup by the new project wizard, and the code ran just fine. But then I put in the settings we are using on our project, and recompile, it then fails. Here's what we are using for our project (copied from our makefile):
# Default compilation flags
# -F2 : Use ELF/Dwarf output
# -Ccs08 : Generate code for HCS08
# -Cc : Allocate constant objects into ROM
# -Ms : Small memory model
# -Os : Optimize for size
# -Ou : Optimize dead assignments
# -Of : Create sub-functions for common code
# -OnCstVar : Disable const variable by constant replacement
# -OnPMNC : Disable code generation for NULL point to member check
# -Tue1 : Make enums a single unsigned byte
#
# It isn't clear from the documentation whether this is allocate local variables
# into registers or register optimization. This "-Or" is discussed on p. 246
# and p. 401 of the compiler documentation, and one says it causes code bloat
# (register allocation) and the other says it reduces code size (register
# optimization).
# -Or : Allocate local variables into registers
CFLAGS = -F2 -Cs08 -Cc -Ms -Os -Ou -Of -OnCstVar -OnPMNC -Or -Tue1
A couple notes. First, we use a command line based build using GNU make. We do not use the IDE. Second, we invoke the debugger directly on the command line. However, the sample project I've attached does use the IDE, and exhibits the same problem.
Finally, I started tweaking options. The problem seems to be the "-Or" option. When I remove this option, the code runs just fine. Now, we are unclear as to what this option really does (see the above note). Looking at the help file (Compiler_HC08.chm) it says two (seemingly contradictory) things about this option.
-Or: Allocate Local Variables into Registers
Allocate local variables (char or int) in registers. The number of local variables allocated in registers depends on the number of available registers. Use this option when using variables as loop counters or switch selectors or when the processor requires register operands for multiple operations (e.g., RISC processors). Compiling with this option may increase your code size (spill and merge code).
However it also says:
-Or: Register Optimization
When accessing pointer fields, this option prevents the compiler from reloading the pointer address for each access. An index register holds the pointer value across statements when possible.
We aren't sure which actually is the case. Similar language is found in the PDF documentation (Compiler_HC08.pdf) on p. 246 and p. 401 (in the same respective order as above).
Any insight? Are we misusing options, or does this appear to be a compiler issue?
Thanks for the help,
Pete
Queue.zip
Message Edited by t.dowe on 2009-10-26 01:30 PM