工具/软件:TI-RTOS
在一个项目中、我在链接期间突然遇到错误、表示我没有足够的闪存空间。
第128行:错误#10099-D:程序不能装入可用内存。 对齐方式对".cinit"大小为0xbb6的段进行放置失败。 可用存储器范围: 闪存 大小:0x10010 未使用:0x4fe 最大孔数:0x4fc 错误#10010:链接期间遇到错误;未生成"sensortag_Reporter .out"
我经常在执行少量代码修改或根本不进行代码修改时出现这样的错误。 我阅读 了 e2e.ti.com/.../543036上提供的建议
因此、昨天我研究了这个问题、比较了我的代码(包含一些修改)和原始代码(cc2650stk 代码)之间的存储器映射。 在原始的 sensortag 存储器映射上、我们可以看到闪存上只有4510字节的重校准(带有 OAD 映像)。 因此、添加代码可以快速填充闪存
在.const 段中有一个显著的差异:有一个巨大的0x1000字节的差异。 此处列出了添加的常量数据:
.const 0 0000efa0 00001b84 0000efa0 00001000 rtsv7M3_T_le_eabi.lib:s_exp2.obj (.const:tbl$62)
此库是 RTS 库 processors.wiki.ti.com/.../C28x_Code_Generation_Tips_and_Tricks
在这两个构建中、我都可以在.data、.text 段中看到一些符号。
但是、为什么我会得到这些常数?
挖掘后,我发现这些常量用于计算2个指数的基本值,有关实现方法,请参阅 :android.googlesource.com/.../s_exp2.c
有关详情,请访问 :www.google.fr/url
我发现此 exp2方法在 TI RTOS MW 文件 SensorOpt3001.c 中使用 为了释放一些闪存、我修改了这个代码(从我的代码调用)。
float SensorOpt3001_convert (uint16_t RawData) { uint16_t e、m; M = RawData 和0x0FFF; E =(RawData & 0xF000)>> 12; 返回 m *(0.01 * exp2 (e)); }
更改为
float SensorOpt3001_convert (uint16_t RawData) { uint16_t e、m; M = RawData 和0x0FFF; E =(RawData & 0xF000)>> 12; 返回 m *(0.01 * pow (2.0、e)); }
经过此修改后,我不再在 const 段中使用此4K,但 pow 的代码占用2476字节:
.text 0 0000104c 0000eaaa 0000104c 000009ac rtsv7M3_T_le_eabi.lib:e_pow.obj (.text)
必须将其与 exp2代码大小~500字节进行比较
因此、如果您需要一些闪存空间并且不需要快速的 exp2计算、请使用 pow (我不知道数学库中的 pow 实现)替换 exp2调用、您将释放2kb 的闪存。 但 Pow 代码位于闪存代码存储器列表中的第一个位置。
在进行此修改后、我仍然没有足够的空间... 使用可用闪存时、使用2k 函数是不合理的...
我们可以获得更多空间。 当我们调用一个以整数表示指数的基本2指数函数时,我们可以将该 pow 函数替换为:
float SensorOpt3001_convert (uint16_t RawData) { uint16_t e、m; M = RawData 和0x0FFF; E =(RawData & 0xF000)>> 12; /** e 在存储在16位无符号数中的4位上=>它可以存储2 <<(e - 1)和 e < 16 */ E =(e = 0)? 1:2 <(e - 1); 返回 m *(0.01 * e); }
没有构建我的程序、与参考 sensortag 应用程序的区别是1KB……
总之、必须小心使用 double / float 类型上的数学函数。 我没有所有函数的实现细节。 我在代码中使用了其中的两个(pow 和 exp)、这两个都需要很多闪存空间。 这就是为什么在使用数学函数时检查.map 文件中的存储器使用情况非常有用的原因。