I'm trying to write a small application which shows a message through Serial Port. This binary is being executed without OS, so it's bare metal.
The code is as follows:
#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");
}
I'm booting this binary with u-boot, and actually the binary boots fine, until it reaches:
*uart0 = (unsigned int)(*str);
Once I try to write to this memory, I get a Data Abort Error. It looks like I'm not allow to write at this memory address, but taking a look at the A20 User Manual I see that actually UART0 is being mapped to 0x01C28000, so I should have access for writing there.
This is the output:
=> 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 ...
Do you an idea why this is happening?
Is possible that the code is not being mapped to the RAM and this is why I'm getting this error?
== UPDATE ==
After define the vars as a constant now is working "better". It's still not working fine because I get trash instead of my text.
Here is the code updated:
#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");
}
And the output is:
=> go 0x42000000
## Starting application at 0x42000000 ...
��ᚕ��
��
I'm sure I'm missing something but I'm not sure what. I took a look at the driver which is being used by u-boot, located at:
arch/arm/cpu/armv7/sunxi/early_print.c
And actually it's not doing more than me. So I'm wondering where is the failure.
Thanks in advance Regards
The most likely answer here is that you aren't building a bare metal application correctly. Please look at the hello_world example in U-Boot under examples/standalone for how to most importantly link an application. You may wish to start out by calling some of the exported functions just to confirm that you've gotten over these hurdles before you move on to whacking the hardware directly.
User contributions licensed under CC BY-SA 3.0