2016-08-11 4 views
0

Ich versuche, eine kleine Anwendung zu schreiben, die eine Nachricht über die serielle Schnittstelle zeigt. Diese Binärdatei wird ohne Betriebssystem ausgeführt, also ist es Bare-Metal.Daten abbrechen auf A20 SoC

Der Code ist wie folgt:

#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"); 
} 

Ich Booten dieses binäre mit u-boot, und tatsächlich die binären Stiefel gut, bis es erreicht:

*uart0 = (unsigned int)(*str); 

Sobald ich versuche, schreibe in diesen Speicher, ich bekomme einen Data Abort Error. Es sieht aus wie ich bin nicht erlaubt, an dieser Speicheradresse zu schreiben, aber einen Blick auf die A20 User Manual Ich sehe, dass tatsächlich UART0 0x01C28000 zugeordnet ist, so sollte ich Zugang zum Schreiben dort haben.

Dies ist die Ausgabe:

=> 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 ... 

Haben Sie eine Idee, warum dies geschieht?

Ist es möglich, dass der Code nicht dem RAM zugeordnet wird, und deshalb bekomme ich diesen Fehler?

== == UPDATE

Nachdem die Vars als Konstante definieren arbeitet nun "besser". Es funktioniert immer noch nicht gut, weil ich Müll anstelle von meinem Text bekomme. Hier

ist der Code aktualisiert:

#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"); 
} 

Und der Ausgang ist:

=> go 0x42000000 
## Starting application at 0x42000000 ... 
��ᚕ�� 
    �� 

Ich bin sicher, dass ich etwas fehle, aber ich bin nicht sicher, was. Ich habe einen Blick auf den Fahrer, die von U-Boot verwendet wird, finden Sie unter:

arch/arm/cpu/armv7/sunxi/early_print.c 

Und es ist eigentlich nicht mehr als mich zu tun. Ich frage mich, wo der Fehler ist.

Vielen Dank im Voraus Grüße

+0

Sie haben 'stdint' bereits eingefügt. Irgendein Grund, warum Sie es nicht benutzen? Außerdem: niemals ohne Notwendigkeit oder vollständige Akzeptanz aller Implikationen. – Olaf

+0

Nicht das eigentliche Problem: 'while ((* uart_lstr & (1 << THR_STATUS))! = THR_READY)' diese Bedingung wird niemals wahr sein: '(xxx & (1 << 5))! = 1' für jedes xxx in der Stadt. – joop

+0

Verwenden Sie für die Registeradressen konstante Makros, keine globalen Variablen! Vielleicht sollten Sie zuerst eine professionelle Hardware-Treibersoftware lesen, bevor Sie Ihre eigene schreiben. – Olaf

Antwort

2

Die wahrscheinlichste Antwort ist, dass Sie nicht richtig Aufbau einer Bare-Metal-Anwendung. Sehen Sie sich das Beispiel hallo_world in U-Boot unter examples/standalone an, um eine Anwendung zu verknüpfen. Vielleicht möchten Sie beginnen, indem Sie einige der exportierten Funktionen aufrufen, nur um zu bestätigen, dass Sie diese Hürden überwunden haben, bevor Sie weitermachen, um die Hardware direkt zu schlagen.

+0

Die App wird in Ordnung gebaut.Ich habe gerade ein anderes Beispiel geschrieben (LED blinkt) und funktioniert einfach. Trotzdem danke ;) – leberus

Verwandte Themen