Crossworks for ARM 2.1 - The missing __vfprintf(..)
I'm in the process of migrating an existing codebase from 1.7 to 2.1 (Crossworks for ARM), and ran across an issue I'm not sure how to handle.
This codebase is unique in that it implements multiple console instances and had previously used fprintf() to specify which console (or file) responses would be written to. We did this by rewriting fprintf using some low-level methods listed in the older compiler documentation: it used to be back in 1.7 that one could spin their own printf-esque routines via the __vfprintf() routine reminiscent of the following (courtesy of the Crossworks Documentation):
int uart0_printf(const char *fmt, ...)
{
int n;
va_list ap;
__printf_t iod;
va_start(ap, fmt);
iod.is_string = 0;
iod.maxchars = INT_MAX;
iod.u.output_fn = uart0_putc;
n = __vfprintf(&iod, fmt, ap);
va_end(ap);
return n;
}
Now in 2.1, the __printf_t structure as listed in "__vfprintf.h" has changed slightly (which is fine), but my linker cannot find the an object file: reporting this error.
> undefined reference to `vfprintf'
Arm 2.1 documentation from Rowley makes no mention on how to do this now: previously you could find this in the manual under the section heading "Extending I/O library functions".
My question is twofold:
1) is this method of extending printf() still possible?
2) If so, where is the object file for this?
FYI: The only packages installed is the "STMicroelectronics STM32 CPU Support Package".
Thanks!
- Craig Stickel
-
There isn't a __vfprintf symbol in the library any more. Each __vfprintf variant is now in the library and the build process uses linker symbol renaming to select the __vfprint variant to use. For example the symbol __vfprintf_double_long_long is the __vfprintf implementation that supports double and long long printing. As long as you have not disabled printf support then your example should work.
-
Managed to get it working through a different method, which I'll post here for future reference.
Ensure the following project settings:
- Linker Options->Allow Multiple Symbol Definitions = YES (if you want to rewrite printf - we did. Not sure it helped in this regard)
- Printf/Scanf Options->Printf Supported = YES
After which, create the following routine (note that in this project FILE * pointers are merely numeric indexes to consoles (0 = UART, 1=WIFI, 2=USB, etc)
int fprintf( FILE *file, const char *fmt, ... )
{
int n = 0;int iConsoleIndex = (int)file;
va_list ap;
__printf_t iod;
// Grab variable argument list
va_start(ap, fmt);
// Initialize the printf io descriptor
iod.charcount = 0;
iod.string = NULL;
iod.maxchars = INT_MAX;
// Print the text to the console
if( CONSOLE_IS_VALID(iConsoleIndex ) )
{
// Grab exclusive rights to this console
Console_Lock( iConsoleIndex );
// Specify the character insertion routine for this console
iod.output_fn = /* From some table of function pointers indexed by iConsoleIndex */;
// Print to the consoleif( iod.output_fn != NULL )
{
n = __vfprintf(&iod, fmt, ap);}
// Release the console
Console_Unlock( iConsoleIndex );
}
// Finish up
va_end(ap);
return n;
}Now all you need is your normal low-level insertion routines to populate in that printf_t instance, iod. For example:
int uart_putc( int ch )
{
// Add to UART TX buffer/queue
}
int debugfile_putc( int c )
{
// Append to file buffer
}
Hope somebody finds that useful.
-
Sorry for bringing up an old thread. I have a similar problem. If I build my project from within the Studio, the project is built without any error. If I use a batch file though with a command such as:
CROSSBUILD -config "THUMB Debug" -project "Main" -rebuild -echo Main.hzp
then I get this error: (you may skip to the end to see the error)
Linking Main.elf
.... a bunch of my files.... (in the following B:\ is the Crossworks directory)
THUMB Debug/misc.o THUMB Debug/stm32f4xx_adc.o THUMB Debug/stm32f4xx_can.o THUMB Debug/stm32f4xx_crc.o THUMB Debug/stm32f4xx_cryp.o THUMB Debug/stm32f4xx_cryp_aes.o THUMB Debug/stm32f4xx_cryp_des.o THUMB Debug/stm32f4xx_cryp_tdes.o THUMB Debug/stm32f4xx_dac.o THUMB Debug/stm32f4xx_dbgmcu.o THUMB Debug/stm32f4xx_dcmi.o THUMB Debug/stm32f4xx_dma.o THUMB Debug/stm32f4xx_exti.o THUMB Debug/stm32f4xx_flash.o THUMB Debug/stm32f4xx_fsmc.o THUMB Debug/stm32f4xx_gpio.o THUMB Debug/stm32f4xx_hash.o THUMB Debug/stm32f4xx_hash_md5.o THUMB Debug/stm32f4xx_hash_sha1.o THUMB Debug/stm32f4xx_i2c.o THUMB Debug/stm32f4xx_iwdg.o THUMB Debug/stm32f4xx_pwr.o THUMB Debug/stm32f4xx_rcc.o THUMB Debug/stm32f4xx_rng.o THUMB Debug/stm32f4xx_rtc.o THUMB Debug/stm32f4xx_sdio.o THUMB Debug/stm32f4xx_spi.o THUMB Debug/stm32f4xx_syscfg.o THUMB Debug/stm32f4xx_tim.o THUMB Debug/stm32f4xx_usart.o THUMB Debug/stm32f4xx_wwdg.o THUMB Debug/crc.o THUMB Debug/thumb_crt0.o THUMB Debug/STM32_Startup.o b:/lib/libm_v7em_t_le_eabi.a b:/lib/libc_v7em_t_le_eabi.a b:/lib/libcpp_v7em_t_le_eabi.a b:/lib/libdebugio_v7em_t_le_eabi.a b:/lib/libc_targetio_impl_v7em_t_le_eabi.a b:/lib/libc_user_libc_v7em_t_le_eabi.a --end-group
b:/lib/libc_v7em_t_le_eabi.a(libc2.o): In function `sprintf':
libc2.c:(.text.libc.sprintf+0x1e): undefined reference to `__vfprintf'
There were 1 build errorsAny idea on why there is a difference between these two approaches? Thank you in advance
-
Nchristoforou,
Did you find a solution to your problem? I'm currently having the same problem. It's like a bunch of the project settings aren't making it through to the linker because I also have to add the the standard libraries to the "Additional Input Files:" even though I configured the project to include them.
-
There are two places where one selects the "printf/scanf" option:
1) Project Properties -- go down to Printf/Scanf Options --- check the "Printf Supported" and "Scanf Supported". I think they are set to 'No' by default, because they have been set as in 2 below
2) In the IDE, go to Tools -- Options -- Building. Look to the 'Building Options". You will find 'Link In printf default' and 'Link In Scanf default'. They are most likely set to yes.
Now, if you set the 2 to no and the 1 to yes, you may be able to build your project.
Good luck
Please sign in to leave a comment.
Comments
6 comments