cancel
Showing results for 
Search instead for 
Did you mean: 

Retargeting stdio to USART1

avinash_elec
Associate III
Posted on August 02, 2011 at 04:56

Hello,

I have USART1 configured properly and running. I am using the following code to write to the USART1

[code]

USART_SendData(USART1,'A');

/* Loop until the end of transmission */

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

[/code]

The above code is working.

The problem is coming when I am trying to retarget the output of printf() to USART1

Following is the code to overide the fputc() function

[code]

/**

  * @brief  Retargets the C library printf function to the USART.

  * @param  None

  * @retval None

  */

int fputc(int ch, FILE *f)

{

      /* Place your implementation of fputc here */

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

      USART_SendData(USART1,(uint8_t)ch);

    /* Loop until the end of transmission */

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

      return ch;

}

[/code]

But when ever I am trying to use printf() the USART start sending NULL's repeatedly.

Tool Chain: RV Compiler on Keil RVMDK (demo)

Any help is appreciated!

12 REPLIES 12
Radosław
Senior II
Posted on February 29, 2016 at 08:46

You need only syscalls implementation with _write and _read function.

Posted on February 29, 2016 at 18:28

I'm trying to retarget the C library printf function to the USART using arm-none-eabi toolchain on Ubuntu. Where and how do I get <rt_misc.h> header?

The OP was using KEIL, not GNU/GCC, you're not going to have the Keil include files. For your situation, you'd need a newlib_stubs.c like file, doing this

/*
* newlib_stubs.c
*
* Minimal implementation after nanoage.co.uk
*/
#include <
errno.h
>
#include <
sys
/stat.h>
#include <
sys
/times.h>
#include <
sys
/unistd.h>
#include ''stm32f10x.h''
extern int __io_putchar(int ch);
extern int __io_getchar(void);
#undef errno
extern int errno;
/*
environ
A pointer to a list of environment variables and their values.
For a minimal environment, this empty list is adequate:
*/
char *__env[1] = { 0 };
char **environ = __env;
int _write(int file, char *ptr, int len);
void _exit(int status) {
_write(1, ''exit'', 4);
while (1) {
;
}
}
int _close(int file) {
return -1;
}
/*
execve
Transfer control to a new process. Minimal implementation (for a system without processes):
*/
int _execve(char *name, char **argv, char **env) {
errno = ENOMEM;
return -1;
}
/*
fork
Create a new process. Minimal implementation (for a system without processes):
*/
int _fork() {
errno = EAGAIN;
return -1;
}
/*
fstat
Status of an open file. For consistency with other minimal implementations in these examples,
all files are regarded as character special devices.
The `sys/stat.h' header file required is distributed in the `include' subdirectory for this C library.
*/
int _fstat(int file, struct stat *st) {
st->st_mode = S_IFCHR;
return 0;
}
/*
getpid
Process-ID; this is sometimes used to generate strings unlikely to conflict with other processes. Minimal implementation, for a system without processes:
*/
int _getpid() {
return 1;
}
/*
isatty
Query whether output stream is a terminal. For consistency with the other minimal implementations,
*/
int _isatty(int file) {
switch (file){
case STDOUT_FILENO:
case STDERR_FILENO:
case STDIN_FILENO:
return 1;
default:
//errno = ENOTTY;
errno = EBADF;
return 0;
}
}
/*
kill
Send a signal. Minimal implementation:
*/
int _kill(int pid, int sig) {
errno = EINVAL;
return (-1);
}
/*
link
Establish a new name for an existing file. Minimal implementation:
*/
int _link(char *old, char *new) {
errno = EMLINK;
return -1;
}
/*
lseek
Set position in a file. Minimal implementation:
*/
int _lseek(int file, int ptr, int dir) {
return 0;
}
/*
sbrk
Increase program data space.
Malloc and related functions depend on this
*/
caddr_t _sbrk(int incr) {
extern char _ebss; // Defined by the linker
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &_ebss;
}
prev_heap_end = heap_end;
char * stack = (char*) __get_MSP();
if (heap_end + incr > stack)
{
_write (STDERR_FILENO, ''Heap and stack collision
'', 25);
errno = ENOMEM;
return (caddr_t) -1;
//abort ();
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
/*
read
Read a character to a file. `libc' subroutines will use this system routine for input from all files, including stdin
Returns -1 on error or blocks until the number of characters have been read.
*/
int _read(int file, char *ptr, int len) {
int n;
int num = 0;
switch (file) {
case STDIN_FILENO:
for (n = 0; n < 
len
; n++) {
*ptr++ = __io_getchar();
num++;
}
break;
default:
errno
= 
EBADF
;
return -1;
}
return num;
}
/*
stat
Status of a file (by name). Minimal implementation:
int _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
*/
int _stat(const char *filepath, struct stat *st) {
st->st_mode = S_IFCHR;
return 0;
}
/*
times
Timing information for current process. Minimal implementation:
*/
clock_t _times(struct tms *buf) {
return -1;
}
/*
unlink
Remove a file's directory entry. Minimal implementation:
*/
int _unlink(char *name) {
errno = ENOENT;
return -1;
}
/*
wait
Wait for a child process. Minimal implementation:
*/
int _wait(int *status) {
errno = ECHILD;
return -1;
}
/*
write
Write a character to a file. `libc' subroutines will use this system routine for output to all files, including stdout
Returns -1 on error or number of bytes sent
*/
int _write(int file, char *ptr, int len) {
int n;
switch (file) {
case STDOUT_FILENO: /*stdout*/
case STDERR_FILENO: /* stderr */
for (n = 0; n < len; n++) {
__io_putchar(*ptr++);
}
break;
default:
errno = EBADF;
return -1;
}
return len;
}

And supporting functions like these

#include ''stm32f10x.h''
//****************************************************************************
void USART1_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure); /* Configure USART */
USART_Cmd(USART1, ENABLE); /* Enable the USART */
}
//******************************************************************************
/**
* @brief Retargets the C library printf function to the USART (GNU)
* @param None
* @retval None
*/
int __io_putchar(int ch)
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
/* Loop until the transmission buffer is empty */
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, (uint8_t) ch);
return(ch);
}
//******************************************************************************
/**
* @brief Retargets the C library scanf function to the USART (GNU)
* @param None
* @retval None
*/
int __io_getchar(void)
{
/* Place your implementation of fgetc here */
/* e.g. read a character from the USART */
/* Loop until the reception buffer is not empty */
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
return((int)USART_ReceiveData(USART1));
}
//******************************************************************************

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ColdWeather
Senior
Posted on September 25, 2017 at 10:35

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6su&d=%2Fa%2F0X0000000bxH%2FTsdFgxxOt73HjsQfTkt39ULNzPcrHt3WBwNTNrpVA_0&asPdf=false