RingBuffer on S12X

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

RingBuffer on S12X

Jump to solution
2,422 Views
Cow2k
Contributor I

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 :smileywink:

 

thanks,

markus

Labels (1)
0 Kudos
1 Solution
782 Views
kef
Specialist I

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.

View solution in original post

0 Kudos
6 Replies
782 Views
Lundin
Senior Contributor IV
Where are the volatile variables and the ISR itself? Where are the semaphores protecting the ring buffer from getting corrupted when the ISR access it at the same time as the main() program?
0 Kudos
782 Views
Cow2k
Contributor I

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.

0 Kudos
783 Views
kef
Specialist I

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.

0 Kudos
782 Views
Cow2k
Contributor I

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 :smileyhappy:

0 Kudos
782 Views
Cow2k
Contributor I
I've attached a picture of what my buffer variables look like right after calling the reset_buffer() function.  As you can see, the "elementCount" can not be set to zero... My guess is, that this is out of the same reason for which the storing of new elements in the buffer doesn't work properly. What's also to be seen in the screenshot, is that particular parts of the stack are initially not zero but some other values (always the same...)
Message Edited by Cow2k on 2009-05-13 08:13 AM
0 Kudos
782 Views
Cow2k
Contributor I

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 :smileysad:

0 Kudos