0

さまざまな印刷コマンドに問題があります。
printf() を呼び出そうとするたびに、システムがハングするか、リセットされることがあります。
UART が動作しており、UART_PutChar() を使用してコンソールに正常に出力できます。
fprintf は単純な文字列を印刷するだけの単純なケースで機能しますfprintf(stdout, "test\n");
が、フォーマットされた文字列はシステムをfprintf(stdout, "test %d\n", 1);
ハングさせます .data セクションからデータを印刷しようとしているときにもハングが発生します

char* dataString = "test\n\0";

int main(){
     fprintf(stdout, dataString);
}

改行を印刷するとprintfが機能しますprintf("\n");
printfは、次のような場合にのみ 改行を印刷します

fputc('B', stdin); //notice stdin
printf("test\n"); //prints newline

場合によっては、fprintf が失敗すると、EOF が返されます (今は覚えていないので、関連性があれば明日提供します)
(f)printf は putchar を呼び出しているようで、UART に再ターゲットしました。不思議なことに、それは newlib-nano によって提供される呼び出しまたはルーチン
であるべきだと思います(そして printf はそれらを呼び出していません)。 IDE として、EmBitz とそれが提供するツールチェーン (arm-none-eabi) を使用しています。私が使用しているCPUはat91sam7x128です。JTAG を使用してプログラムをデバッグできないため、デバッグには UART のみを使用する必要があります。_write_write_r

char* dataSection = "data\n\0";
char* dataSingle = "A";
int bssSection = 0;

int main(){
    fprintf(stdout, "plain\n"); //works
    fprintf(stdout, dataSingle); //works
    fprintf(stdout, *(char*)(bssSection + 0x41)); //prints A, works
    printf("\n"); //works
    fprintf(stdout, "%d", 1); //hangs
    fprintf(stdout, dataSection); //hangs
    printf("plain printf\n"); //hangs
}

UPDATE スターター スクリプト: SAM7.s

/*********************************************************************
*
*       Defines, used for the processor status register
*
**********************************************************************
*/
        ARM_MODE_USER  = 0x10        /* Normal User Mode                             */
        ARM_MODE_FIQ   = 0x11        /* FIQ Fast Interrupts Mode                     */
        ARM_MODE_IRQ   = 0x12        /* IRQ Standard Interrupts Mode                 */
        ARM_MODE_SVC   = 0x13        /* Supervisor Interrupts Mode                   */
        ARM_MODE_ABORT = 0x17        /* Abort Processing memory Faults Mode          */
        ARM_MODE_UNDEF = 0x1B        /* Undefined Instructions Mode                  */
        ARM_MODE_SYS   = 0x1F        /* System Running in Priviledged Operating Mode */
        ARM_MODE_MASK  = 0x1F

        I_BIT          = 0x80        /* Disables IRQ when I bit is set               */
        F_BIT          = 0x40        /* Disables FIQ when F bit is set               */  

/*********************************************************************
*
*       Vector table
*
**********************************************************************
*/
        .text
        .global  __vector
        .global  _exit

        .extern  Reset_Handler

        .arm
        .section .vectors, "ax"

__vector:
        ldr     pc,Reset_Addr   /* RESET                 vector */


Reset_Addr:     .word   Reset_Handler

__vector_end:

/*********************************************************************
*
*       Standard C (crt0) initialization function
*
**********************************************************************
*/
        .global OS_GetStackInfo
        .extern  __low_level_init
        .extern  main

crt0:
        /*
         * Call __low_level_init to initiliaze hardware
         * before calling c-standard startup
         */
        ldr     r0,=__low_level_init
        mov     lr, pc
        bx      r0
        /*
         * Relocate .data section
         * (Copy from ROM to RAM)
         */
        ldr   r1, =_etext
        ldr   r2, =_data
        ldr   r3, =_edata
LoopRel:
        cmp   r2, r3
        ldrlo r0, [r1], #4
        strlo r0, [r2], #4
        blo   LoopRel

        /*
         * Clear .bss section
         */
        ldr   r1, =__bss_start__
        ldr   r2, =__bss_end__
        ldr   r3, =0
bss_clear_loop:
        cmp   r1, r2
        strne r3, [r1], #+4
        bne   bss_clear_loop
        /*
         *  Prepare and call main()
         */
        mrs   r0, cpsr
        bic   r0, r0, #(I_BIT | F_BIT)     /* Enable FIQ and IRQ interrupt */
        msr   cpsr, r0
        mov   r0, #0                         /* No arguments are passed to main */
        mov   r1, #0
        ldr   r2, =main
        mov   lr, pc
        bx    r2
_exit:  b     _exit                          /* We should never come to here, just for sureness. */

/*********************************************************************
*
*       __low_level_init
*
**********************************************************************
*/
__low_level_init:
        bx lr
        .weak __low_level_init

/**********************************************************************
* Reset_Handler
*
* Execution starts here.
* After a reset, the mode is ARM, Supervisor, interrupts disabled.
*/
        .global  Reset_Handler
        .global  end
        .arm
        .section .text, "ax"

