Hi,
I have one question about Cortexm3 from smartfusion device from actel. Could you pls help me? I add follwing codes into retarget.c and then add retarget.c into source code group and find : printf function works.however scanf function doesn't. anybody knows why?
int fputc(int ch, FILE *f) { return ((int)ITM_SendChar(ch)); } int fgetc(FILE *f) { int i=0; i=ITM_ReceiveChar(); if((-1)!=i) return ((int)ITM_SendChar((uint32_t)i)); else return (0); }
printf("hello world\n\r"); // when executed, string displayed in debug(printf)window scanf("%s",str); // when executed, hard fault occurs
Hello Fisher Cheng,
µVision provides for a CM3/CM4 debug support via ITM (Instrumented Trace Macrocell). In a debug session the Debug (printf) Viewer window is used to display the debug data.
Direction: Microcontroller -> µVision: * Characters received via ITM communication channel 0 are written in a printf style to Debug (printf) Viewer window.
Direction: µVision -> Microcontroller: * variable ITM_RxBuffer is used for data transfer. * Check if ITM_RxBuffer variable is available (only performed once). * Read character from Debug (printf) Viewer window. * If ITM_RxBuffer empty write character to ITM_RxBuffer.
Note: Current solution does not use a buffer mechanism for transmitting the characters.
For my tests (only simulation) I used following code in retarget.c
#include <stdio.h> #include <rt_misc.h> #include "a2fxxxm3.h" #pragma import(__use_no_semihosting_swi) volatile int ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* used for Debug Input */ struct __FILE { int handle; }; FILE __stdout; FILE __stdin; int fputc(int ch, FILE *f) { return (ITM_SendChar(ch)); } int fgetc(FILE *f) { /* blocking */ while (ITM_CheckChar() != 1); return (ITM_ReceiveChar()); } int ferror(FILE *f) { /* Your implementation of ferror */ return EOF; } void _ttywrch(int ch) { ITM_SendChar(ch); } void _sys_exit(int return_code) { label: goto label; /* endless loop */ }
Do not use MicroLib if you are using scanf(..)
Best Regards, Martin Günther
Hello Martin Günther,
Thank you very much for your help. I add your retarget.c into my project and use following codes:
volatile unsigned char str='\0'; main() { for (;;) { scanf("%s\n",&str); ITM_SendChar(str); } }
I connect A2F dev kit to PC using ulink2 first. when the program runs in flash target, I place mouse in debug(pringf) windows and then click the key "p" in the keyboard and find :
(1) no character displayed in debug(pringf) windows (2) when I open memory window 1 and try to observe it using &str commander, I still find that the data is always 0
it seems that no character from Debug (printf) Viewer window is read to ITM_RxBuffer.
Could you please post your test codes here? can scanf() be used in simulation mode only? thanks a lot.
Fisher Cheng
So all do ever do is to get a single string for each input line? Why then don't you use the gets() function, that (in Keils edition) takes a parameter specifying the size of your buffer?
But the worst problem - str is expected to be a string. But your declaration is a character. Taking the address of the character and send into sprintf() means that sprintf() only have a valid if it is expected to retrieve a zero-length string (i.e. a string only storing the termination character).
You must definitely need to make:
enum { BUF_SIZE = 64, }; char str[BUF_SIZE];
Now you have a buffer that can fit 0 to 63 characters + a termination.
And with gets() you can send BUF_SIZE as parameter, making sure that gets() does never allow you to overflow the buffer.
View all questions in Keil forum