完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在看最新的第一期加强版视频的过程中,不知道大家有没有用4.3.2版本的编译器编译老师讲的视频,我在看视频过程中一直用的4.3.2版本交叉编译工具编译项目,当我看到视频的第11课第005节的时候,演示自己实现printf裸机打印,里面用到了lib1funcs.S文件,我编译的时候发现会遇到这样一个错误
ARM-linux-gcc -c -o led.o led.c arm-linux-gcc -c -o uart.o uart.c arm-linux-gcc -c -o lib1funcs.o lib1funcs.S arm-linux-gcc -c -o my_printf.o my_printf.c arm-linux-gcc -c -o main.o main.c arm-linux-gcc -c -o start.o start.S arm-linux-ld -Ttext 0 -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf my_printf.o: In function `out_num': my_printf.c:(.text+0x120): undefined reference to `__aeabi_uidivmod' my_printf.c:(.text+0x158): undefined reference to `__aeabi_uidiv' Makefile:2: recipe for target 'all' failed make: *** [all] Error 1 这是因为编译器的库没有实现除法运算,可是老师演示的时候明明可以编译通过啊,而且代码也反复检查了一下,没有不同,后来了解到老师用的是3.4.5版本的交叉编译工具,换成3.4.5版本的编译工具,果然可以编译通过。但是我想试试4.3.2版本能不能编译通过。 首先这个错误提示说明是一个未定义引用的错误,说的是my_printf.c文件out_num方法有问题,根据__aeabi_uidivmod,和__aeabi_uidiv猜想应该是除法实现的问题,这里用到了lib1funcs.S这个除法库文件,于是我在里面搜索__aeabi_uidiv和__aeabi_uidivmod,可是发现找不到这两个关键字的定义,事实表明应该是4.3.2版本的编译工具需要找这两个关键字的定义,但是找不到。于是猜测应该是这个lib1funcs.S是比较老版本的库文件,可是这个较新版本的去哪找呢,除法运算在u-boot和Linux内核里肯定实现了,就到这两个里面去找这个文件。 4.3.2编译通过的两个项目版本分别是u-boot-2012.04.01以及linux-3.4.2,就到这两个项目中找,你会发现u-boot里面没有这个文件,u-boot肯定实现了,但是不是用这个来实现的,我们到linux内核里找,你会搜索到如下结果: song@dev:/work/hardware/009_uart$ find /work/system/linux-3.4.2 -name "lib1funcs.S" /work/system/linux-3.4.2/arch/arm/lib/lib1funcs.S /work/system/linux-3.4.2/arch/arm/boot/compressed/lib1funcs.S /work/system/linux-3.4.2/arch/arm/lib/lib1funcs.S,这个文件应该就是我们找的库文件把他copy到项目里,然后make arm-linux-gcc -c -o led.o led.c arm-linux-gcc -c -o uart.o uart.c arm-linux-gcc -c -o lib1funcs.o lib1funcs.S lib1funcs.S:36:27: error: linux/linkage.h: No such file or directory lib1funcs.S:37:27: error: asm/assembler.h: No such file or directory lib1funcs.S:38:24: error: asm/unwind.h: No such file or directory Makefile:2: recipe for target 'all' failed make: *** [all] Error 1 遇到如上错误,提示我们找不到这些头文件,我们没有引用怎么可能找到,对比以前的lib1funcs.S不需要这些头文件,我们直接去掉就行。保存make song@dev:/work/hardware/009_uart$ make arm-linux-gcc -c -o led.o led.c arm-linux-gcc -c -o uart.o uart.c arm-linux-gcc -c -o lib1funcs.o lib1funcs.S lib1funcs.S: Assembler messages: lib1funcs.S:175: Error: bad instruction `entry(__udivsi3)' lib1funcs.S:176: Error: bad instruction `entry(__aeabi_uidiv)' lib1funcs.S:177: Error: bad instruction `unwind(.fnstart)' lib1funcs.S:201: Error: bad instruction `unwind(.fnend)' lib1funcs.S:202: Error: bad instruction `endproc(__udivsi3)' lib1funcs.S:203: Error: bad instruction `endproc(__aeabi_uidiv)' lib1funcs.S:205: Error: bad instruction `entry(__umodsi3)' lib1funcs.S:206: Error: bad instruction `unwind(.fnstart)' lib1funcs.S:220: Error: bad instruction `unwind(.fnend)' lib1funcs.S:221: Error: bad instruction `endproc(__umodsi3)' lib1funcs.S:223: Error: bad instruction `entry(__divsi3)' lib1funcs.S:224: Error: bad instruction `entry(__aeabi_idiv)' lib1funcs.S:225: Error: bad instruction `unwind(.fnstart)' lib1funcs.S:262: Error: bad instruction `unwind(.fnend)' lib1funcs.S:263: Error: bad instruction `endproc(__divsi3)' lib1funcs.S:264: Error: bad instruction `endproc(__aeabi_idiv)' lib1funcs.S:266: Error: bad instruction `entry(__modsi3)' lib1funcs.S:267: Error: bad instruction `unwind(.fnstart)' lib1funcs.S:287: Error: bad instruction `unwind(.fnend)' lib1funcs.S:288: Error: bad instruction `endproc(__modsi3)' lib1funcs.S:350: Error: bad instruction `unwind(.fnstart)' lib1funcs.S:351: Error: bad instruction `unwind(.pad #4)' lib1funcs.S:352: Error: bad instruction `unwind(.save {lr})' lib1funcs.S:357: Error: bad instruction `unwind(.fnend)' lib1funcs.S:358: Error: bad instruction `endproc(Ldiv0)' Makefile:2: recipe for target 'all' failed make: *** [all] Error 1 这些错误,从意思应该是也是对这些定义不理解,应该是去掉头文件引起来的,也就是说头文件中有这些的定义,我们对比老的lib1funcs开头有一些宏定义我们先加上,其中有entry的宏定义,我们可以猜想这些都是在头文件里的宏定义,其实你去linux内核里找这个头文件#include 还会报这种错误,也是没有写宏定义 lib1funcs.S:357: Error: bad instruction `unwind(.fnend)' lib1funcs.S:358: Error: bad instruction `endproc(Ldiv0)' 但是我们对别老的lib1funcs.S发现这些都没有,所以这些关键字标识符我们先去掉只要是UNWIND和ENDPROC开头的都去掉,然后make arm-linux-gcc -c -o led.o led.c arm-linux-gcc -c -o uart.o uart.c arm-linux-gcc -c -o lib1funcs.o lib1funcs.S arm-linux-gcc -c -o my_printf.o my_printf.c arm-linux-gcc -c -o main.o main.c arm-linux-gcc -c -o start.o start.S arm-linux-ld -Ttext 0 -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf my_printf.o: In function `out_num': my_printf.c:(.text+0x120): undefined reference to `__aeabi_uidivmod' Makefile:2: recipe for target 'all' failed make: *** [all] Error 1 你会发现还是报未定义的错误,在lib1funcs.S搜索这个定义,它的上面有个#ifdef CONFIG_AEABI,需要先定义这个宏定义,我们在开头加一句 #define CONFIG_AEABI 1,然后保存make arm-linux-gcc -c -o led.o led.c arm-linux-gcc -c -o uart.o uart.c arm-linux-gcc -c -o lib1funcs.o lib1funcs.S arm-linux-gcc -c -o my_printf.o my_printf.c arm-linux-gcc -c -o main.o main.c arm-linux-gcc -c -o start.o start.S arm-linux-ld -Ttext 0 -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf arm-linux-ld: section .data [00000e80 -> 00000e8f] overlaps section .rodata [00000d74 -> 00000e9b] arm-linux-ld: uart.elf: section .data lma 0xe80 overlaps previous sections lib1funcs.o: In function `Ldiv0': (.text+0x3ec): undefined reference to `__div0' Makefile:2: recipe for target 'all' failed make: *** [all] Error 1 还有一个未定义搜索lib1funcs.S,是在最后相对跳转到一个c函数里面执行,我们对比老的lib1funcs.S发现这里注释掉了,我们也注释掉,然后保存make arm-linux-gcc -c -o led.o led.c arm-linux-gcc -c -o uart.o uart.c arm-linux-gcc -c -o lib1funcs.o lib1funcs.S arm-linux-gcc -c -o my_printf.o my_printf.c arm-linux-gcc -c -o main.o main.c arm-linux-gcc -c -o start.o start.S arm-linux-ld -Ttext 0 -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf arm-linux-ld: section .data [00000e80 -> 00000e8f] overlaps section .rodata [00000d74 -> 00000e9b] arm-linux-ld: uart.elf: section .data lma 0xe80 overlaps previous sections Makefile:2: recipe for target 'all' failed make: *** [all] Error 1, 你可能会遇到这个问题这个应该是代码段太长了,超过了定义的数据段的位置,可以自己适当延长代码段,我试了一下用0xea0就可以,到此第一期arm加强版demo程序009-uart移植4.3.2编译器完毕。 在后面的lcd那里的除法解决方案里需要用到libgcc.a库,我当时用的是/usr/local/arm/4.3.2/lib/gcc/arm-none-linux-gnueabi/4.3.2/libgcc.a这个文件,在后面的adc实验的时候发现这个库无法解决浮点数除法的问题,解决了一段时间,最后还是微信请教了韦老师,老师最后发现是我用的libgcc.a文件错误,应该用4.3.2/lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a这个位置的libgcc.a文件 备注:这里我用的是009_uart项目重新走了一遍。 |
|
相关推荐
1个回答
|
|
|
|
只有小组成员才能发言,加入小组>>
197个成员聚集在这个小组
加入小组为什么点亮LED的例子放在NORFlash上跑会出现奇怪的现象?
2232 浏览 6 评论
2032 浏览 5 评论
韦东山老师推出的《玩转ARM裸机实战》课程将帮你以上问题一扫而光!
4594 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-3-6 13:53 , Processed in 0.498327 second(s), Total 42, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191