Hello All
I am working on a project using a STR912 ARM9 core microcontroller with 96k internal RAM. I also have a external RAM with 1MB. Since i begin to run low on internal RAM, i want to transfer the whole stack to the external RAM so everything is running from there.
Now i am wondering how to implement this. I am using Keil µVision and the Keil Compiler. In the target options i can specifiy my external RAM but as soon as i declare it as on the only default memory, the code won't execute on the microcontroller anymore. My guess is that the EMI configuration (it's a c function in my main.c file) needs to be called from the Startup code before the stack gets initialized but i don't really know how to implement this. Has anybody the answer or a example code where this is done ? I searched for this info but haven't found anything. Oh the startup code i use is the one provided by Keil for the STR912 device.
Thanks for reading
Florian
BLX is both an ARM and THUMB instruction. It is used to branch, load the LR and assume the mode of the called function (either ARM or THUMB). It is safe to use when calling ARM to ARM, THUMB to THUMB, ARM to THUMB and THUMB to ARM. To return, the function that was called should use BX LR. This will cause the proper state to be restored. BL can only be use calling ARM to ARM or THUMB to THUMB, it cannot switch modes.
I understand that THUMB BLX switches to ARM instruction set (depending on target address bit 0 of course). So it merely depends on the instruction set used to compile his function. BLX is fine if it is ARM code, if it is THUMB code he must use BL. Please do correct me if necessary so that we don't confuse the OP!
True - good point, we do need to load the LR. But I believe (without know the full details) that he was calling thumb code so BL would be just as wrong/bad. I think BLX is available on the ARM9, so that may be the best choice. (easier than loading LR by hand)
BX is correct, especially if your C-code is thumb.
But that is not the point. If he does not use BL and placed code after the BX branch, guess what would and would not happen...in other words: If you want your code to return to the first instruction after a branch, BL if your best friend.
Can you be more specific than "it does not work?"
What happens when you step into the EMI_Configruation Function?
Just a quick reply - very busy. Why not call your function using the BL instruction...?
Hello
I tried to call the c-function from the main routine for configuration of the EMI in the startup code but it doesn't work.
Here is the c-function:
void EMI_Configuration(void) { // GPIO7 Configuration //configure EMI A16, A17, A18, CS0, CS1 pin GPIO 7.0, 7.1, 7.2, 7.6, 7.7 GPIO_InitTypeDef GPIO_InitStructure2; EMI_InitTypeDef EMI_InitStruct; GPIO_DeInit(GPIO7); GPIO_StructInit(&GPIO_InitStructure2); GPIO_InitStructure2.GPIO_Direction = GPIO_PinOutput; GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7; GPIO_InitStructure2.GPIO_Type = GPIO_Type_PushPull; GPIO_InitStructure2.GPIO_Alternate = GPIO_OutputAlt2 ; GPIO_Init (GPIO7, &GPIO_InitStructure2); GPIO_InitStructure2.GPIO_Direction = GPIO_PinOutput; GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure2.GPIO_Type = GPIO_Type_PushPull; GPIO_InitStructure2.GPIO_Alternate = GPIO_OutputAlt3 ; GPIO_Init (GPIO7, &GPIO_InitStructure2); GPIO_EMIConfig(ENABLE); EMI_DeInit(); EMI_StructInit(&EMI_InitStruct); EMI_InitStruct.EMI_Bank_IDCY = 0x3 ; EMI_InitStruct.EMI_Bank_WSTRD = 0x3 ; EMI_InitStruct.EMI_Bank_WSTWR = 0x3 ; EMI_InitStruct.EMI_Bank_WSTROEN = 0x2; EMI_InitStruct.EMI_Bank_WSTWEN = 0x2; EMI_InitStruct.EMI_Bank_MemWidth = EMI_Width_HalfWord; EMI_InitStruct.EMI_Bank_WriteProtection = EMI_Bank_NonWriteProtect; EMI_Init( EMI_Bank0, &EMI_InitStruct); EMI_Init( EMI_Bank1, &EMI_InitStruct); }
And here the call from the startup:
; Setup External Memory Interface IMPORT EMI_Configuration MOV SP,#0x4000000 ADD SP,SP,#0x10000 LDR R0, =EMI_Configuration BX R0
Can anybody tell me where the problem is ? Can i even call a c-function directly from the startup code ? As it's possible with other compilers. If it's not possible to call a c-function, has anybody got an example for configuration of the EMI in ASM for the STR9xx device ?
First let me say thanks for the answer and sorry that i only reply now as i just came back from vacations.
Are there any examples somewhere where it's shown how to do this ? Since i am a beginner in ARM programming and never had to mess with a startup code before it's not too clear to me how to implement this and i haven't found any example startup code to see how to do this.
Thanks again.
Yes, you need to configure the EMI BEFORE the external memory is used. This will need to be done before __main is called in the startup.s file.
You should be able to convert your C function to assembly in the startup file without too much trouble.
If you are having too much trouble, you could call the C function from the startup file directly before you call __main. Just make sure you have at least a small, valid stack in the 96k of RAM and that you do not do anything that would require the setup that __main does to be called (such as counting on the initial value of a variable)
View all questions in Keil forum