android---整形*浮点--相乘错误(浮点运算)----

本文介绍了一个关于Linux内核中浮点运算引发的编译错误问题,并提供了两种解决方案。一是避免直接使用浮点运算,二是通过配置CodeBlocks环境及使用Android NDK编译器来解决未定义符号引用的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.problem:

       更改:===>>>在tp的驱动文件中:

             cinfo->x[i]=(int)(cinfo->x[i]*1.33);

       查看log:===>>>

mediatek/custom/out/kernel/built-in.o: In function `tpd_touchinfo':
/home/tonylau/tony-workspace/xxxx/my-ap/kernel/mediatek/custom/out/kernel/touchpanel/ft5206_driver.c:1237: undefined reference to `__aeabi_i2d'
/home/tonylau/tony-workspace/xxxx/my-ap/kernel/mediatek/custom/out/kernel/touchpanel/ft5206_driver.c:1237: undefined reference to `__aeabi_dmul'
/home/tonylau/tony-workspace/xxxx/my-ap/kernel/mediatek/custom/out/kernel/touchpanel/ft5206_driver.c:1237: undefined reference to `__aeabi_d2iz'
make[3]: *** [.tmp_vmlinux1] Error 1
make[2]: *** [sub-make] Error 2


2.analysis:

       内核没有提供浮点运算支持,linux内核不会链接libc,所以有很多用户态的写法都不适用于内核。

       因此,不应该在内核里使用浮点数。




3.solution:


       方法1:cinfo->x[i]=(int)(cinfo->x[i]*1.33);===》》》cinfo->x[i]=(int)(cinfo->x[i]*1.33);


       方法2:codeblocks 环境,配置android NDK 编译器



GCC_3.5 {
  # BPABI symbols
  __aeabi_cdcmpeq
  __aeabi_cdcmple
  __aeabi_cdrcmple
  __aeabi_cfcmpeq
  __aeabi_cfcmple
  __aeabi_cfrcmple
  __aeabi_d2f
  __aeabi_d2iz
  __aeabi_d2lz
  __aeabi_d2uiz
  __aeabi_d2ulz
  __aeabi_dadd
  __aeabi_dcmpeq
  __aeabi_dcmpge
  __aeabi_dcmpgt
  __aeabi_dcmple
  __aeabi_dcmplt
  __aeabi_dcmpun
  __aeabi_ddiv
  __aeabi_dmul
  __aeabi_dneg
  __aeabi_drsub
  __aeabi_dsub
  __aeabi_f2d
  __aeabi_f2iz
  __aeabi_f2lz
  __aeabi_f2uiz
  __aeabi_f2ulz
  __aeabi_fadd
  __aeabi_fcmpeq
  __aeabi_fcmpge
  __aeabi_fcmpgt
  __aeabi_fcmple
  __aeabi_fcmplt
  __aeabi_fcmpun
  __aeabi_fdiv
  __aeabi_fmul
  __aeabi_fneg
  __aeabi_frsub
  __aeabi_fsub
  __aeabi_i2d
  __aeabi_i2f
  __aeabi_idiv
  __aeabi_idiv0
  __aeabi_idivmod
  __aeabi_l2d
  __aeabi_l2f
  __aeabi_lasr
  __aeabi_lcmp
  __aeabi_ldiv0
  __aeabi_ldivmod
  __aeabi_llsl
  __aeabi_llsr
  __aeabi_lmul
  __aeabi_ui2d
  __aeabi_ui2f
  __aeabi_uidiv
  __aeabi_uidivmod
  __aeabi_uldivmod
  __aeabi_ulcmp
  __aeabi_ul2d
  __aeabi_ul2f
  __aeabi_uread4
  __aeabi_uread8
  __aeabi_uwrite4
  __aeabi_uwrite8

  # Exception-Handling
  # \S 7.5
  _Unwind_Complete
  _Unwind_VRS_Get
  _Unwind_VRS_Set
  _Unwind_VRS_Pop
  # \S 9.2
  __aeabi_unwind_cpp_pr0
  __aeabi_unwind_cpp_pr1
  __aeabi_unwind_cpp_pr2
  # The libstdc++ exception-handling personality routine uses this 
  # GNU-specific entry point.
  __gnu_unwind_frame
}




