目录
1.1 问题现象
通过gcc 反汇编指令arm-none-eabi-objdump .elf > .s得到汇编,发现仅数据段有内容,代码段是空的,如下:
text段为空,
.data段有内容
进一步的,去找指定的函数进行反汇编,发现也没有任何内容。
最后查看生成的hex,发现Flash这一空间没有任何代码,这会导致仅生成符号,没有任何内容,MCU一运行就绝对跑飞。
很明显,问题出现在最后链接上,没有把任何代码段链接,所以可以将问题初步定位在ld 链接脚本上。
1.2 问题定位
找到LD文件的text段属性定义,依次来解释一下:
.text (NOLOAD):
NOLOAD类型的section与普通输出seciton不同之处在于:它的文本或数据不写入输出文件。NOLOAD节被分配虚拟空间,出现在内存映射中。问题应该就出在这里;
参考链接:DSECT, COPY, NOLOAD, INFO, and OVERLAY sections (sco.com)
我们继续看该section里面内容
*(.text*):包含所有的代码段到text这个section里,这里*是通配符,与正则表达式类似。
KEEP(*(.init)):保持.init里所有内容,避免编译器发现该section内容没有被使用时删除;
Ctors\dtors:用于c++,构造函数和析构函数,这里用不到;可以考虑优化
参考链接:Initialization (GNU Compiler Collection (GCC) Internals)
*(.rodata*):匹配所有的常量
1.3 问题解决
好,现在我们修改ld文件,去掉.text段的NOLOAD属性进行编译,
编译又出现了memset问题,又是在链接时找不到memset的实现
Memset是C定义的标准函数,按理说eclipse应该可以找到这个标准库,但是实际上现在没有,说明该工程编译配置没有使用标准库,因此修改编译选项:
表示该编译工程链接要使用默认库和标准库,继续编译,又出现如下问题:
涉及到了浮点寄存器相关内容,这部分内容不是很熟悉,但我们来看环境配置,
首先,处理器关于FPU的配置采用工具链默认配置
这里就要讨论下了,是否是当前内核架构和所选的浮点处理器不匹配造成的;因此这时候来看编译器的说明文档,首先来看-mfloat-abi支持三种方式,如
Soft -- 调用浮点操作的软件库来进行浮点运算
Softfp -- 浮点计算交由FPU处理,但函数参数传递使用通用整形寄存器而不是FPU寄存器
Hard -- 使用FPU浮点寄存器将函数参数传递给FPU处理
因此,根据官方文档参考,当我们使用hard模式时,可选用FPU类型如下(当前gcc版本10)
最后编译成功
Hex如下,代码段已经存在:
经测试,当使用GNU12.2.0版本,在选用hard模式,FPU type基本都可支持。