Part Number: CC2650STK
Tool/software: TI-RTOS
In a project, I suddenly got an error during linking indicating I did not have enough flash space.
line 128: error #10099-D: program will not fit into available memory. placement with alignment fails for section ".cinit" size 0xbb6 . Available memory ranges: FLASH size: 0x10010 unused: 0x4fe max hole: 0x4fc error #10010: errors encountered during linking; "sensortag_reporter.out" not built
I often got such errors sometilmes appearing when doing few code modifications or not code modifications at all. I read advices given here e2e.ti.com/.../543036
So yesterday I investigated this issue comparing memory mapping between my code that contains some modifications and original code (cc2650stk code). On original sensortag memory map, we can see there is only 4510bytes reamining on flash (with OAD image). So adding code can quickly fill flash memory
A noticeable difference is in .const section : there is a huge difference of 0x1000 bytes. Added const data is listed here :
.const 0 0000efa0 00001b84
0000efa0 00001000 rtsv7M3_T_le_eabi.lib : s_exp2.obj (.const:tbl$62)
This library is RTS library processors.wiki.ti.com/.../C28x_Code_Generation_Tips_and_Tricks
In both build I can see some symbols in .data, .text sections.
But why do I got these constants?
After digging, I found these constants are used to compute an base 2 exponential, for an implementation refer : android.googlesource.com/.../s_exp2.c
And more details are here : www.google.fr/url
I found this exp2 method was used in TI RTOS MW file SensorOpt3001.c. To free some flash, I modified this code (that was called from my code).
float SensorOpt3001_convert(uint16_t rawData)
{
uint16_t e, m;
m = rawData & 0x0FFF;
e = (rawData & 0xF000) >> 12;
return m * (0.01 * exp2(e));
}
to
float SensorOpt3001_convert(uint16_t rawData)
{
uint16_t e, m;
m = rawData & 0x0FFF;
e = (rawData & 0xF000) >> 12;
return m * (0.01 * pow(2.0, e));
}
After this modification I do not have anymore this 4k in const section, but code for pow takes 2476bytes :
.text 0 0000104c 0000eaaa
0000104c 000009ac rtsv7M3_T_le_eabi.lib : e_pow.obj (.text)
that must be compared with exp2 code size of ~500 bytes
So if you need some flash space and does not need fast exp2 computing, replace exp2 calls with pow (I do not know pow implementation in math lib), you will free 2kbytes of flash. But pow code is at first position in flash code memory list.
After this modification I still did not have enough space... and taking 2 k for pow function is not reasonable with available flash...
We can get more space. As we are calling a base 2 exponent function with exponent as integer, we can replace this pow function with :
float SensorOpt3001_convert(uint16_t rawData)
{
uint16_t e, m;
m = rawData & 0x0FFF;
e = (rawData & 0xF000) >> 12;
/** e on 4 bits stored in a 16 bit unsigned => it can store 2 << (e - 1) with e < 16 */
e = (e == 0) ? 1 : 2 << (e - 1);
return m * (0.01 * e);
}
No my program builds, and difference with reference sensortag application is 1kbytes...
As a conclusion, math functions on double / float types must be used with care. I do not have implementation details for all functions. I used two of it in my code (pow and exp), both needed many flash space. That's why checking memory usage in, .map file when using math functions is very useful.