Skip to main content
ccowdery9
Associate III
October 16, 2009
Question

Retarget printf() on GCC / IDEaliST?

  • October 16, 2009
  • 12 replies
  • 3000 views
Posted on October 16, 2009 at 08:52

Retarget printf() on GCC / IDEaliST?

    This topic has been closed for replies.

    12 replies

    ccowdery9
    ccowdery9Author
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    Hi,

    I would like to retarget printf() to the uart. I have checked out the application note & example, and they don't work.

    I have tried defining the following three functions:

    int __io_putchar(int ch)

    int fputc(int ch, FILE *f)

    int _write(int file,char *ptr,int len)

    and none of them are called when I execute a printf()

    My dev tools are Anglia IDEaliST, which uses GCC.

    Any pointers gratefully received.

    Thanks,

    Chris.

    jaroslaw2
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    This example works fine with RIDE 7. This is because RIDE has it's own printf. They call it small printf.

    Did you try to change environment into RIDE 7. I used to work with Anglia but then I moved into RIDE. It is better, in my opinion, and it is free too.

    relaxe
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    Below is code found inside the FWLib examples. It works fine for printf() with me. I have no clue about scanf tho...

    ////////////////////////////////////////////////////////////////////

    // Redirect fputc to the serial port, so printf() outputs to USART1.

    #ifdef __GNUC__

    /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf

    set to 'Yes') calls __io_putchar() */

    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

    #else

    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

    #endif /* __GNUC__ */

    ///////////////////////////////////////////////////////////////////

    /*******************************************************************************

    * Function Name : PUTCHAR_PROTOTYPE

    * Description : Retargets the C library printf function to the USART.

    * Input : None

    * Output : None

    * Return : None

    *******************************************************************************/

    PUTCHAR_PROTOTYPE

    {

    /* Place your implementation of fputc here */

    /* e.g. write a character to the USART */

    USART_SendData(USART1, (u8) ch);

    /* Loop until the end of transmission */

    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)

    {}

    return ch;

    }

    ccowdery9
    ccowdery9Author
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    That doesn't work for me for some reason.... :(

    Chris.

    pramod
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    Hi Chris,

    Thanks for your post.

    Unfortunately, the same does not work for me.

    I get linker errors like this:

    ...libc.a uses FPA instructions, whereas Hello.elf does not.

    I use GCC version 4.4.1. I specify ''-mfpu=vfp'' in compiler options.

    Is that the reason? But aren't we supposed to use ''-mfpu=vfp'' for

    Cortex-M3 processors?

    Which processor do you use? And do you use ''-mfpu=vfp'' option?

    Regards,

    Pramod

    Quote:

    Quote:

    Quote:

    ccowdery9
    ccowdery9Author
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    OK, sorted (with thanks to Spencer for some helpful clues).

    The redirection required is _write_r(). This is my implementation

    Code:

    int _write_r(void *reent, int fd, char *ptr, size_t len)

    {

    size_t i;

    for (i=0; i<len; i++)

    {

    uart_putc(ptr[i]);

    }

    return len;

    }

    However, newlib wasn't calling _write_r because malloc was failing. This turned out to be because the stack / heap was insufficient. Under these circumstances, newlib calls exit() which hangs up.

    So I changed the relevant part of my linker script to:

    Code:

    _STACKSIZE = 8192;

    _HEAPSIZE = 512;

    and Bingo, it worked!

    I also decided to leave in a verbose version of _sbrk_r to give me warning if it hangs up for the same reason in the future:

    Code:

    void exit(int n)

    {

    uart_puts(''exit()n'');

    while(1);

    }

    register char *stack_ptr asm (''sp'');

    caddr_t _sbrk_r(void *reent, size_t incr)

    {

    extern char end asm (''end''); // Defined by the linker

    //extern char end asm (''__heap_start__''); // Defined by the linker

    static char *heap_end;

    char *prev_heap_end;

    if( heap_end == NULL )

    heap_end = &end;

    prev_heap_end = heap_end;

    if(( heap_end + incr ) > stack_ptr )

    {

    /* Some of the libstdc++-v3 tests rely upon detecting

    out of memory errors, so do not abort here. */

    //write( 1, ''sbrk: Heap and stack collisionn'', 32 );

    //abort();

    uart_puts(''HALT - heap exhaustedn'');

    exit(1);

    //errno = ENOMEM;

    return (caddr_t) -1;

    }

    heap_end += incr;

    return (caddr_t) prev_heap_end;

    }

    I hope this helps somebody else.

    Chris.

    pramod
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    Hi,

    Thanks Chris and slawcus.

    It seems that Chris is using ARM7, so it works.

    On the other hand, I am using Cortex-M3.

    slawcus, do you mean I should not use -mfpu=vfp ?

    I tried to change it to -mfpu=fpa because that is what the gcc library

    functions seem to use. After that, there were no errors, but some

    warnings:

    interworking not enabled.

    And the code does not work (no output).

    Perhaps -mfpu=vfp is the only choice for Cortex-M3. However, the gcc

    library is built with fpa option, so I can not link to it? If so, how

    can I get gcc library built for Cortex-M3 (i.e. with fpa option)?

    Regards,

    Pramod

    ccowdery9
    ccowdery9Author
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    I'm using IDEaliST, and the gcc command is:

    main.c -mthumb -march=armv7-m -g -ffunction-sections -fdata-sections -Wall -O2 -Iinc -Iusb/inc -Ifat/inc -Ifat/conf -Ifat/inc/interfaces

    Chris.

    slawcus
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    Option that you use is for floating point units. Something that Cortex-M3 doesn't have.

    http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html#ARM-Options

    pramod
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 12:55

    Hi slawcus,

    Tried -msoft-float already, but it does not work :(

    It produces error:

    ...libc.a uses Hardware FP, whereas Hello.elf uses Software FP.

    Once again, I feel that Cortex-M3 does not have hardware FP, but the

    gcc library is built using hardware FP option. So can't use this

    library for Cortex-M3. Question is how / where to get library built

    with sofware FP (suitable for Cortex-M3) ?

    Regards,

    Pramod