Hello,
I'm working with the AT91RM9200 - the USART is already configurated and works but I don't know how I could use the printf-function for the usart.
Now I'm sending a character with this function - it works, but it's ver uncomfortable if I want to send one sentence or numbers...
char a[11] = "Hallo Welt"; for(int i=0; i<11; i++) { while( !(COM1->US_CSR & AT91C_US_TXRDY) ) continue; COM1->US_THR = (a[i] & 0xFF); }
Is there a possibility to use the printf-function for the first USART / not the DEBUG-Unit at the AT91?
printf("Hello World\n");
best regards Johannes
Hello Johannes Meier,
you have to enable Retargetting to use printf.
Adapt file RETARGET.c to your microcontroller and add it to your project. File RETARGET.C can be found in ..\Keil\ARM\Startup.
Best Regards, Martin Guenther
thanks for your answer...
could you show me a small example how I have to configurate this c-file for my controller?
just change the function that prints a single character on the UART with the one you already have and leave the other functions empty. A lot of the Keil examples use retargetting. Search the examples for the use of RETARGET.c
ok, that must be the function fputc...
struct __FILE { int handle; /* Add whatever you need here */ }; FILE __stdout; FILE __stdin; int fputc(int ch, FILE *f) { return (sendchar(ch)); }
But what about the lines FILE __stdout; and FILE __stdin;?
There are many name linkage conflicts with previous declaration of variable "std::__stdin" (declared in stdio.h)
FILE __stdout; (incomplete type is not allowed)
I take a look into one example from keil - but I don't see the differences between these two projects
my code in the retarget.c is
#include <stdio.h> //#include <time.h> #include <rt_misc.h> #pragma import(__use_no_semihosting_swi) extern int COM1_putchar(int ch); struct __FILE { int handle; /* Add whatever you need here */ }; FILE __stdout; FILE __stdin; int fputc(int ch, FILE *f) { volatile unsigned int i; while (COM1_putchar (ch) != 0) { for (i=0; i<1000; i++) { /*** DO NOTHING ***/ } } return (ch); }
it's the same as in the example from keil - only to test it.
you just have to change fputc, fgetc and _ttywrch. _ttywrch should be the same as fputc. Leave the rest as it is.
#include <stdio.h> //#include <time.h> #include <rt_misc.h> #pragma import(__use_no_semihosting_swi) extern int COM1_putchar(int ch); /* in Serial.c */ struct __FILE { int handle; /* Add whatever you need here */ }; FILE __stdout; FILE __stdin; int fputc(int ch, FILE *f) { volatile unsigned int i; while (COM1_putchar (ch) != 0) { for (i=0; i<1000; i++) { /*** DO NOTHING ***/ } } return (ch); } /* int fgetc(FILE *f) { return (sendchar(getkey())); } */ int ferror(FILE *f) { /* Your implementation of ferror */ return EOF; } void _ttywrch(int ch) { volatile unsigned int i; while (COM1_putchar (ch) != 0) { for (i=0; i<1000; i++) { /*** DO NOTHING ***/ } } } void _sys_exit(int return_code) { while (1); /* endless loop */ }
I get still the same errors...
I don't know what I'm doing wrong.
I work with the Realview Compiler and probably the compiler don't understand such defintions as FILE __stdout; (incomplete type is not allowed is the error message)...
And I get warnings, that std::__stdin and std::__stdout functions are declared in stdio.h
Could anybody tell me a solution for this problem?
Are there any other files I have to use with retarget.c??? Or are there any links, header-files - anything like that... there must be the error...
Johannes
Is there nobody who could help me?
Now I have only the startup file from Keil, a empty main-routine and a short retarget.c file - that's all...
#include <stdio.h> #include <rt_misc.h> #pragma import(__use_no_semihosting_swi) struct __FILE { int handle; /* Add whatever you need here */ }; FILE __stdout; FILE __stdin; void _sys_exit(int return_code) { label: goto label; /* endless loop */ }
error messages:
compiling Retarget.c... Retarget.c(19): warning: #2681-D: name linkage conflicts with previous declaration of variable "std::__stdout" (declared at line 87 of "D:\Keil\ARM\RV31\INC\stdio.h") Retarget.c(19): error: #70: incomplete type is not allowed Retarget.c(20): warning: #2681-D: name linkage conflicts with previous declaration of variable "std::__stdin" (declared at line 87 of "D:\Keil\ARM\RV31\INC\stdio.h") Retarget.c(20): error: #70: incomplete type is not allowed Retarget.c(23): error: #734: function "fputc(int, std::FILE *)" conflicts with using-declaration of function "std::fputc(int, std::FILE *) C" Retarget.c(47): error: #734: function "ferror(std::FILE *)" conflicts with using-declaration of function "std::ferror(std::FILE *) C" Retarget.c - 4 Error(s), 2 Warning(s).
please take a look at Project C:\Keil\ARM\Boards\Atmel\AT91SAM7S-EK\Hello. This example program uses UART with retargetting. It is not the microcontroller you are using but it is also an Atmel.
thanks for your reply, but there is no problem with the retarget.c file...
there must be another problem, because the retarget.c file from the AT91SAM7S-EK is identical with the retarget.c file I use.
I don't know where could be the error that FILE __stdout; is not allowed
Don\t you notice something strange.
You have posted what you claim is your Retarget.c file. It doesn't have many source lines. The compiler complains about line 19. Line 19 does not match your source file. Have you really posted a verbatim copy of Retarget.c?
right, at the beginning of the retarget.c file there are comments, I don't posted...
But the error message says which things are not correct... I created a complete new protect file and now it is working... I only copy the whole c-code in the new project file..
But it would be very interesting what the error was / or is.