2016-11-18 1 views
8

Beaglebone Black에서 UART0을 통해 문자열을 인쇄하려고합니다. 부트 로더가 UART0을 초기화하고 문자를 써야합니다. 나는 간단한 함수를 만들었습니다.C 문자열이 루프에서 올바르게 반복되지 않습니다.

void uart_put(unsigned char c) 
{ 
    while((UART0->LSR_r & 32) == 0); 
    UART0->THR = c;  
} 

시작 코드에서 다음 함수가 호출되었습니다.이 함수에서는 단순히 문자를 인쇄합니다.

#define SIZE_OF_ARRAY 7 
int c_entry(void) 
{ 
unsigned char s_name[SIZE_OF_ARRAY] = "Hello"; 
unsigned char a_name[SIZE_OF_ARRAY] = {'H','e','l','l','o','\0'}; 
unsigned int a_int[SIZE_OF_ARRAY] = {9,8,7,6,5,4}; 
int i = 0; 
    for(i = 0; i<6; i++) 
    { 
     uart_put('0'+i);  /*print value of i*/ 
     uart_put(9);   /*print a tab*/ 
     uart_put(s_name[i]); /*print char from string*/ 
     uart_put(9);   /*print a tab*/ 
     uart_put(a_name[i]); /*print char from array*/ 
     uart_put(9);   /*print a tab*/ 
     uart_put('0'+a_int[i]); /*print int from array*/ 
     uart_put('\n'); 
     uart_put('\r'); 
    } 
    while(1); 
    return 0; 
} 

함수

문자의 배열로 잘 작동되고, 정수가 정상적으로 인쇄되지만이어야하는 문자열이 인쇄되지 않는다. 링커 스크립트 내에서

+0

"while (name [i]! = '\ 0')" –

+0

@SaeidYazdani 나는 그것이 무엇이든 변경하는 것을 의심합니다. BTW 왜 이렇게 :'uart_put (name [5]);'이 하나가 널 문자인가? –

+1

당신의 정보를 위해서, 그리고 조금 익살 꾸러기를 할 때 줄 바꿈 시퀀스는 캐리지 리턴 - 개행이어야합니다. 다른 방법은 아닙니다. –

답변

7

enter image description here가 변경 :

. = 0x402F0400; 

에 : 0x8000000는 DDR2 메모리 동안

. = 0x80000000; 

memory map for the AM335X ARM processor 당, 0x402F0400 핵심 SRAM이다. TFTP 부트 출력의 스크린 샷에 따라 응용 프로그램을 0x80000000에로드하고 있지만 링커 스크립트는 0x402F04000에있는 메모리를 참조하도록 구성되어 있습니다. 문자열이 로컬 변수에 메모리에서 복사

% arm-none-eabi-objdump -D -b binary -marm download.bin 
download.bin:  file format binary 

Disassembly of section .data: 

00000000 <.data>: 
    0: e51fd000  ldr  sp, [pc, #-0] ; 0x8 
    4: eb00000e  bl  0x44 
    8: 402f1638  eormi r1, pc, r8, lsr r6  ; <UNPREDICTABLE> 
    c: e52db004  push {fp}   ; (str fp, [sp, #-4]!) 
    [removed several lines of text] 
    4c: e24dd030  sub  sp, sp, #48  ; 0x30 
    50: e300262c  movw r2, #1580  ; 0x62c 
    54: e344202f  movt r2, #16431  ; 0x402f 
    [remainder of dump removed] 

: 원래 링커 스크립트 수익률을 사용하여 구축 원시 이진 파일 download.bin을 분해

. 문자열 복사에 대한 주소는 0x402f062c입니다 (movwmovt 명령은 레지스터에 주소를로드합니다). 생략 된 코드를 빠르게 검사해도 메모리에 액세스하려는 다른 시도는 표시되지 않습니다.

Beaglebone Black에 액세스 할 수 없어서 이것을 테스트 할 수 없습니다. 관찰 된 행동을 설명합니다. 프로그램이 초기화되지 않은 SRAM의 문자열을 복사하기 때문에 표시 할 내용을 보증 할 수 없습니다. 프로그램 내에서 메모리에 액세스하려는 다른 시도가 없으므로 이것이 유일한 문제입니다.

링커 스크립트를 변경하고 다시 작성하면 결과는 약간 다릅니다 (download.bin). 원래 링커 스크립트 내 제안 된 변화에 의해 생성 된 분해 download.bin 사이의 DIFF입니다 : 당신은 분명히 문자열을 복사하는 새 주소 참조를 볼 수 있습니다

10c10 
< 8: 402f1638  eormi r1, pc, r8, lsr r6  ; <UNPREDICTABLE> 
--- 
> 8: 800andhi r1, r0, r8, lsr r2 
28,29c28,29 
< 50: e300262c  movw r2, #1580  ; 0x62c 
< 54: e344202f  movt r2, #16431  ; 0x402f 
--- 
> 50: e300222c  movw r2, #556  ; 0x22c 
> 54: e3482000  movt r2, #32768  ; 0x8000 

. 불행히도, 나는 다른 변화가 무엇인지, 그리고이 변화가 어떤 문제를 야기하는지 확신 할 수 없다.

문자열이 0x8000022c인지 확인하기 위해 xxd를 사용하여 download.bin을 덤프 할 수 있습니다. 출력은 다음과 같습니다

% xxd download.bin 
0000000: 00d0 1fe5 0e00 00eb 3816 2f40 04b0 2de5 ........8./@..-. 
0000010: 00b0 8de2 14d0 4de2 0030 a0e1 0d30 4be5 ......M..0...0K. 
[... omitted lots of lines ...] 
0000220: 0500 53e3 cdff ffda feff ffea 4865 6c6c ..S.........Hell 
0000230: 6f00 0000        o... 

문자열 Hello0x22c에서 볼 수 있습니다. 0x80000000에로드되면 문자열이 복사 된 주소가 올바른 것 같습니다.

+1

무슨 잡기! 이 문제가 있는지보기를 기대합니다. –

+0

오! silliest 나 지금 그 덕분에 생각하지 않았습니다 XD – Uint32

+0

축하해, 와우, 정말 까다 롭습니다! 참여한 모든 사람들의 인상적인 직업! –

관련 문제