cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 GCC printf

pedro
Associate II
Posted on July 17, 2015 at 04:14

Hello.

I'm trying, for the first time in my life,to implement the printf/scanf functions on GCC. I managed to get the UART working in interrupt mode but somehow I can not do the easiest part. That is, I can not retarget the printf. I read that I needed to change the _write and _read function on syscalls.c so I did it. As a result, I can print only one character and then, the printf goes to HARD_FAULT. I also tried to use the retarget.c file that I used on keil and it compiled exept from the ferror fuction. But it did nothing. Below, I show my syscalls.c file. I'm using System Worbench for stm32 with gcc. thanks

/* Includes */
#include <
sys
/stat.h>
#include <
stdlib.h
>
#include <
errno.h
>
#include <
stdio.h
>
#include <
signal.h
>
#include <
time.h
>
#include <
sys
/time.h>
#include <
sys
/times.h>
#include ''serialport.h''
/* Variables */
//#undef errno
extern int errno;
extern int __io_putchar(int ch) __attribute__((weak));
extern int __io_getchar(void) __attribute__((weak));
register char * stack_ptr asm(''sp'');
char *__env[1] = { 0 };
char **environ = __env;
/* Functions */
void initialise_monitor_handles()
{
}
int _getpid(void)
{
return 1;
}
int _kill(int pid, int sig)
{
errno = EINVAL;
return -1;
}
void _exit (int status)
{
_kill(status, -1);
while (1) {} /* Make sure we hang here */
}
int _read (int file, char *ptr, int len)
{
int DataIdx;
for (DataIdx = 0; DataIdx < 
len
; DataIdx++)
{
//*ptr++ = __io_getchar();
*ptr++ = GetKey();
}
return len;
}
int _write(int file, char *ptr, int len)
{
int DataIdx;
for (
DataIdx
= 
0
; DataIdx < len; DataIdx++)
{
//__io_putchar(*ptr++);
SendChar((*ptr++));
}
return len;
}
caddr_t _sbrk(int incr)
{
extern char end asm(''end'');
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0)
heap_end = &end;
prev_heap_end
= heap_end;
if (heap_end + incr > stack_ptr)
{
// write(1, ''Heap and stack collision\n'', 25);
// abort();
errno = ENOMEM;
return (caddr_t) -1;
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
int _close(int file)
{
return -1;
}
int _fstat(int file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
int _isatty(int file)
{
return 1;
}
int _lseek(int file, int ptr, int dir)
{
return 0;
}
int _open(char *path, int flags, ...)
{
/* Pretend like we always fail */
return -1;
}
int _wait(int *status)
{
errno = ECHILD;
return -1;
}
int _unlink(char *name)
{
errno = ENOENT;
return -1;
}
int _times(struct tms *buf)
{
return -1;
}
int _stat(char *file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
int _link(char *old, char *new)
{
errno = EMLINK;
return -1;
}
int _fork(void)
{
errno = EAGAIN;
return -1;
}
int _execve(char *name, char **argv, char **env)
{
errno = ENOMEM;
return -1;
}

6 REPLIES 6
Posted on July 17, 2015 at 05:21

Nothing really leaping out there. You could try calling _write() directly. Check stack. Check what the Hard Fault is complaining about.

Pretty sure I have the printf() working, will dig it up tomorrow.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pedro
Associate II
Posted on July 17, 2015 at 05:31

Just tested the __write directly to print 20 characters. 

It worked fine.

Tomorrow, I will try to enable all the exeption handlers to see if I can find the cause of the hard fault.

I already saw from the assembly, that when I use a string with more than one character the program crashes from inside printf and does not print anything. But when I put one character it works fine. I actually can see the printf going to __write to print a string of length 1, in that situation.

Thanks clive.

Posted on July 17, 2015 at 14:03

Make sure the stack is large enough and properly aligned.

The F7 cube STILL had this stupidity despite being pointed out months ago.

/* Highest address of the user mode stack */
_estack = 0x2004FFFF; /* end of RAM */

STM32Cube_FW_F7_V1.1.0\Projects\STM32746G-Discovery\Demonstration\SW4STM32\STM32F7-DISCO\STM32F746NGHx_FLASH.ld
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pedro
Associate II
Posted on July 17, 2015 at 15:07

The changes I made to my LinkerScript.ld

/* Highest address of the user mode stack */

_estack = 0x2004FF00;    /* end of RAM */

/* Generate a link error if heap and stack don't fit into RAM */

_Min_Heap_Size = 0x200;;      /* required amount of heap  */

_Min_Stack_Size = 0xF00;; /* required amount of stack */

Nothing changed. I will try to understand why is it going to hardfault during the day.
pedro
Associate II
Posted on July 17, 2015 at 15:58

Yeah, thanks clive! I managed to solve the problem thanks to you.

When I found that error of ''Attempting to execute a coproccessor instruction'' on the SCB->CFSR it hit me that the FPU might not be enabled and that was the case.

Now the printf is working after so many hours lost because of my stupidity.

Amel NASRI
ST Employee
Posted on February 05, 2016 at 13:26

Hi,

Please note that the end of RAM related issue in the .ld files is already taken into account.

The fix will be available in coming versions.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.