我正在尝试编写一个小应用程序,它通过串行端口显示消息。这个二进制文件是在没有操作系统的情况下执行的,所以它是裸机。
代码如下:
#include <stdint.h>
#define FIFO 0x0
#define NOFIFO 0x1
#define FIFO_STATUS 0x0
#define THR_READY 0x1
#define THR_STATUS 0x5
#define UART_MEM 0x1C28000
volatile unsigned int *uart0 = (unsigned int *)UART_MEM;
volatile unsigned int *uart_str = (unsigned int *)(UART_MEM + 0x7c);
volatile unsigned int *uart_lstr = (unsigned int *)(UART_MEM + 0x14);
void print_smth(const char *str) {
while (*str != '\0') {
while ((*uart_lstr & (1 << THR_STATUS)) != THR_READY)
;
*uart0 = (unsigned int)(*str);
str++;
}
}
void c_entry(void) {
print_smth("Hello");
}
我用u-boot启动这个二进制文件,实际上二进制文件可以正常启动,直到它达到:
*uart0 = (unsigned int)(*str);
一旦我试图写入这个内存,我会得到一个数据中止错误。
看起来我不允许在这个内存地址写东西,但是看一下A20 User Manual我发现实际上UART0被映射到0x01c2800,所以我应该有权限在那里写东西。
这是输出:
=> loadx
## Ready for binary (xmodem) download to 0x42000000 at 115200 bps...
CxyzModem - CRC mode, 2(SOH)/0(STX)/0(CAN) packets, 2 retries
## Total Size = 0x000000c4 = 196 Bytes
=> go 0x42000000
## Starting application at 0x42000000 ...
data abort
pc : [<4200007c>] lr : [<420000ac>]
reloc pc : [<0d0a207c>] lr : [<0d0a20ac>]
sp : 000010b0 ip : 7fe79000 fp : 000010bc
r10: 00000002 r9 : 7af3dee0 r8 : 7efb47a8
r7 : 7af3fab8 r6 : 42000000 r5 : 00000002 r4 : 7af3fabc
r3 : ee070f15 r2 : 0000001e r1 : 7af3fabc r0 : 000000b0
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...
resetting ...
你知道为什么会这样吗?
可能代码没有映射到RAM,这就是我得到这个错误的原因吗?
==更新==
在将变量定义为常量之后,现在工作得“更好”。它仍然不能正常工作,因为我得到的是垃圾而不是我的短信。
下面是更新的代码:
#include <stdint.h>
#define TEMT_STATUS (0x1 << 6)
#define UART0 0x1C28000
#define UART_LSR 0x14
volatile unsigned int *const uart0 = (unsigned int *)(UART0);
volatile unsigned int *const uart_lsr = (unsigned int *)(UART0 + UART_LSR);
void print_smth(const char *str) {
while (*str != '\0') {
while ( !(*uart_lsr & TEMT_STATUS))
;
*uart0 = (unsigned int)(*str);
str++;
}
}
void c_entry(void) {
print_smth("os");
}
结果是:
=> go 0x42000000
## Starting application at 0x42000000 ...
��ᚕ��
��
我肯定我漏掉了什么,但我不确定是什么。我查看了u-boot正在使用的驱动程序,位于:
arch/arm/cpu/armv7/sunxi/early_print.c
事实上,它做的并不比我多。所以我想知道失败在哪里。
提前谢谢
当做
最佳答案
这里最可能的答案是您没有正确地构建裸机应用程序。请查看examples/standalone下U-Boot中的hello_world示例,了解如何最重要地链接应用程序。您可能希望首先调用一些导出的函数,以确认您已经克服了这些障碍,然后再继续直接打击硬件。
关于c - A20 SoC上的数据中止,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38900328/