cancel
Showing results for 
Search instead for 
Did you mean: 

Retargeting scanf

johan239955_st
Associate II
Posted on January 15, 2009 at 09:47

Retargeting scanf

6 REPLIES 6
johan239955_st
Associate II
Posted on May 17, 2011 at 12:59

I´m trying to retarget scanf by writing my own fgetc, but I'm having some trouble. The scanf misses the first character in each integer ''sent'' to it. The implementation is the following:

// Just a dummy implementation for debug

int fgetc(FILE *f)

{

static int cnt = 0;

int ch;

static char str[20] = ''874 543 -345\0\0\0\0'';

ch = (int) str[cnt];

cnt = (cnt + 1) % 13;

return ch;

}

main()

{

int a,b,c;

scanf(''%d%d%d'', &a, &b, &c);

}

When running the code, the result is: a=74, b=73, c=345.

If I instead call sscanf(...), the result becomes correct. Any ideas?

[ This message was edited by: johan.stridkvist on 15-01-2009 14:37 ]

dmatheis2
Associate II
Posted on September 23, 2011 at 09:26

Hi Johan,

did you solve this issue? I think I have the same problem with my scanf redirection. The first character or digit sent via a terminal program (hyperterminal or putty) is lost. I am using the IAR Workbench (Kickstart) with a Olimex STM32-P103 Board and the ST-Link v2.

bassinux2
Associate
Posted on September 23, 2011 at 10:46

Hi all,

I use the following scanf retarget and It works fine with IAR :

int fgetc(FILE *f)

{

  u16 uiTemp;

 

  /* Loop until the end of reception */

  while(!(DISPLAY_USARTx->SR & USART_SR_RXNE));

  /* Read a character from the USART */

  uiTemp = (u16)(DISPLAY_USARTx->DR & (u16)0x01FF);

 

  return uiTemp;

}

void main(void)

{

  u8     uiTemp;

  printf(''Press 'C' to Continue... :'');

  scanf(''%c'',&uiTemp);

  while((uiTemp != 'c') && (uiTemp != 'C'))

  {

    scanf(''%c'',&uiTemp);

  }

  printf(''\r\n'');

}

dmatheis2
Associate II
Posted on September 23, 2011 at 11:53

Hmm. That is mostly the same way as I implemented it. Are there any configuration changes in the Compiler/Debugger section to edit or any special library includes? Now I've read something about differences between CLib and DLib. DLib uses different routines for printf/scanf (__write and __read). For your information: I am using Workbench version 6.21 with the integrated CMSIS and standard peripheral library version 3.5.0

Here are my versions of fputc and fgetc:

int fputc(int iChar, FILE *f)

{

  if(boUSARTen == true)

  {

   

    USART2->DR = (iChar & ((uint16_t)0x01FF));

    while((USART2->SR & USART_FLAG_TC) == RESET); /* wait until byte is send */

    return iChar;

  }

  else

  {

    return -1;

  }

}

int fgetc(FILE *f)

{

  if(boUSARTen == true)

  {

    while(((USART2->SR) & USART_FLAG_RXNE) == RESET);/* wait until data arrived */

    return (USART2->DR & (uint16_t)0x01FF);          /* return data byte */

  }

  else

  {

    return -1;

  }

}

Thanks a lot for your help!

bassinux2
Associate
Posted on September 23, 2011 at 15:03

Hi Dominik,

could you check the following points :

1) In IAR project general options->Library Options : you should have printf formatter : full and Scanf formatter : full.

 2) Is it possible to remove the test ''  if(boUSARTen == true)'' and make the function as simple as possible and try it

3) Change the USART baudrate (for example try a communication with 9600)

Best regards

Bassem

 

dmatheis2
Associate II
Posted on October 11, 2011 at 11:07

Hi Bassem,

I think i have a solution. Iar Workbench 6.21 is using the DLib C-Libraries. In this version you'll have to overwrite the routines __read and __write instead of putchar and getachr!

There are two different sets of runtime libraries provided:

�? The IAR DLIB Library, which supports ISO/ANSI C and C++. This library also

supports floating-point numbers in IEEE 754 format and it can be configured to

include different levels of support for locale, file descriptors, multibytes, et cetera.

�? The IAR CLIB Library is a light-weight library, which is not fully compliant with

ISO/ANSI C. Neither does it fully support floating-point numbers in IEEE 754

format or does it support Embedded C++. (This library is used by default).

Migration from CLIB to DLIB

There are some considerations to have in mind if you want to migrate from the CLIB

library, the legacy C library, to the modern DLIB C/C++ library:

�? The CLIB exp10() function defined in iccext.h is not available in DLIB.

�? The DLIB library uses the low-level I/O routines __write and __read instead of

 

putchar and getchar.

�? If the heap size in your old compiler version using CLIB was defined in a file

named heap.c, you must now set the heap size either in the extended linker

command file (*.xcl) or in the Embedded Workbench to use the DLIB library.

Source: http://supp.iar.com/FilesPublic/UPDINFO/004350/EWM32C_CompilerReferenceAddendum.pdf

 

The compiler comes with the IAR DLIB Library, a complete library, compliant with

Standard C and C++. This library also supports floating-point numbers in IEEE 754

format and it can be configured to include different levels of support for locale, file

descriptors, multibyte characters, et cetera.

Source: http://supp.iar.com/FilesPublic/UPDINFO/005832/arm/doc/EWARM_DevelopmentGuide.ENU.pdf

Regards Dominik