且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用裸机树莓派调用 printf 到 uart 时,应用程序挂起

更新时间:2021-08-01 02:46:10

很抱歉这么晚才为您解决这个问题.我是 Valvers.com 裸机教程的作者.崩溃的原因是由于我知道但没有时间解决的事情.实际上,我不知道它会解决您的问题.

I'm sorry I'm so late to solve this problem for you. I'm the author of the valvers.com bare metal tutorials. The cause of the crash is due to something I was aware of, but hadn't had time to solve. Actually, I didn't know it would be the solution to your problem.

简而言之,问题在于我们告诉工具链处理器是 ARM1176,更重要的是浮点单元是 VFP,我们应该使用硬浮点 ABI.

In short, the problem is that we're telling the toolchain that the processor is an ARM1176 and more importantly that the floating point unit is VFP, and we should use the hard-float ABI.

使用 VFP 是一个重要的选项 - 这意味着我们选择了也使用此选项编译的 C 库.通常不使用 VFP 指令,因此不会绊倒我们.显然, printf 的部分确实使用了 VFP 指令.

Using the VFP is an important option - it means we pick up the C library that's also been compiled with this option. Generally the VFP instructions aren't used and therefore do not trip us up. Clearly, portions of printf do use VFP instructions.

这让我们感到困惑的原因是,负责生成良好 C 运行时环境的启动汇编程序没有启用 VFP,因此当您到达 VFP 指令时,处理器会跳转到未定义的指令异常向量.

The reason this trips us up is because the startup assembler which is responsible for generating a good C runtime environment doesn't enable VFP, so when you reach a VFP instruction the processor jumps to the undefined instruction exception vector.

我就是这样发现问题的.我简单地启用了任何异常向量中的 LED,并在使用 printf 格式时点亮.然后是删除异常向量中的 LED 调用,直到它不再亮起.这发生在未定义指令"异常中.在 ARM 站点上进行快速搜索显示,如果遇到 VFP 指令且未启用 VFP,处理器将转到此处.因此,它提醒我解决这个问题!

This is how I found out that this was the problem. I simple enabled the LED in any of the exception vectors and it lit when using printf formatting. Then it was a case of removing the LED calls in the exception vectors until it didn't light anymore. This happened in the "Undefined Instruction" exception. A quick search on the ARM site reveals the processor will go here if a VFP instruction is encountered and the VFP is not enabled. Hence, it reminded me to sort that out!

解决方案

您需要做一些事情.您需要将 CMakeLists.txt 文件中的 CMAKE_C_FLAGS 复制到 CMAKE_ASM_FLAGS,以便将正确的选项传递给汇编程序,目前它们不是!我会尽快更新教程来解决这个问题!

There are a few things you need to do. You need to replicate the CMAKE_C_FLAGS to CMAKE_ASM_FLAGS in the CMakeLists.txt file so that the correct options are passed to the assembler, currently they are not! I will update the tutorials as soon as possible to fix this!

在 CMakeLists.txt 文件中最后一个 set( CMAKE_C_FLAGS ... ) 命令下方添加 set( CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS} ) ,因为 CMake 使用gcc 作为汇编程序.

Just below the last set( CMAKE_C_FLAGS ... ) command in the CMakeLists.txt file add set( CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS} ) which works okay because CMake uses gcc as the assembler.

接下来,我们需要修改启动汇编程序文件(在我的教程 armc-nnn-start.S 中)以启用 VFP.在 bl _cstartup

Next, we need to modify the startup assembler file (in my tutorials armc-nnn-start.S) to enable the VFP. Insert the code below just above bl _cstartup

(这直接来自 TI 网站)

// Enable VFP/NEON
// r1 = Access Control Register
MRC p15, #0, r1, c1, c0, #2
// enable full access for p10,11
ORR r1, r1, #(0xf << 20)
// ccess Control Register = r1
MCR p15, #0, r1, c1, c0, #2
MOV r1, #0
// flush prefetch buffer because of FMXR below
MCR p15, #0, r1, c7, c5, #4
// and CP 10 & 11 were only just enabled
// Enable VFP itself
MOV r0,#0x40000000
// FPEXC = r0
FMXR FPEXC, r0

您可以从 ARM 找到有关此的一些信息 这里.

You can find some information from ARM about this here.

这些更改足以使 printf 格式正常工作(我已在 UART 上对其进行了测试).如果您有任何其他问题,请随时提出.

Those changes are enough to get printf formatting working okay (I've tested it on the UART). If you have any further problems, don't hesitate to ask.

最后,很抱歉您因为启动代码不正确而感到悲伤!我最不想做的就是浪费别人的时间!!

Lastly, sorry you've had grief because the startup code is not correct! The last thing I'd want to do is cost someone's time!!