Hi, MCU: LPC2138 I am writing a code that takes data from serial port (interrupt driven) and stores it in queues. Here's an overview:
////////////// struct queue{ char *buffer; int wp; in rp; }; char buffer1[6000]; char buffer2[1000]; char buffer3[600]; char uartBuffer[100]; struct queue myQueue; void initQueue(char* bufferQueue, int size) { myQueue.buffer = bufferQueue; myQueue.wp = 0; myQueue.rp = 0; } void enqueue(char *data) { q = &myQueues; while(data[i] != '\0') { q->buffer[q->writePointer++] = data[i++]; if (q->writePointer >= q->size) q->writePointer = 0; } q->buffer[q->writePointer++] = 0; if (q->writePointer >= q->size) q->writePointer = 0; } int main () { char str[50]; UART0_init(9600); UART0_interrupt_init(); initQueue(buffer3, 600); while(1) { sprintf(str, "wp: %d rp: %d", myQueues.wp, myQueues.rp); UART0_sendstring(str); } } void UART0Isr() { UARTbuffer[i] = UART0_getbyte(); // get data until sequence completed if(/*sequence complete condition*/) enqueue(UARTbuffer); }
Now, the problem is that the controller hangs after "enqueuing" 8 sequences(all sequences are same). and the number 8 decreases if i increase the size of sequence.
if i reduce the buffer3 size to 500 or less, code works perfectly fine. for buffer3 size >= 500 ----> code hangs
if i interchange the declaration sequence of global variables like:
char buffer3[600]; char buffer1[6000]; char buffer2[1000];
it gets ok. Atleast for 1000 sequences.
if i disable all interrupts and use enqueue in main in a while loop, its runs fine.
void main() { while(1) { enqueue(sequence); //works fine here } }
Thanks for reading and advance thanks for helpful replies.
Regards, Salman.
I did the following steps to remap the interrupt vectors in to ram:
> put 0x02 in MEMMAP and copy the exception vectors to ram. (Options for Target > Asm > Define [RAM_INTVEC REMAP RAM_MODE])
> Here's my relevant startup code:
;*****************this portion i copied from other example startup.s file to mine ; Copy Exception Vectors to Internal RAM --------------------------------------- RAM_BASE EQU 0x40000000 IF :DEF:RAM_INTVEC ADR R8, Vectors ; Source LDR R9, =RAM_BASE ; Destination LDMIA R8!, {R0-R7} ; Load Vectors STMIA R9!, {R0-R7} ; Store Vectors LDMIA R8!, {R0-R7} ; Load Handler Addresses STMIA R9!, {R0-R7} ; Store Handler Addresses ENDIF ;*****************this portion was already in the startup.s file ; Memory Mapping (when Interrupt Vectors are in RAM) MEMMAP EQU 0xE01FC040 ; Memory Mapping Control IF :DEF:REMAP LDR R0, =MEMMAP IF :DEF:EXTMEM_MODE MOV R1, #3 ELIF :DEF:RAM_MODE MOV R1, #2 ELSE MOV R1, #1 ENDIF STR R1, [R0] ENDIF
But my issue remains the same. Problem still lingers. Please see if i have missed any step.
Yes. The normal prio 1 step is to download the user manual for the NXP processor.
It will describe the mapping setting for the interrupt vector table.
After you have read up on that, you can take a look at the Keil startup file.
The startup file will most probably contain the required information what you - based on your knowledge from the user manual - must do to remap the vector table.
Note also that Keil have examples that can run from RAM.
No, i didn't. and that's the issue. Can you please tell me how to do that?
So the big question here is: What have you done with your interrupt vector table?
Have you remapped it to RAM, since the application can not make use of a interrupt vector table at 0x10000?
One more thing that i would like to mention is that i have set the starting address of my code in flash from 0x10000.
It is because i am using a secondary boot loader in the controller to execute the code at this address. I think this has something to do with the above mentioned issue because when i changed the rom address setting back to 0x000 and executed the code directly. it worked...even in those situations in which it didn't while using code starting address of 0x10000 in rom.
Well,
Lots of use of variables we can't see the data type of. Are they global? Ans: Most of the variables are global. yes
Your serial ISR is using an array to store the temporary byte received before enqueue - why? Ans: Because the idea is to store the sequence when it gets completed successfully. Not if it gets corrupted (here corruption implies from external source).
enqueue() takes a pointer to a char as parameter. How would it know how many characters there are in the array? Does your UART ISR even pick up multiple characters - you using receive FIFO? Ans: It would not know. but we will since it will be null terminated.
Why does your enqueue also insert a zero? You don't expect to be able to print the queue buffer directly as a C string? Remember that it's a ring buffer... Ans: No. Idea here is to store multiple strings in a single linear buffer with 0 as delimiter.
How can you have a queue with a write pointer named "wp" but code that plays with a write pointer named "writePointer"? Ans: ok that's my mistake ...replace writePointer and readPointer with wp and rp.
I just cutoff all the unrelated portion of code in order to highlight the main problem. Thanks.
It hurts to see your code.
Lots of use of variables we can't see the data type of. Are they global?
Your serial ISR is using an array to store the temporary byte received before enqueue - why?
enqueue() takes a pointer to a char as parameter. How would it know how many characters there are in the array? Does your UART ISR even pick up multiple characters - you using receive FIFO?
Where do you reset your variable "i"?
Why does your enqueue also insert a zero? You don't expect to be able to print the queue buffer directly as a C string? Remember that it's a ring buffer...
How can you have a queue with a write pointer named "wp" but code that plays with a write pointer named "writePointer"?
For some reason, I can not for the life of me understand the meaning of posting random typed text and ask for help. What was wrong with posting the real code? That the real code could possibly make sense? What you typed is just nonsense since it does not compute. It does not compile. That makes it basically just a sequence of more or less random characters that we can't relate to.
View all questions in Keil forum