STM32L152 EVAL Board Port: Example 1 - Scheduler Failure

paulromero wrote on Friday, July 11, 2014:

Dear Forum:

I am experiencing problems with the FreeRTOS port for
the STM32L152 Eval. board and I am not sure if it is
correct. The environment is as follows:

Board: ST32L152-EVAL
Processor: STM32L152VB
FreeRTOS Version: 8.0.1
Toolchain: Rowley Crossworks for ARM

The “FreeRTOS Blinkly” example for the STM32L Discovery Board works but
“Example 1” for the Cortex M3 does not. I created the execution
environment by cloning the environment from the Blinky example
as much as possible. The problem is that when the example is
executed only Task1 runs–indicating the scheduler is not
working correctly.

The modification to the Blinky environment are as follows.

  • Simple main.c (Example 1) and basic_io.h (Cortex M3 Version)

PATH/CrossWorks for ARM/v3/packages/samples/FreeRTOS$

Stellaris features are disabled in main.c.

  • basic_io.c with minor modification (Cortex M3 Version)

Replaced printf() with debug_printf()

  • Default FreeRTOSConfig.h

PATH/CrossWorks for ARM/v3/packages/targets/ST_STM32L152C_DISCOVERY$

Best Regards,

Paul R.

paulromero wrote on Friday, July 11, 2014:

Here are the relevant files.

rtel wrote on Friday, July 11, 2014:

Can you describe how you know only one task is running - are you getting any print outs at all, and if so, what is the pattern of the output. What happens if you replace the calls to print output with simple variable increments - with both tasks using a different variable. Do both variables indicate (showing that both tasks run if debug_printf() is not called)?

Which project did you base your working blinky example on? I don’t think there is a Rowley project for the STM32L152 in the download. Does the project have any additional hardware setup that is required before you create the tasks and start the scheduler (I note you commented out the Stellaris specific hardware line).


paulromero wrote on Saturday, July 12, 2014:

There are two ways I know Task1 is the only one running.
First, it is the only task that prints anything. Second,
if you put a breakpoint, just before the vPrintString()
call, in Task1 and Task2 and disable the debug_printf()
in basic_io.c, only the breakpoint in Task1 is ever
reached. Similarly, if you put a global execution
counter in both Task1 and Task2, and stop
execution only the counter in Task1 is updated.

The Blinky example came as port of sample projects
delivered by Rowley. The Blinky project does not
appear to require special hardware setup.

The Blinky example is very short and the relevant files,
main.c and main_blinky.c are attached. As you will notice,
there is no special hardware initialization.

rtel wrote on Saturday, July 12, 2014:

What about the interrupt vector table? How is the Rowley project installing the FreeRTOS handlers on the SysTick, PendSV and SVCall vectors? This can be done in [at least] one of two ways - either the names of the FreeRTOS handlers can be installed directly, or if the vector table is using CMSIS handler names then the FreeRTOS handlers can be mapped onto their CMSIS equivalents as described in bullet number 1 on the following page:


paulromero wrote on Tuesday, July 15, 2014:

ST sent intialization code which fails during clock initialiazation.
The file with the board initialization code is attached to this note.
The point of failure is as follows:

void SystemInit()
// ********* Comment: BUG - RCC_CR_HSERDY is never set ! ************
while ((RCC->CR & RCC_CR_HSERDY)==0);


davedoors wrote on Tuesday, July 15, 2014:

Sent code where? To you or to Richard (FreeRTOS)? Is your problem fixed now?

Are you certain this is a bug? Sometimes clocks can fail to lock if there is a power rail problem. Presumably you are running this on real hardware not a simulator, how is the hardware powered?

paulromero wrote on Tuesday, July 15, 2014:

The board is powered via USB and it is real hardware.
ST sent the code to me.

paulromero wrote on Tuesday, July 15, 2014:

Afterthought: If Richard would like, I can send him
the package.

paulromero wrote on Tuesday, July 15, 2014:

Correction: The package came from Rowley rather than ST !

paulromero wrote on Tuesday, July 15, 2014:

Crossworks suggested trying an external DC power supply.
I tried it and it made no difference. I don’t think lack
of power from the USB port is a problem because this is a very
low power device and the Discovery version of Blinky runs
on the board.

paulromero wrote on Tuesday, July 15, 2014:

Below is a partially commented list of the differences between
the STM32L152-EVAL and STM32L-Discovery board initialization
code. The first obvious difference is the user of the
internal clock on the Discovery board versus the external
clock on the STM32L152-EVAL board. Search for the word
“Comment” for further differences. (i.e. Only the code
related to clock configuration has detailed comments.)

Is it possible the use of the external clock is the problem ?

**************** KEY *************

< Means STM32L152-Eval Board with

Means the STM32L-Discovery board

Both cases STM32L152VB Processor

Comment: Pin Names.


