cancel
Showing results for 
Search instead for 
Did you mean: 

Semihosting in Eclipse or retargeting printf

a239955_stm1
Associate II
Posted on June 03, 2014 at 09:43

Hi,

I am trying to debug some very simple code for STM32F0Discovery using Eclipse, 

ARM arm-none-eabi-gdb compiler and OpenOCD debuger.

I could build and debug my cods and now I am trying to use printf to see some variables on the screen. CoIDE has this nice semihosting which without using USART, sends printf output on the screen. I tried to use the semihosting library files with eclips to do the same. I could enable  semihosting in Eclipse but nothing showed up on the screen! I guess the problem was SH_DoCommand

http://techwithdave.blogspot.ca/2013/04/hello-world-tutorial-for-stm-discovery.html

Then I tried to use USART_Printf example from STM32F0xx_StdPeriph_Examples.

I got errors regarding _read and _write and so many errors like that. I tried to fix the errors by adding newlib_stubs.c as in 

https://sites.google.com/site/stm32discovery/open-source-development-with-the-stm32-discovery/getting-newlib-to-work-with-stm32-and-code-sourcery-lite-eabi

After small changes in the code I couldn't debug the code!

I have also tried to add 

--specs=rdimon.specs   -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group

flags to the linker but still nothing on the screen!

Any Idea?

Thanks

Ali

#stm32f0 #printf #discovery
11 REPLIES 11
Posted on June 03, 2014 at 13:00

Can you initialize and output data to the USART directly in these circumstances? Serial access normally means via a cable and terminal application.

The Cortex-M3/4 also have a Serial Wire Viewer (SWV) mode which is a debugger communications channel, which also must be enabled, and be set to the clock rate of the core. The ST-Link Utilities has a SWV screen built into it. Some of the DISCO boards will require an Solder Bridge (SB) be made to connect the SWO PB3 pin to the debugger.

I've use USART and SWV methods with GNU/GCC, with hosting via the newlib stubs.

The Cortex-M0 does not provide for the SWV method, so you'll probably want to concentrate on showing the USART is initialized and functioning, and that your terminal settings and connection are right.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
a239955_stm1
Associate II
Posted on June 03, 2014 at 18:34

Following the other discussion in here (UART example code for STM32F0) and using you sample code, I can initialize and compile/debug USART and see the string on the terminal. 

Now I am trying to get ''printf'' to work with STM32F0 Discovery. I was wondering If you have tried that or have any suggestion.

  

Thanks

a239955_stm1
Associate II
Posted on June 03, 2014 at 19:59

I found this amazing book ''Discoverying the STM32 Microcontrollr'' by Dr. Geoffrey Brown

 that provides systemcall functions for STM32. Using his code the ''undefined reference to stackend'' is the only error that I get. 

In chapter 15, page 211, it is stated that we need to define _end and  stackend in the linker script. I don't know how to get those numbers and how to add them to the linker script. 

Posted on June 03, 2014 at 21:06

This is my

https://drive.google.com/file/d/0B7OY5pub_GfIcnFFUGJRT3ZTV00/edit?usp=sharing

, it would not take much effort to port it to an STM32F0 implementation. Copy over the newlib_stubs.c, and modify the USART routines from main.c

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
a239955_stm1
Associate II
Posted on June 03, 2014 at 21:09

Progress report:

I managed to define _stackend as:

caddr_t _stackend = 0x20001FFF;

and I could compile the code. Bug I cannot debug it yet!

When I start the debugger I receive these messages from debugger:

Open On-Chip Debugger 0.6.1 (2012-10-07-10:34)

Licensed under GNU GPL v2

For bug reports, read

http://openocd.sourceforge.net/doc/doxygen/bugs.html

adapter speed: 1000 kHz

srst_only separate srst_nogate srst_open_drain

Info : clock speed 1000 kHz

Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints

Info : accepting 'gdb' connection from 3333

Info : device id = 0x20006440

Info : flash size = 64kbytes

Warn : acknowledgment received, but no packet pending

undefined debug reason 6 - target needs reset

Warn : target was in unknown state when halt was requested

Error: Invalid command argument

halt [milliseconds]

reset [run|halt|init]

soft_reset_halt   stm32f0x.cpu arp_halt

  stm32f0x.cpu arp_halt_gdb

wait_halt [milliseconds]

in procedure 'halt'

Error: Target not halted

Error: failed erasing sectors 0 to 13

Error: flash_erase returned -304

Here is the code I am running:

#include ''main.h''

#include ''stm32f0_discovery.h''

#include <stdio.h>

//**************************************************************************************

int main(void)

{

  USART_InitTypeDef USART_InitStructure;

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

  /* Configure USART1 pins:  Rx and Tx ----------------------------*/

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 9600;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART1, &USART_InitStructure);

  USART_Cmd(USART1,ENABLE);

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

  while (1)

  {

  }

}