<think>我们正在讨论ARM Compiler 5中的__aeabi_assert函数。根据引用[1]提到,microlib(ARM的一个小型C库)为了节省空间,不支持或实现几乎所有与操作系统交互的函数,包括assert()。因此,在ARM Compiler 5中,assert()函数可能由__aeabi_assert函数实现。 在ARM Compiler中,__aeabi_assert是一个内部函数,用于处理断言失败。当标准C库中的assert()宏检测到条件为假时,会调用一个底层函数来报告错误。在ARM Compiler 5中,这个底层函数通常就是__aeabi_assert。 作用: 1. 当断言失败时,__aeabi_assert函数被调用,用于输出错误信息(如文件名和行号)并终止程序。 2. 在嵌入式系统中,终止程序的方式可能是进入一个死循环,或者调用一个用户定义的错误处理函数。 使用方法: 1. 通常,我们在代码中包含<assert.h>,然后使用assert宏。当断言条件不满足时,就会调用__aeabi_assert。 2. 用户也可以自定义__aeabi_assert函数,以覆盖库中的默认实现。这样当断言失败时,可以执行自定义的错误处理(例如打印错误信息到串口、点亮LED等)。 自定义__aeabi_assert函数的示例: ```c #include <stdio.h> #include <stdlib.h> // 自定义__aeabi_assert函数 void __aeabi_assert(const char *expr, const char *file, int line) { // 这里可以输出错误信息,例如通过串口打印 printf("Assertion failed: %s, file %s, line %d\n", expr, file, line); // 然后可以选择死循环或者复位系统 while (1); // 或者调用abort(),但注意microlib可能不支持abort,所以需要自己实现 } ``` 注意: 1. 在ARM Compiler 5中,如果使用标准库(非microlib),则可能已经提供了__aeabi_assert的实现。但是,如果使用microlib,则可能需要用户自己实现,因为microlib为了精简,不提供完整的实现。 2. 在自定义__aeabi_assert时,需要确保函数的签名正确:三个参数分别是表达式字符串、文件名字符串和行号。 另外,引用[1]中提到了microlib不支持abort()、exit()等函数,因此如果使用microlib,那么自定义的__aeabi_assert函数不能依赖于这些函数,而应该自己实现错误处理。 参考引用[1]:由于microlib不支持这些函数,因此用户需要自己提供实现。 总结步骤: 1. 确定是否使用microlib:在Keil MDK中,可以在项目选项中选择使用标准库或microlib。 2. 如果使用microlib,并且需要断言功能,则必须自定义__aeabi_assert函数。 3. 在自定义函数中,实现错误处理逻辑(如打印信息、死循环等)。 相关问题: 1. 如何在ARM Compiler 5中自定义断言失败处理函数? 2. 使用ARM Compiler 5的microlib时,为什么需要自定义__aeabi_assert函数? 3. ARM Compiler 5中,__aeabi_assert函数的标准实现是什么? 4. 在嵌入式系统中,如何通过__aeabi_assert函数实现系统复位? 注意:在自定义__aeabi_assert函数时,要避免使用任何可能引起递归断言的操作(如调用assert宏),否则可能导致栈溢出。</think>### ARM Compiler 5 中 `__aeabi_assert` 函数详解 `__aeabi_assert` 是 ARM Compiler 5 (ARMCC) 中用于处理断言失败的底层函数,属于 ARM EABI (嵌入式应用二进制接口) 的一部分。当标准 `assert()` 宏检测到条件为假时,最终会调用此函数。 #### 核心作用 1. **断言处理** 当程序中的 `assert(condition)` 检测到 `condition` 为假时,自动触发此函数 2. **错误报告** 输出断言失败信息:文件名、行号、失败条件表达式 3. **程序终止** 默认实现会调用 `abort()` 终止程序执行 4. **可定制性** 允许开发者重写以实现自定义错误处理 #### 标准实现 ```c void __aeabi_assert( const char *expr, // 断言条件表达式字符串 const char *file, // 源代码文件名 int line // 失败位置的行号 ) { // 默认实现伪代码 printf("Assertion failed: %s, file %s, line %d\n", expr, file, line); abort(); // 终止程序 } ``` #### 使用方法 1. **基本断言** 在代码中使用标准 `assert()` 宏: ```c #include <assert.h> void func(int* ptr) { assert(ptr != NULL); // 触发 __aeabi_assert 当 ptr==NULL } ``` 2. **自定义实现(关键步骤)** 当使用 microlib 时(如引用[1]所述),需重写此函数: ```c // 自定义断言处理 void __aeabi_assert(const char *expr, const char *file, int line) { // 1. 通过串口输出错误信息 uart_printf("ASSERT: %s\nFile: %s\nLine: %d\n", expr, file, line); // 2. 错误指示灯控制 GPIO_Set(LED_ERROR, ON); // 3. 可选: 进入调试模式 __breakpoint(0); // 4. 系统复位或挂起 while(1) {} // 死循环 // NVIC_SystemReset(); // 系统复位 } ``` 3. **链接库配置** 确保正确链接库文件(参考引用[2]): ```makefile PLATFORM_LIBS += -lc -lgcc # 链接标准C库和GCC支持库 ``` #### 关键注意事项 1. **microlib 限制** 如引用[1]指出,microlib 不提供完整的 `abort()` 实现,需自定义 `__aeabi_assert` 才能使用断言功能[^1]。 2. **浮点处理** 若涉及浮点运算(参考引用[4]),需确保浮点调用约定一致: ```makefile CFLAGS += -mfloat-abi=softfp # 硬件浮点指令+软调用约定 ``` 3. **交叉编译支持** 交叉编译时需指定工具链前缀(参考引用[3]): ```bash export CC=arm-none-eabi-gcc export AR=arm-none-eabi-ar ``` 4. **优化建议** - 在发布版本中通过 `#define NDEBUG` 禁用断言 - 避免在断言中调用有副作用的函数:`assert(a++ > 0)` ❌ --- ### 相关问题 1. 如何在 ARM Compiler 5 中禁用断言功能? 2. microlib 和标准 ARM C 库在异常处理上有何区别?[^1] 3. 如何通过 `__aeabi_assert` 实现错误日志存储到 Flash? 4. 在无操作系统的嵌入式环境中,`abort()` 应该如何实现? [^1]: microlib 是一个比 ARM 标准 C 库小的独立库。为了节省大小,它不支持或实现几乎所有与操作系统交互的函数,例如 `abort()`、`exit()` 或 `assert()`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值