在 Code Composer Studio 编译器中禁用 64 位除法
Disable 64-bit division in Code Composer Studio compiler
我目前正在使用 Code Composer Studio (CCS) V7.4.0.00015 用 C 编写程序。
该程序有几个自写的库,可以执行字节、无符号整数和浮点数除法。
我已经到了项目的那个阶段,我需要减少代码大小以确保有足够的 space 来适应引导加载程序。
查看我的 .map 文件会发现 CCS 自动包含的几个运行时支持对象。其中一些包括:
div64u.obj
--> 846 字节
div64s.obj
--> 316 字节
这些对象来自 rts430x_lc_sd_eabi.lib
我的问题是:为什么要包含这些 64 位除法对象(特别是当我的程序中没有任何 64 位浮点数时)?更重要的是,我可以禁用它们(或阻止 CCS 包含它们)吗?
我花了几天时间在谷歌上搜索和搜索不同的网站,但我没能找到很多关于这些对象或如何禁用它们的文档。
编辑:
结果我确实有一个函数使用 long long ints (typedef'd as SLLONG)
/**
* @brief Compensate the raw pressure gained from the BME
* @details Uses the pressure compensation parameters to
* calculate the true pressure from the raw pressure
*
* Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa
*
* The contents of this function have been taken from the Adafruit Github page
* https://github.com/adafruit/Adafruit_BME280_Library
*
* @param rawPressure The raw pressure
* @param tempFine The temperature in high resoltuion format,
* gained from the BME_compensateTemp() function
*
* @return the pressure read from the device
*/
float BME_compensatePressure(ULONG rawPressure, SLONG tempFine)
{
SLLONG var1, var2, p;
if (rawPressure == 0x800000) // value in case pressure measurement was disabled
return SNaN;
rawPressure >>= 4;
var1 = ((SLLONG)tempFine) - 128000; // SLONG cast to SLLONG
var2 = var1 * var1 * (SLLONG)compParamsStruct.dig_P6; // SLONG^2 x (SWORD cast to SLLONG)
var2 = var2 + ((var1*(SLLONG)compParamsStruct.dig_P5)<<17); // SLLONG + (SLLONG * SWORD cast to SLLONG)
var2 = var2 + (((SLLONG)compParamsStruct.dig_P4)<<35);
var1 = ((var1 * var1 * (SLLONG)compParamsStruct.dig_P3)>>8) +
((var1 * (SLLONG)compParamsStruct.dig_P2)<<12);
var1 = (((((SLLONG)1)<<47)+var1))*((SLLONG)compParamsStruct.dig_P1)>>33;
if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - rawPressure;
p = (((p<<31) - var2)*3125) / var1;
var1 = (((SLLONG)compParamsStruct.dig_P9) * (p>>13) * (p>>13)) >> 25;
var2 = (((SLLONG)compParamsStruct.dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((SLLONG)compParamsStruct.dig_P7)<<4);
return ((float)p)/256;
}
新问题:
- 谁能想出一种方法来重新排列函数,使其不需要使用 long long 整数(不会造成任何精度损失?)
- OR 更具体地说,谁能想出我如何以不同的方式进行长除法,即下面显示的行:
p = (((p<<31) - var2)*3125) / var1;
我对64位浮点运算原问题的解决总结:
首先将以下行插入到编译器标志中:
--float_operations_allowed=32
然而,这在项目中产生了一些错误。每个位置的错误都相同:
#1558-D 64-bit floating point operations are not allowed
产生这些错误的代码是:
float lowerFence = med -1.5 * IQR;
float upperFence = med +1.5 * IQR;
和
return 0.5*coeffs->c0+tempScaled*coeffs->c1;
错误已通过将文字转换为浮点数并将多个浮点运算移至单行来修复
float IQR = STATS_Iqr(sorted, numSamples);
float iqrScaled = 1.5 * IQR;
float lowerFence = med - iqrScaled;
float upperFence = med + iqrScaled;
和
float half = 0.5;
float c0Scaled = half*coeffs->c0;
float c1Scaled = tempScaled*coeffs->c1;
return c0Scaled + c1Scaled;
解决了上述错误后,清理并重建了项目。添加此编译器标志具有删除以下对象的效果
我目前正在使用 Code Composer Studio (CCS) V7.4.0.00015 用 C 编写程序。 该程序有几个自写的库,可以执行字节、无符号整数和浮点数除法。
我已经到了项目的那个阶段,我需要减少代码大小以确保有足够的 space 来适应引导加载程序。
查看我的 .map 文件会发现 CCS 自动包含的几个运行时支持对象。其中一些包括:
div64u.obj
--> 846 字节div64s.obj
--> 316 字节
这些对象来自 rts430x_lc_sd_eabi.lib
我的问题是:为什么要包含这些 64 位除法对象(特别是当我的程序中没有任何 64 位浮点数时)?更重要的是,我可以禁用它们(或阻止 CCS 包含它们)吗?
我花了几天时间在谷歌上搜索和搜索不同的网站,但我没能找到很多关于这些对象或如何禁用它们的文档。
编辑: 结果我确实有一个函数使用 long long ints (typedef'd as SLLONG)
/**
* @brief Compensate the raw pressure gained from the BME
* @details Uses the pressure compensation parameters to
* calculate the true pressure from the raw pressure
*
* Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa
*
* The contents of this function have been taken from the Adafruit Github page
* https://github.com/adafruit/Adafruit_BME280_Library
*
* @param rawPressure The raw pressure
* @param tempFine The temperature in high resoltuion format,
* gained from the BME_compensateTemp() function
*
* @return the pressure read from the device
*/
float BME_compensatePressure(ULONG rawPressure, SLONG tempFine)
{
SLLONG var1, var2, p;
if (rawPressure == 0x800000) // value in case pressure measurement was disabled
return SNaN;
rawPressure >>= 4;
var1 = ((SLLONG)tempFine) - 128000; // SLONG cast to SLLONG
var2 = var1 * var1 * (SLLONG)compParamsStruct.dig_P6; // SLONG^2 x (SWORD cast to SLLONG)
var2 = var2 + ((var1*(SLLONG)compParamsStruct.dig_P5)<<17); // SLLONG + (SLLONG * SWORD cast to SLLONG)
var2 = var2 + (((SLLONG)compParamsStruct.dig_P4)<<35);
var1 = ((var1 * var1 * (SLLONG)compParamsStruct.dig_P3)>>8) +
((var1 * (SLLONG)compParamsStruct.dig_P2)<<12);
var1 = (((((SLLONG)1)<<47)+var1))*((SLLONG)compParamsStruct.dig_P1)>>33;
if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - rawPressure;
p = (((p<<31) - var2)*3125) / var1;
var1 = (((SLLONG)compParamsStruct.dig_P9) * (p>>13) * (p>>13)) >> 25;
var2 = (((SLLONG)compParamsStruct.dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((SLLONG)compParamsStruct.dig_P7)<<4);
return ((float)p)/256;
}
新问题:
- 谁能想出一种方法来重新排列函数,使其不需要使用 long long 整数(不会造成任何精度损失?)
- OR 更具体地说,谁能想出我如何以不同的方式进行长除法,即下面显示的行:
p = (((p<<31) - var2)*3125) / var1;
我对64位浮点运算原问题的解决总结:
首先将以下行插入到编译器标志中:
--float_operations_allowed=32
然而,这在项目中产生了一些错误。每个位置的错误都相同:
#1558-D 64-bit floating point operations are not allowed
产生这些错误的代码是:
float lowerFence = med -1.5 * IQR;
float upperFence = med +1.5 * IQR;
和
return 0.5*coeffs->c0+tempScaled*coeffs->c1;
错误已通过将文字转换为浮点数并将多个浮点运算移至单行来修复
float IQR = STATS_Iqr(sorted, numSamples);
float iqrScaled = 1.5 * IQR;
float lowerFence = med - iqrScaled;
float upperFence = med + iqrScaled;
和
float half = 0.5;
float c0Scaled = half*coeffs->c0;
float c1Scaled = tempScaled*coeffs->c1;
return c0Scaled + c1Scaled;
解决了上述错误后,清理并重建了项目。添加此编译器标志具有删除以下对象的效果