- Have printf working in other programs using serial.c/h and redirect_io.c. - Using a Segger JLink - Keil MCBSTM32F200 - RTX Blinky example - Added STDOUT redirect using the RTE
If I enable trace with bit 31, my program will never start the RTOS and get hung here:
#ifdef DBG_MSG void dbg_task_notify (P_TCB p_tcb, BOOL create) { while (ITM_PORT31_U32 == 0); ITM_PORT31_U32 = (U32)p_tcb->ptask; while (ITM_PORT31_U32 == 0); ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; } #endif
If I disable bit31, the Keil RTX tracing the OS / the System and Thread Viewer tab works, but maybe that's something else because the Performance Analyzer tab does not seem to work, it's 0us on all values... If I try and use printf() I get hung here:
uint32_t ITM_SendChar (uint32_t ch) { if ((ITM_TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ (ITM_TER & (1UL << 0) )) { /* ITM Port #0 enabled */ while (ITM_PORT0_U32 == 0); ITM_PORT0_U8 = (uint8_t)ch; } return (ch); }
Until I disable the bit0 checkbox in the trace tab. Then the program runs well again, the printf() command "does" nothing though. I can't ever seem to get a message to show up in the serial window.
Does anyone have any thoughts? I'm really not sure where I'm supposed to learn how to initialize the RTX for this or Trace Settings, etc.
Sorry, that formatting is terrible
Hangs with trace / ITM stimulus port bit31 enabled:
Hangs with trace / ITM stimulus port bit0 enabled:
Ugh... Nevermind, solved it myself. A ton of googling later to discover this is a Segger issue, sort of. I suspect other tools set the proper settings automagically but Segger and Keil treat you like a big boy... or just assumes you know things you could not possibly - either one.
SWO needs to be explicitly enabled. So, you need to follow this obscure page: www.keil.com/.../jLink_STM32F10xxx_SWT.htm
But for my part, the STM32F20x, setting the DBGMCU_CR to 0xE0 was incorrect and did enable printf() but did not enable Event Viewer. Using 0x27 works for me.
Note: Performance Analyzer only works in Simulation or ETM. Does not work with SWO / ITM.
/*------------------------------------------------------------------- ** Define the function to enable the trace port **-----------------------------------------------------------------*/ FUNC void EnableTPIU(void) { _WDWORD(0xE0042004, 0x00000027); // Set 4-pin tracing via DBGMCU_CR //Might be 0xE0-E7 for the STM32F1x, check reference and your setup //Careful, DBGMCU_CR value remains after reset } /*------------------------------------------------------------------- ** Invoke the function at debugger startup **-----------------------------------------------------------------*/ EnableTPIU();
So I have in this above, RTE added the IO redirects for STDOUT/printf. All boxes checked in the ITM Stimulus field.
I'm only sorry I put RTX in the title, this is really a printf doesn't work with Segger JLink out of the box, or SWO Enable for Segger issue. But whatever. Hope someone who needs this finds it someday.
Hi, after found my self in similar problem, i make this debug script, perhaps someone found it useful. regards
//use only with stm32f4 microcontrollers DEFINE INT TEMP; DEFINE INT DbgMCU_CR; DEFINE INT DbgMCU_CR_ADDRESS; DbgMCU_CR_ADDRESS = 0xE0042004; DEFINE INT DbgMCU_APB1_Fz; DEFINE INT DbgMCU_APB1_Fz_ADDRESS; DbgMCU_APB1_Fz_ADDRESS = 0xE0042008; DEFINE INT DbgMCU_APB2_Fz; DEFINE INT DbgMCU_APB2_Fz_ADDRESS; DbgMCU_APB2_Fz_ADDRESS = 0xE004200C; // <<< Use Configuration Wizard in Context Menu >>> // <h>Debug MCU Configuration // <o.0> DBG_SLEEP Debug Sleep Mode // <o.1> DBG_STOP Debug Stop Mode // <o.2> DBG_STANDBY Debug Standby Mode // <e> Trace I/O Enable // <o.5> TRACE_IOEN Trace I/O Enable // <o.6..7> TRACE_MODE Trace Mode // <0=> Asynchronous // <1=> Synchronous: TRACEDATA Size 1 // <2=> Synchronous: TRACEDATA Size 2 // <3=> Synchronous: TRACEDATA Size 4 // </e> // </h> DbgMCU_CR = 0x00000000; TEMP = _RWORD(DbgMCU_CR_ADDRESS); _WWORD (DbgMCU_CR_ADDRESS, TEMP|DbgMCU_CR); // <h> Debug MCU APB1 Freeze // <o.0> DBG_TIM2_STOP Timer 2 Stopped when Core is halted // <o.1> DBG_TIM3_STOP Timer 3 Stopped when Core is halted // <o.2> DBG_TIM4_STOP Timer 4 Stopped when Core is halted // <o.3> DBG_TIM5_STOP Timer 5 Stopped when Core is halted // <o.4> DBG_TIM6_STOP Timer 6 Stopped when Core is halted // <o.5> DBG_TIM7_STOP Timer 7 Stopped when Core is halted // <o.6> DBG_TIM12_STOP Timer 12 Stopped when Core is halted // <o.7> DBG_TIM13_STOP Timer 13 Stopped when Core is halted // <o.8> DBG_TIM14_STOP Timer 14 Stopped when Core is halted // <o.10> DBG_RTC_STOP RTC Stopped when Core is halted // <o.11> DBG_WWDG_STOP Window Watchdog Stopped when Core is halted // <o.12> DBG_IWDG_STOP Independent Watchdog Stopped when Core is halted // <o.21> DBG_I2C1_SMBUS_TIMEOUT I2C1 SMBUS Timeout Mode Stopped when Core is halted // <o.22> DBG_I2C2_SMBUS_TIMEOUT I2C2 SMBUS Timeout Mode Stopped when Core is halted // <o.23> DBG_I2C3_SMBUS_TIMEOUT I2C3 SMBUS Timeout Mode Stopped when Core is halted // <o.25> DBG_CAN1_STOP CAN1 Stopped when Core is halted // <o.26> DBG_CAN2_STOP CAN2 Stopped when Core is halted // </h> DbgMCU_APB1_Fz = 0x6E01DFF; _WWORD (DbgMCU_APB1_Fz_ADDRESS, DbgMCU_APB1_Fz); // <h> Debug MCU APB2 Freeze // <o.0> DBG_TIM1_STOP Timer 1 Stopped when Core is halted // <o.1> DBG_TIM8_STOP Timer 8 Stopped when Core is halted // <o.16> DBG_TIM9_STOP Timer 9 Stopped when Core is halted // <o.17> DBG_TIM10_STOP Timer 10 Stopped when Core is halted // <o.18> DBG_TIM11_STOP Timer 11 Stopped when Core is halted // </h> DbgMCU_APB2_Fz = 0x70003; _WWORD (DbgMCU_APB2_Fz_ADDRESS, DbgMCU_APB2_Fz); // <<< end of configuration section >>>