2011-08-01 07:56 PM
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!2016-02-28 11:46 PM
You need only syscalls implementation with _write and _read function.
2016-02-29 09:28 AM
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));
}
//******************************************************************************
2017-09-25 01:35 AM