hello everybody,
I'm new to µC programming. my first project includes working with the SCI interface. for this purpose I wanted to use a ringbuffer, to which my SCI-ISR write every received byte.
the ISR itself works fine but my ringbuffer seems to be corrupt. I've already slightly rewrote the code so I can test it on the PC where everything goes without errors.
but when I execute the code on the µC (MC9S12XDT512), there are some pretty strange things going on. here is the code I wrote:
/* Includes */ #define TRUE 1 #define FALSE 0 /* HEADER HAPTIC */ #define BUFFERSIZE 10 struct ringBuffer { unsigned int elementCount; unsigned int posRead; unsigned int posWrite; unsigned char stack[BUFFERSIZE]; }; struct knobDevice { struct ringBuffer *buffer; }; struct knobDevice pr1000_SCI0; struct ringBuffer pr1000_buffer; /* FUNCTIONS HAPTIC */ void reset_buffer(struct ringBuffer * buffer){ buffer->posRead=0; buffer->posWrite=0; buffer->elementCount=0; } unsigned int increment_buffer(unsigned int i) { //this is used to "increment" the read&write position of a ringbuffer, when it touches BUFFERSIZE we reset to 0 return (i+1)==BUFFERSIZE ? 0 : i+1; } unsigned char get_buffer(struct ringBuffer * buffer) { //empty buffer has to be handled before function call! unsigned int posRead; posRead=buffer->posRead; buffer->posRead=increment_buffer(buffer->posRead); buffer->elementCount--; return buffer->stack[posRead]; } void put_buffer(struct ringBuffer * buffer, unsigned char storeThis) { //when buffer is full, we overwrite it from the beginning buffer->stack[buffer->posWrite]=storeThis; buffer->posWrite=increment_buffer(buffer->posWrite); if(buffer->elementCount<BUFFERSIZE) { //only increment elementcount if we didn't overwrite existing data buffer->elementCount++; }else { //buffer is overwritten, increment posRead so we don't get the just inserted data when reading next time buffer->posRead=increment_buffer(buffer->posRead); } } unsigned char isempty_buffer(struct ringBuffer * buffer) { if(buffer->elementCount>0) { return FALSE; }else{ return TRUE; } } void main(void){ unsigned char i; pr1000_SCI0.buffer= &pr1000_buffer; reset_buffer(pr1000_SCI0.buffer); while(1){ for(i=0;i<5;i++){ put_buffer(pr1000_SCI0.buffer, i);} } }
I use ICC for compiling and NoICE for debugging.
when I run the code and watch the buffer, right after doing the "reset_buffer", the buffer.elementCount=0xFF00 and the buffer's stack is 00,00,00,1F,00,00,00,D0,00,3F
also I am only able to modify a few of my buffer variables from within NoICE...
what am I doing wrong? I guess there are some memory issues so my variables are stored in a wrong area or something. unfortunately I have no idea how to verify my guess.
I'd really appreciate some hints here
thanks,
markus
Solved! Go to Solution.
Looks like you put your variables to EEPROM. In project settings please verify that you don't mix
MC9S12D512 device with MC9S12XD512. These have different memory maps. If your ICC version doesn't have XD512 in device list, then you should use Custom target and set data memory to 0x1000, stack pointer to 0x4000. If you are using Expanded Memory, then also please verify that it is set to 0x380000.0x3FFFFF. Also using NoICe, please don't mix D512 with XD512.
hello again,
I just found out that the programm works when I declare my structs locally inside my main()... unfortunately this is not an option for me because I have to change them inside my ISR later on
in NoICE I've looked a little closer on the memoryadresses and discovered that, declaring the buffer globally, it is beeing stored from 0x0000 to 0x000E. Am I wrong or is my code trying to write to the controller's registers??
I thought the compiler had to take care of the correct initialization of variables. Don't know if it helps, but my map-file looks like this:
Area Addr Size Decimal Bytes (Attributes)-------------------------------- ---- ---- ------- ----- ------------ text 4000 0155 = 341. bytes (rel,con,rom) Addr Global Symbol ----- -------------------------------- 4000 __start 4028 _exit 402A _reset_buffer 402A __text_start 404D _increment_buffer 4069 _get_buffer 40AB _put_buffer 410D _isempty_buffer 4122 _main 4150 __HC12Setup 4155 __text_endArea Addr Size Decimal Bytes (Attributes)-------------------------------- ---- ---- ------- ----- ------------ bss 0800 0012 = 18. bytes (rel,con,rom) Addr Global Symbol ----- -------------------------------- 0800 __bss_start 0800 _pr1000_SCI0 0802 _pr1000_buffer 0812 __bss_end
sorry for the triplepost, but post editing seems to be allowed only a few minutes after sending a post.
Looks like you put your variables to EEPROM. In project settings please verify that you don't mix
MC9S12D512 device with MC9S12XD512. These have different memory maps. If your ICC version doesn't have XD512 in device list, then you should use Custom target and set data memory to 0x1000, stack pointer to 0x4000. If you are using Expanded Memory, then also please verify that it is set to 0x380000.0x3FFFFF. Also using NoICe, please don't mix D512 with XD512.
thanks alot!
I've simply selected the only available S12X in my compiler, which is a S12XDP but I use a S12XDT. By following your advise with the custom target I've got everything working now
well, in this version I do not make use of the IRS as I wanted to make sure the buffer itself is working,
which it doesn't