CoIDE, STM32F103 and Semihosting

I have been a little quiet lately as I have been working on a few projects. One of these are some experiments with the CooCox CoIDE and a STM32F103 dev board that I picked up off EBay a while back.

As a quick background, I have generated the bulk of the test project(s) with STM32CubeMX, and then modified what I needed. It should be noted that STM has updated the StdPeripheral library with a new HAL Library, which I decided to use. CoIDE has a neat feature called “semihosting” which allows you to shoot debug messages back to the IDE via the JTAG interface, freeing up the UART for your application-specific use.

The problem comes when adding semihosting. You need to add the “Retarget printf” component as well as the “Semihosting”. A quick implementation of PrintChar() in the semihosting code:

#include <semihosting/semihosting.h>
 
void PrintChar(char c)
{
  SH_SendChar(c);
}

If you try and compile this, you get the following error:

[cc] Starting link
[cc] arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -g -nostartfiles -Wl,-Map=cdctest.map -O0 -Wl,--gc-sections -LC:\CooCox\CoIDE\configuration\ProgramData\cdctest -Wl,-TC:\CooCox\CoIDE\configuration\ProgramData\cdctest/arm-gcc-link.ld -g -o cdctest.elf ..\obj\stm32f1xx_hal_rcc_ex.o ..\obj\semihosting.o ..\obj\stm32f1xx_hal_pwr.o ..\obj\stm32f1xx_hal_can.o ..\obj\stm32f1xx_hal.o ..\obj\stm32f1xx_it.o ..\obj\stm32f1xx_hal_dac.o ..\obj\stm32f1xx_hal_gpio_ex.o ..\obj\stm32f1xx_hal_wwdg.o ..\obj\stm32f1xx_hal_cortex.o ..\obj\stm32f1xx_hal_crc.o ..\obj\stm32f1xx_hal_iwdg.o ..\obj\system_stm32f1xx.o ..\obj\stm32f1xx_hal_rcc.o ..\obj\stm32f1xx_hal_dac_ex.o ..\obj\stm32f1xx_hal_adc.o ..\obj\stm32f1xx_hal_i2s.o ..\obj\stm32f1xx_hal_smartcard.o ..\obj\stm32f1xx_hal_pcd.o ..\obj\stm32f1xx_hal_uart.o ..\obj\usbd_core.o ..\obj\main.o ..\obj\startup_stm32f103xb.o ..\obj\stm32f1xx_hal_usart.o ..\obj\stm32f1xx_hal_nor.o ..\obj\stm32f1xx_ll_usb.o ..\obj\printf.o ..\obj\stm32f1xx_hal_spi_ex.o ..\obj\stm32f1xx_hal_cec.o ..\obj\stm32f1xx_hal_hcd.o ..\obj\stm32f1xx_hal_flash.o ..\obj\stm32f1xx_hal_gpio.o ..\obj\stm32f1xx_hal_dma.o ..\obj\usbd_desc.o ..\obj\usbd_conf.o ..\obj\stm32f1xx_hal_adc_ex.o ..\obj\stm32f1xx_hal_irda.o ..\obj\stm32f1xx_hal_sd.o ..\obj\sh_cmd.o ..\obj\stm32f1xx_hal_spi.o ..\obj\syscalls.o ..\obj\stm32f1xx_hal_i2c.o ..\obj\stm32f1xx_hal_msp.o ..\obj\usb_ctrl.o ..\obj\stm32f1xx_hal_eth.o ..\obj\stm32f1xx_ll_fsmc.o ..\obj\usbd_cdc.o ..\obj\stm32f1xx_hal_rtc.o ..\obj\stm32f1xx_hal_tim.o ..\obj\stm32f1xx_hal_flash_ex.o ..\obj\usbd_ctlreq.o ..\obj\stm32f1xx_hal_pcd_ex.o ..\obj\usbd_cdc_if.o ..\obj\stm32f1xx_hal_nand.o ..\obj\usbd_ioreq.o ..\obj\stm32f1xx_hal_pccard.o ..\obj\stm32f1xx_hal_sram.o ..\obj\usb_device.o ..\obj\stm32f1xx_hal_rtc_ex.o ..\obj\stm32f1xx_hal_tim_ex.o ..\obj\stm32f1xx_ll_sdmmc.o -lm -lgcc -lc
[cc] c:/program files (x86)/gnu tools arm embedded/5.3 2016q1/bin/../lib/gcc/arm-none-eabi/5.3.1/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-impure.o):(.data._impure_ptr+0x0): multiple definition of `_impure_ptr'
[cc] ..\obj\printf.o:(.data+0x428): first defined here
[cc] collect2.exe: error: ld returned 1 exit status

It turns out that after a lot of googling, pulling out of hair and cursing, the answer is rather simple. It seems that the struct “r” and “_impure_ptr” are being redefined in printf.c; so we just need to comment them out from the printf.c file in our project:

#include <semihosting/semihosting.h>
 
void PrintChar(char c)
{
	SH_SendChar(c);
}
 
/** Required for proper compilation. */
//struct _reent r = {0, (FILE *) 0, (FILE *) 1, (FILE *) 0};
//struct _reent *_impure_ptr = &r;
 
...

Rebuild and problem solved.