Hi,
I am currently developing a project with CW 10.1 on a K60 MCU.
I have successfully managed to place my code in RAM but I have encountered some issues while performing math operations which call for library functions. Here follows some sample code:
main.c:
#include <stdio.h>
#include <math.h>
#include "derivative.h" /* include peripheral declarations */
#pragma define_section text ".text" ".text" ".text" far_abs RX
#pragma define_section RAMCode ".RAMCode" ".RAMCode" ".RAMCode" far_abs RX
__declspec(RAMCode) int myRAMfunction(int cnt);
int main(void)
{
int counter = 0;
for(;;) {
counter++;
counter = myRAMfunction(counter);
}
return 0;
}
__declspec(RAMCode) int myRAMfunction(int cnt)
{
cnt = __aeabi_idiv(cnt,3);
cnt = cnt /3;
return cnt;
}
Linker command file:
MEMORY {
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000001E0
m_text (RX) : ORIGIN = 0x00000800, LENGTH = 0x00080000-0x00000800
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000
m_RAMexec (RX) : ORIGIN = 0x20000000, LENGTH = 0x00001000
m_cfmprotrom (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
}
......
.RAMexec:
{
. = ALIGN (0x8);
* (.RAMCode)
. = ALIGN (0x8);
} > m_RAMexec
....
The first #pragma sets .text section as far_abs and allows to call flash stored functions, both user defined and (most) library ones, in myRAMfunction.
As I try to perform, for example, a division operation, the MCU generates an exception.
However, the code runs smoothly if I directly call the library function __aeabi_idiv which seems to be the function the compiler calls while performing a division.
Looking at the disassembly while debugging sheds a bit of light:
myRAMfunction:
20000000: push {r4,lr}
20000002: cpy r4,r0
27 cnt = __aeabi_idiv(cnt,3);
20000004: ldr r2,[pc,#0x1c]
20000008: cpy r0,r4
2000000a: movs r1,#3
2000000c: blx r2
2000000e: cpy r4,r0
28 cnt = cnt /3;
20000010: cpy r0,r4
20000012: movs r1,#3
20000014: bl $Ven$lb$$__aeabi_idiv._s32_div_f.o (0x20000028); 0x20000028
20000018: cpy r4,r0
29 return cnt;
2000001a: cpy r0,r4
30 }
2000001c: ldm sp!,{r4,lr}
20000020: bx lr
20000022: nop
20000024: lsrs r5,r5,#16
20000026: movs r0,r0
20000028: bx pc
It seems that the compiler carries out the second division with a branch link to $Ven$lb$$__aeabi_idiv._s32_div_f.o, which unfortunately points to nowhere (0x20000028), while the explicit call to __aeabi_idiv works fine, moving the PC back to the flash section where the integer division code is stored.
1. Does anybody know how to solve this issue?
2. Is there a smooth way to load the math EWL libraries in RAM?
Solved! Go to Solution.
Hello,
found an answer to both questions:
1. The issue related to the assembly branch link seems to originate from a CW 10.1 Linker bug. Simply substituting the linker .exe with a new one (version 10.5) solves the problem: now at address 0x20000028, after the bl, there is another branch to the flash stored division code. Everything now works fine.
2. I have found in another post Re: Calling all LCF Experts... the correct sintax to move a whole EWL library to RAM.
Best regards,
Cesare
Hello Cesare:
Is it possible for you to share your project? I would like to reproduce this issue from my side and see if I can find the problem. Also please tell us the exact part number you have.
Regards!
Jorge Gonzalez
Hello,
found an answer to both questions:
1. The issue related to the assembly branch link seems to originate from a CW 10.1 Linker bug. Simply substituting the linker .exe with a new one (version 10.5) solves the problem: now at address 0x20000028, after the bl, there is another branch to the flash stored division code. Everything now works fine.
2. I have found in another post Re: Calling all LCF Experts... the correct sintax to move a whole EWL library to RAM.
Best regards,
Cesare