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.
Now my question is why is it necessary to not to overlap the RAM area of bootloader in application code. ?
It is not necessary. I suppose that in your usage of "protect" you actually mean "not set to 0" upon application startup code execution.
I miss read your previous post. The bootloader and application can share RAM - because the bootloader should never run after the startup process. Note that you could have intermittent software layer between the application and bootloader that _can_ run alongside the application and do require RAM - be careful there.
Yeah i mean to protect by setting application code IRAM1 start address at 0x40 or ox50 for safety lets say. Just enough not to overlap the first 64 bytes of ram.
Other then that changing the iram1 to 0x100 or 0x1000 does not makes sense.
The bootloader and application can share RAM Ok.
But that would be very clear and visible if there is any such software layer. Lets say i am using the default SD/MMC bootloader provided by nxp for LPC2100 series.
In that case what i apprehended is right?
Hi Salman Liaquat,
UM10211 Chapter 29: LPC23XX Flash memory programming firmware
3.2.8 RAM used by ISP command handler ISP commands use on-chip RAM from 0x4000 0120 to 0x4000 01FF. The user could use this area, but the contents may be lost upon reset. Flash programming commands use the top 32 bytes of on-chip RAM. The stack is located at RAM top - 32. The maximum stack usage is 256 bytes and it grows downwards.
UM10114 Chapter 21: LPC21xx/22xx Flash memory controller
5.11 RAM used by ISP command handler ISP commands use on-chip RAM from 0x4000 0120 to 0x4000 01FF. The user could use this area, but the contents may be lost upon reset. Flash programming commands use the top 32 bytes of on-chip RAM. The stack is located at RAM top - 32. The maximum stack usage is 256 bytes and it grows downwards.
In my case, 0x40000200 is good enough.
http://www.keil.com/forum/13707/
John Linq, 8-Apr-2009 10:27 GMT
2. Set IRAM1 Start: 0x40000200 Size: 0x7E00
I have no longer worked on the ARM platform for quite a long time. I can not remember correctly that why I reserve 200 bytes. But I do remember that I had found some reasons/explanations before, just fail to recall them. I believe the reason is related to 1st and 2nd bootloaders, ISP/IAP needs.
GNU tool-chain linker script
ieee.ucsd.edu/.../LPC2148-ROM.ld
/* RAM used by boot loader: 0x40000120 - 0x400001FF (223 bytes) for ISP variables */ /* 0x40007FE0 - 0x4000FFFF (32 bytes) for ISP and IAP variables */ /* 0x40007EE0 - 0x40007FE0 (256 bytes) stack for ISP and IAP */
mbed.org/.../LPC1768.ld
MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 512K ram (rwx) : ORIGIN = 0x100000C8, LENGTH = 0x7F38 ram1(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K ram2(rwx) : ORIGIN = 0x20080000, LENGTH = 16K }
Nice links
Thankyou