How to retarget printf() on an STM32F10x?

前端 未结 4 1166
迷失自我
迷失自我 2021-01-23 23:19

I use this code for retarget printf(), but it does not work

#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->         


        
相关标签:
4条回答
  • 2021-01-23 23:23

    Tank you Bence Kaulics

    I use tinyprintf library and it worked quite well : github link

    0 讨论(0)
  • 2021-01-23 23:24

    As an alternative, you could write your own printf() function using, Variable Argument Functions (va_list).

    With va_list a custom print function looks like the following:

    #include <stdio.h>
    #include <stdarg.h>
    #include <string.h>
    
    void vprint(const char *fmt, va_list argp)
    {
        char string[200];
        if(0 < vsprintf(string,fmt,argp)) // build string
        {
            HAL_UART_Transmit(&huart1, (uint8_t*)string, strlen(string), 0xffffff); // send message via UART
        }
    }
    
    void my_printf(const char *fmt, ...) // custom printf() function
    {
        va_list argp;
        va_start(argp, fmt);
        vprint(target, fmt, argp);
        va_end(argp);
    }
    

    Usage example:

    uint16_t year = 2016;
    uint8_t month = 10;
    uint8_t day   = 02;
    char* date = "date";
    
    // "Today's date: 2015-12-18"
    my_printf("Today's %s: %d-%d-%d\r\n", date, year, month, day);
    

    Note that while this solution gives you convenient function to use, it is slower than sending raw data or using even sprintf(). I have used this solution both on AVR and on STM32 microcontrollers.

    You could further modify the vprint like this, where periphery_t is a simple enum type:

    void vprint(periphery_t target, const char *fmt, va_list argp)
    {
        char string[200];
        if(0 < vsprintf(string,fmt,argp))
        {
            switch(target)
            {
                case PC: PC_send_str(string);
                    break;
                case GSM: GSM_send_str(string);
                    break;
                case LCD: LCD_print_str(string);
                    break;
                default: LCD_print_str(string);
                    break;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-23 23:33

    just make sure to add the following in the init code:

    // Turn off buffers, so I/O occurs immediately
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
    
    0 讨论(0)
  • 2021-01-23 23:35

    Try hijacking the _write function like so:

    #define STDOUT_FILENO   1
    #define STDERR_FILENO   2
    
    int _write(int file, char *ptr, int len)
    {
        switch (file)
        {
        case STDOUT_FILENO: /*stdout*/
            // Send the string somewhere
            break;
        case STDERR_FILENO: /* stderr */
            // Send the string somewhere
            break;
        default:
            return -1;
        }
        return len;
    }
    
    0 讨论(0)
提交回复
热议问题