Loading...
 

Zephyr project on STM32

   Zephyr Workbench, a VSCode extension to manage Zephyr on STM32.
It enables users to easily create, develop, and debug Zephyr applications.
Main features:
  • Install host dependencies.
  • Import toolchain and SDK.
  • Create, configure, build and manage apps.
  • Debug STM32.
You can directly download it from the VSCode marketplace
For more details, visit the Zephyr Workbench

System Workbench for STM32


You are viewing a reply to printf through uart  

printf through uart

The way I got printf (and all other console-oriented stdio functions) to work was by creating custom implementations of the low-level I/O functions like _read() and _write().

The GCC C library makes calls to the following functions to perform low-level I/O :

 
int _read(int file, char *data, int len)
int _write(int file, char *data, int len)
int _close(int file)
int _lseek(int file, int ptr, int dir)
int _fstat(int file, struct stat *st)
int _isatty(int file)


These functions are implemented witihin the GCC C library as stub routines with “weak” linkage. If a declaration of any of the above functions appears in your own code, your substitute routine will override the declaration in the library and be used instead of the default (non-functional) routine.

I have copied my implementations of these functions below. You will need to substitute the calls to UART_TxBlocking() and UART_RxBlocking() with calls to whatever functions you have created that do U(S)ART I/O.

x
 
#ifdef __GCC__
#include  <errno.h>
#include  <stdio.h>
#include  <sys/stat.h>
#include  <sys/unistd.h>
#include "stdio_helper_gcc.h" 
#include "UART.h"
#undef errno
extern int errno;
/******************************************************************************
 *
 ******************************************************************************/
void stdio_setup(int no_init)
{
    if (! no_init)
    {
        UART_Init(0);
    }
    // Turn off buffers, so I/O occurs immediately
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
}
/******************************************************************************
 *
 ******************************************************************************/
int _read(int file, char *data, int len)
{
    int bytes_read;
    if (file != STDIN_FILENO)
    {
        errno = EBADF;
        return -1;
    }
    for (bytes_read = 0; bytes_read < len; bytes_read++)
    {
        *data = (char) UART_RxBlocking();
        data++;
    }
    return bytes_read;
}
/******************************************************************************
 *
 ******************************************************************************/
int _write(int file, char *data, int len)
{
    int bytes_written;
    if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
    {
        errno = EBADF;
        return -1;
    }
    for (bytes_written = 0; bytes_written < len; bytes_written++)
    {
        UART_TxBlocking(*data);
        data++;
    }
    return bytes_written;
}
/******************************************************************************
 *
 ******************************************************************************/
int _close(int file)
{
    return -1;
}
/******************************************************************************
 *
 ******************************************************************************/
int _lseek(int file, int ptr, int dir)
{
    return 0;
}
/******************************************************************************
 *
 ******************************************************************************/
int _fstat(int file, struct stat *st)
{
    st->st_mode = S_IFCHR;
    return 0;
}
/******************************************************************************
 *
 ******************************************************************************/
int _isatty(int file)
{
    if ((file == STDOUT_FILENO) ||
        (file == STDIN_FILENO) ||
        (file == STDERR_FILENO))
    {
        return 1;
    }
    errno = EBADF;
    return 0;
}
#endif