RCC_CR Register External Clock

< while ((RCC->CR & RCC_CR_HSERDY)==0);

RCC_CR Register Internal Clock

while ((RCC->CR & RCC_CR_HSIRDY)==0);

Comment: Exact clock configuration.

PLL: Entry Clock Source, MUL12 Configruation, Clock Output = CKVCO 3


PLL: MUL 4 Configuration, Clock Ouput = CKVCO 2

< SystemCoreClock = 32000000; // 32 Mhz

SystemCoreClock = 32000000; // 32 Mhz
< //STM32L152-EVAL LD1 led connected to port D pin 0, Key push-button is connected to port C pin 13 (EXTI 13).

//STM32L-DISCOVERY LD3 led connected to port B pin 7, User push-button is connected to port A pin 0 (EXTI 0).

Comment: GPI Setup - TBD: Investigate

< // Turn on GPIOD, GPIOC
< // Set PD_0 to output

// Turn on GPIOA, GPIOB
// Set PB_7 to output
< // Associate PC_13_PIN to EXTINT13 - interrupt on a falling edge
< EXTI->FTSR |= 1 << 13; // falling edge trigger
< EXTI->IMR |= 1 << 13; // enable interrupt

// Associate PA_0_PIN to EXTINT0 - interrupt on a falling edge
EXTI->FTSR |= 1 << 0; // falling edge trigger
EXTI->IMR |= 1 << 0; // enable interrupt
< GPIOD->BSRRL = (1<<0);

GPIOB->BSRRL = (1<<7);

< GPIOD->BSRRH = (1<<0);

GPIOB->BSRRH = (1<<7);


Comment: Interrupt Configuration.

< EXTI15_10_IRQHandler(void)

< if (EXTI->PR & (1<<13))

if (EXTI->PR & (1<<0))
< EXTI->PR = (1<<13);

  EXTI->PR = (1<<0);

< ctl_set_priority(EXTI15_10_IRQn, ctl_adjust_isr_priority(ctl_highest_isr_priority(), -1));
< ctl_unmask_isr(EXTI15_10_IRQn);

ctl_set_priority(EXTI0_IRQn, ctl_adjust_isr_priority(ctl_highest_isr_priority(), -1));

paulromero wrote on Tuesday, July 15, 2014:

The Blinky example of the ST32L152_EVAL version of FreeRTOS works
is you use an internal clock as in the Discovery version.
This can be done by making the following minimal changes to
the STM32_ctl_board.c SystemInit() routine. However, this is
just an experiment and probably isn’t completely correct.

  1. Replace the following code segment.

while ((RCC->CR & RCC_CR_HSERDY)==0);

With the following code segment.

while ((RCC->CR & RCC_CR_HSIRDY)==0);

  1. Replace the following line


With the following line of code.


However, basic FreeRTOS Example1 still does not execute correctly.
In particular only Task1 is started–indicating the scheduler is
not working correctly.

paulromero wrote on Wednesday, July 16, 2014:

It looks like the interrurpt handler names are being
mapped to the CMSIS equivanlents. For example
vPortSvcHandler() is mapped to SVC_Handler().
I would assume this means SVC_HAndler() should
be plugged into the interrupt vector table but
I am not sure where the table is being populated.

rtel wrote on Wednesday, July 16, 2014:

This would normally be in the C start up assembly file.

You sent me a zip files, and ST_STM32L152C_DISCOVERY - none of which seem to contain any start up code that I can see.

If you start a debug session without running to main() - so you break on program entry - you will most probably be in the file that has the vectors.


paulromero wrote on Wednesday, July 16, 2014:

The startup code is called before main() and the
file with the code–STM_startup.s is attached.

rtel wrote on Wednesday, July 16, 2014:

As per the links already provided, FreeRTOS needs three handlers installed:

In the file you posted this is called PendSV_Handler.

In the file you posted this is called SVC_Handler.

In the file you posted this is called SysTick_Handler.

These are the CMSIS names for the functions, so the easiest thing to do is leave the start up code unedited, and instead map the FreeRTOS handlers to the CMSIS handlers as described on the link posted above, and replicated below:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler


paulromero wrote on Wednesday, July 16, 2014:

This is already done in FreeRTOSConfig.h

paulromero wrote on Thursday, July 17, 2014:

The scheduler problem was that the FreeRTOS heap size–configured with
configTOTAL_HEAP_SIZE in FreeRTOSConfig.h was too small. Setting it 10K
works. It is important to know that the FreeRTOS heap size is not
the same as the Crossworks heap size, and you need to tune the FreeRTOS
heap size rather than the Crossworks heap size.

The clocking problem with the STM HSE clock is still open and may be
a hardware problem.

paulromero wrote on Thursday, July 17, 2014:

Does FreeRTOS manage its own stack space and does it follow
the normal rule–the stack grows down the heap grows up ?