Skip to content

Instantly share code, notes, and snippets.

@Rajssss
Last active September 2, 2022 09:07
Show Gist options
  • Save Rajssss/642333aabdd6f3bd952f10e1113d23b3 to your computer and use it in GitHub Desktop.
Save Rajssss/642333aabdd6f3bd952f10e1113d23b3 to your computer and use it in GitHub Desktop.
Retargetting STDIO (printf, scanf) to UARTx in STM32 MCUs.
/*
* retarget_stdio.c
*
* Created on: 17-Oct-2020
* Author: Raj.S
*/
#include "stm32f4xx_hal.h"
#include "retarget_stdio.h"
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
void RetargetInit(USART_TypeDef *UARTx)
{
gHuart.Instance = UARTx;
gHuart.Init.BaudRate = 115200;
gHuart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
gHuart.Init.Mode = UART_MODE_TX_RX;
gHuart.Init.Parity = UART_PARITY_NONE;
gHuart.Init.StopBits = UART_STOPBITS_1;
gHuart.Init.WordLength = UART_WORDLENGTH_8B;
HAL_UART_Init(&gHuart);
/* Disable I/O buffering for STDOUT stream, so that
* chars are sent out as soon as they are printed. */
setvbuf(stdout, NULL, _IONBF, 0);
}
/*void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_UART2;
GPIO_UART2.Alternate = GPIO_AF7_USART2;
GPIO_UART2.Mode = GPIO_MODE_AF_PP;
GPIO_UART2.Pin = GPIO_PIN_2; //USART2 Tx
GPIO_UART2.Pull = GPIO_PULLUP;
GPIO_UART2.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOA, &GPIO_UART2);
GPIO_UART2.Pin = GPIO_PIN_3; //USART2 Rx
HAL_GPIO_Init(GPIOA, &GPIO_UART2);
HAL_NVIC_EnableIRQ(USART2_IRQn);
HAL_NVIC_SetPriority(USART2_IRQn, 15, 0);
}*/
int _write(int fd, char* ptr, int len)
{
HAL_StatusTypeDef hstatus;
if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
{
hstatus = HAL_UART_Transmit(&gHuart, (uint8_t *) ptr, len, HAL_MAX_DELAY);
if (hstatus == HAL_OK)
return len;
else
return EIO;
}
errno = EBADF;
return -1;
}
int _read(int fd, char* ptr, int len) {
HAL_StatusTypeDef hstatus;
if (fd == STDIN_FILENO) {
hstatus = HAL_UART_Receive(&gHuart, (uint8_t *) ptr, 1, HAL_MAX_DELAY);
if (hstatus == HAL_OK)
return 1;
else
return EIO;
}
errno = EBADF;
return -1;
}
@Rajssss
Copy link
Author

Rajssss commented Mar 17, 2021

/*
 * retarget_stdio.h
 *
 *  Created on: 17-Mar-2021
 *      Author: Raj.S
 */

#ifndef INC_RETARGET_STDIO_H_
#define INC_RETARGET_STDIO_H_
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>

UART_HandleTypeDef gHuart;

void RetargetInit(USART_TypeDef *UARTx);

#endif /* INC_RETARGET_STDIO_H_ */

@Rajssss
Copy link
Author

Rajssss commented Feb 20, 2022

#define log(fmt, ...) printf("%s: %s: " fmt, __FILE__, __FUNCTION__, ##__VA_ARGS__)

@Richard-Rumpel
Copy link

Richard-Rumpel commented Sep 2, 2022

I think you have made a lite mistake in your _read(...) function. In case of an hal error your code should set errno to EIO and return 0.

int _read(int fd, char* ptr, int len) {
	HAL_StatusTypeDef hstatus;

	if (fd == STDIN_FILENO) {
		hstatus = HAL_UART_Receive(&gHuart, (uint8_t *) ptr, 1, HAL_MAX_DELAY);
		if (hstatus == HAL_OK)
			return 1;
		else
			errno = EIO;
	}
	return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment