I am using LPC1788 and have successfully written EMC code. H57V2562GTR (SDRAM 16Mx16) is interfaced with the controller. Two ICs are used in parallel to write 32Bytes (16MSB in one chip and 16LSB in other). I have tested the code and it works fine (The read and write operations).
I know that by using __attribute__((at(address))) i can define variables at specific memory address.
Will i have to initialize the EMC before defining the variables in the external memory area?
Dear John, you are absolutely correct. When i uncheck the box and generate the map file, i observed that all the variables base address start from 0x1000xxxx which is on-chip ram for lpc1788. and if i check the box, then the base address start from 0xA000xxxx which is SDRAM address.
But i get the following error in the command window when debugging in simulator.
*** error 35: undefined line number WS 1, 'i *** error 65: access violation at 0xA0064000 : no 'read' permission when the code executes this specific line: Dummy = *((volatile uint32_t *)(SDRAM_BASE_ADDR | (0x32<<13))); #define SDRAM_BASE_ADDR 0xA0000000
Why do i get access violation when i am declaring to the linker that there exist memory in the range 0xa0000000 - 0xafffffff?
the error comes when i uncheck the box.
Also, i add my customized lib file to the project. do i have to enable the same settings in the project that generates library file also?
The same error comes even if i check the box.
Not sure how you configure your project, but the basic/important concept is:
> Why do i get access violation
Author: Hans-Bernhard Broeker Posted: 24-Apr-2013 20:24 GMT
What you have to do is initialize your memory subsystem to a workable state before your code accesses those variables [ in any way ] --- and because the first such access is likely the initialization performed by the startup code, that tends to mean you have to do that inside the startup code. The alternative is to mark those variables as "not to be initialized by start-up code" and delay the initial write until you're done initializing the memory subsystem.
Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT SDRAM_H57V2562GTR_Init IMPORT __main LDR R0, =SystemInit BLX R0 LDR R0, =SDRAM_H57V2562GTR_Init BLX R0 LDR R0, =__main BX R0 ENDP
The =SDRAM_H57v2562GTR_Init code calls the function where i have initialized the Hynix SDRAM. The RAM code is same as the example code (except that some timings are modified as per datasheet of the IC).
Also, the line, on execution of which the error is reported in the command window is in the SDRAM_H57V2562GTR_Init function.
on execution of following line
Dummy = *((volatile uint32_t *)(SDRAM_BASE_ADDR | (0x32<<13)));
void SDRAM_H57V2562GTR_Init( void ) { volatile uint32_t i; //Does this cause a problem?? volatile unsigned long Dummy; ... }
The SDRAM initialization function defines 2 variables. Think this is not allowed before calling _main from the start-up (which initializes the RAM memory).
Note that the function have two auto variables, i.e. variables stored on the stack. This isn't really different from the assembler startup file using push/pop to store register content on the stack.
The startup file should prepare all RAM regions so they are accessible, and make sure the stack is usable.
That __main function may zero-initialize BSS and assign initial values to DATA globals. But __main() is called in a context where the stack is already usable.
Thank you Per for highlighting that. But the original problem still remains unsolved.
Do you still only get access errors when simulating, but not when running on real hardware?
That might means that your RAM setup code is working (the real hardware is happy with it). But have you verified if the real hardware actually manages to access the external memory and store data there? Have you tried to write different values to the external memory range and then read back the different values and see if you got the same values you did write?
Next question is if you have done everything correct, to let the simulator know about the existence of RAM in that address range. The real hardware don't need to know. As long as the memory controller is configured, the processor will just try to perform external memory accesses and you either manage - or you don't manage - to store data or read back data from the external memory. The simulator, on the other hand, can scream (since the main goal is to debug code) if any access is made to an address that the simulator (note: simulator - not linker) doesn't know exists.
Have you tried to write different values to the external memory range and then read back the different values and see if you got the same values you did write? Yes, the software works well when debugging the hardware.
The simulator, on the other hand, can scream (since the main goal is to debug code) if any access is made to an address that the simulator (note: simulator - not linker) doesn't know exists. In that case, i will not push further. only that i wanted to check if the there was any way of solving this.