Reset_Handler:
        /*
         * Setup a stack for each mode
         */
        msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */
        ldr   sp, =__stack_und_end__

        msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */
        ldr   sp, =__stack_abt_end__

        msr   CPSR_c, #ARM_MODE_FIQ   | I_BIT | F_BIT   /* FIQ Mode */
        ldr   sp, =__stack_fiq_end__

        msr   CPSR_c, #ARM_MODE_IRQ   | I_BIT | F_BIT   /* IRQ Mode */
        ldr   sp, =__stack_irq_end__

        msr   CPSR_c, #ARM_MODE_SVC   | I_BIT | F_BIT   /* Supervisor Mode */
        ldr   sp, =__stack_svc_end__

        /*
         * Now enter crt0 function,
         * which does low-level and segment initialization.
         * and then calls main().
         */
        ldr   r0, =crt0
        mov   lr, pc
        bx    r0
end:    b     end
        .end

リンカー スクリプト

ENTRY(__vector)

/*********************************************************************
*
*       Define stack sizes here
*/

FIQ_STACK_SIZE = 0x0;
IRQ_STACK_SIZE = 0x1000;
ABT_STACK_SIZE = 0x0;
UND_STACK_SIZE = 0x0;
SVC_STACK_SIZE = 0x1000;

MEMORY
{
  RAM   (wx)  : ORIGIN = 0x200000, LENGTH = 0x8000
  FLASH (rx)  : ORIGIN = 0x100000, LENGTH = 0x10000
}

SECTIONS
{



  .text :
  {
    *(.vectors);
    . = ALIGN(8);
    *(.init);
    . = ALIGN(8);
    *(.text);
    . = ALIGN(8);
    *(.rodata);
    . = ALIGN(8);
    *(.rodata*);
    . = ALIGN(8);
    *(.glue_7t);
    . = ALIGN(8);
    *(.glue_7);
    . = ALIGN(8);
    etext = .;
  } > FLASH


  . = ALIGN(8);
  _etext = . ;
  PROVIDE (etext = .);

  .data : AT (_etext)
  {
    PROVIDE (__data_start__ = .);
    _data = . ;
    *(.data)
    . = ALIGN(8);
    PROVIDE (__data_end__ = .);
  } > RAM

  . = ALIGN(8);
  _edata = . ;
  PROVIDE (edata = .);

  .bss :
  {
    PROVIDE (__bss_start__ = .);
    *(.bss)
    *(COMMON)
    . = ALIGN(8);
    PROVIDE (__bss_end__ = .);

    . = ALIGN(256);

    PROVIDE (__stack_start__ = .);

    PROVIDE (__stack_fiq_start__ = .);
    . += FIQ_STACK_SIZE;
    . = ALIGN(8);
    PROVIDE (__stack_fiq_end__ = .);

    PROVIDE (__stack_irq_start__ = .);
    . += IRQ_STACK_SIZE;
    . = ALIGN(8);
    PROVIDE (__stack_irq_end__ = .);

    PROVIDE (__stack_abt_start__ = .);
    . += ABT_STACK_SIZE;
    . = ALIGN(8);
    PROVIDE (__stack_abt_end__ = .);

    PROVIDE (__stack_und_start__ = .);
    . += UND_STACK_SIZE;
    . = ALIGN(8);
    PROVIDE (__stack_und_end__ = .);

    PROVIDE (__stack_svc_start__ = .);
    PROVIDE (__stack_svc_end__ = .);
    PROVIDE (__stack_end__ = .);
    PROVIDE (__heap_start__ = .);
    . += 0x1000;
    . = ALIGN(8);
    PROVIDE (__heap_end__ = .);
  } > RAM
}

更新 2 syscall の私の迅速で汚い再実装。

int _write(int fd, char* buf, int len){
    LED_On(1);
    while(*buf){
        UART_PutChar(*buf++);
    }
    return len;
}

void _ttywrch(int ch) {
    LED_On(1);
    UART_PutChar(ch);
}

signed int
putchar(signed int c)
{
   return fputc(c, stdout);
}

signed int
fputs(const char* pStr, FILE* pStream)
{
   signed int num = 0;

   while (*pStr != 0)
   {
      if (fputc(*pStr, pStream) == -1)
      {
         return -1;
      }

      num++;
      pStr++;
   }

   return num;
}

int
fputc(int c, FILE* pStream)
{
   if ((pStream == stdout) || (pStream == stderr))
   {
#ifdef UART_CONSOLE_CRLF
      if (c == '\n')
         UART_PutChar('\r');
#endif

      UART_PutChar(c);

      return c;
   }
   else
   {
      return EOF;
   }
}
4

2 に答える 2

0

printf()このタイプの組み込みシステムでは、通常、かなりの量のサポートが必要です。_write()特に、関数を実装する必要がありますが、単純な文字列の正常な出力は、それが存在し、機能していることを示しています。

むしろ、printf() がメモリを割り当てる必要がある状況で問題が発生するようです。依存関係の長いチェーンを介して、これは単純な malloc() を通過し、最終的に実装を呼び出すことになります

void *_sbrk(int increment)

ヒープサイズを増やします。その実装がない場合、またはそれが失敗したり他の領域と衝突したりする場合、生成するためにいくつかのつなぎ合わせが必要な出力でのみ失敗が発生する理由を簡単に説明できます。

于 2016-06-01T19:54:32.227 に答える