//**************************************************************************************

void Usart1Put(uint8_t ch)

{

      USART_SendData(USART1, (uint8_t) ch);

      //Loop until the end of transmission

      while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)

      {

      }

}

uint8_t Usart1Get(void){

     while ( USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

        return (uint8_t)USART_ReceiveData(USART1);

}

//**************************************************************************************

#ifdef  USE_FULL_ASSERT

/**

  * @brief  Reports the name of the source file and the source line number

  *         where the assert_param error has occurred.

  * @param  file: pointer to the source file name

  * @param  line: assert_param error line source number

  * @retval None

  */

void assert_failed(uint8_t* file, uint32_t line)

{

  /* User can add his own implementation to report the file name and line number,

     ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */

  /* Infinite loop */

  while (1)

  {

  }

}

#endif

and here is the systemcalls.S contents:

#include <errno.h>

#include <sys/stat.h>

#include <sys/times.h>

#include <sys/unistd.h>

#include ''stm32f0_discovery.h''

#include ''main.h''

//#define S_IFCHR  0x0020000

extern caddr_t _end;

caddr_t _stackend = 0x20001FFF;

caddr_t _sbrk(int nbytes){

static caddr_t heap_ptr = NULL;

caddr_t base;

if (heap_ptr == NULL) {

heap_ptr = (caddr_t)&_end;

}

if ((caddr_t) &_stackend > heap_ptr + nbytes) {

base = heap_ptr;

heap_ptr += nbytes;

return (base);

} else {

errno = ENOMEM;

return ((caddr_t)-1);

}

}

int _close(int file) {

errno = ENOTSUP;

return -1;

}

int _fstat(int file, struct stat *st) {

st->st_mode = S_IFCHR; // character device

return 0;

}

int _isatty(int file) {

return 1;

}

int _link(char *old, char *new) {

errno = EMLINK;

return -1;

}

int _lseek(int file, int ptr, int dir) {

errno = ENOTSUP;

return -1;

}

int _open(const char *name, int flags , int mode) {

errno = ENOTSUP;

return -1;

}

int _read(int file, char *ptr, int len) {

if (len){

*ptr = (char) Usart1Get();

return 1;

}

return 0;

}

int _unlink(char *name) {

errno = ENOENT;

return -1;

}

int _write(int file, char *ptr, int len) {

if (len) {

Usart1Put(*ptr);

return 1;

}

return 0;

}

I appreciate any help.

a239955_stm1
Associate II
Posted on June 03, 2014 at 23:08

Thanks for sharing the project. I used the newlib_stubs.c file and modified the USART functions as you suggested. I could compile the code with no error. I downloaded the code on the target board and it worked just fine.

When I start OpenOCD, however, I receive this [No source available for ''''] message on debug window and it shows  

thread[1]  suspended and   

  2 <symbol is not available> 0x00000000

  1 <symbol is not available> 0x00000000

and disassembly window shows ''strdcs r1, [r0], -pc    ; <UNPREDICTABLE> ''

When I put an breakpoint and run the code, this information appears infront of thread[1]: (suspended, signal SIGINT received: Description interrupt)

then in console window these messages appear:

Info : accepting 'gdb' connection from 3333

Info : device id = 0x20006440

Info : flash size = 64kbytes

Warn : acknowledgment received, but no packet pending

undefined debug reason 6 - target needs reset

Warn : target was in unknown state when halt was requested

Error: Invalid command argument

halt [milliseconds]

reset [run|halt|init]

soft_reset_halt   stm32f0x.cpu arp_halt

  stm32f0x.cpu arp_halt_gdb

wait_halt [milliseconds]

in procedure 'halt'

Error: Target not halted

Error: failed erasing sectors 0 to 35

Error: flash_erase returned -304

Warn : The target is not in the halted nor running stated, stepi/continue ignored.

Warn : target not halted 

I really appreciate your help.

leos
Associate
Posted on November 12, 2014 at 21:23

In case you have not solved this yet: it is necessary to select ''Semihosting DEBUG channel'' as the Trace Output when a new project is being created. trace_printf does not print anything otherwise.

Posted on November 12, 2014 at 21:37

In case you have not solved this yet: it is necessary to select ''Semihosting DEBUG channel'' as the Trace Output when a new project is being created. trace_printf does not print anything otherwise.

No one even mentioned ''trace_printf'', so I'm not sure what problem this solves and on what platform.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
yakovdk
Associate II
Posted on February 03, 2015 at 06:22

Maybe nobody mentioned it, but this turned up as an answer to my question about why I didn't see printf output using the GNU ARM Eclipse blinking LED example, and it was indeed the need to choose ''Semihosting DEBUG channel''.