2020-02-26 07:13 AM
As soon as I add a task to the scheduler and schedule it to run once every 5 seconds, when the timer fires and the sequencer tries to run the task the STM32 goes to the hard fault handler.
I'm using the latest example BLE_p2pServer from STM32CubeWB 1.5.0, the example is as-is, except for adding "deviceModes.c":
#include "deviceModes.h"
void StandbyMode();
void QueueStandbyMode();
const int SCH_PRIORITY_STANDBY_MODE = CFG_SCH_PRIO_20;
uint8_t standbyTimerId;
#define FIVE_S (5 * 1000 * 1000 / CFG_TS_TICK_VAL)
void RegisterDeviceModes() {
UTIL_SEQ_RegTask(CFG_TASK_STANDBY_MODE, UTIL_SEQ_RFU,StandbyMode);
HW_TS_Create(CFG_TIM_PROC_ID_ISR, &standbyTimerId, hw_ts_Repeated, QueueStandbyMode);
HW_TS_Start(standbyTimerId, FIVE_S);
}
void QueueStandbyMode() {
UTIL_SEQ_SetTask(1 << CFG_TASK_STANDBY_MODE, SCH_PRIORITY_STANDBY_MODE);
}
void StandbyMode() {
BSP_LED_Toggle(LED_RED);
HAL_Delay(5);
BSP_LED_Toggle(LED_RED);
}
The problem doesn't occur on the p2pServer examples from CubeWB1.1.1 - why is this happening? How do we use the Sequencer and Timer server on the 1.5.0 p2pServer example?
I've attached a git repo which shows only 2 changes from as-downloaded: adding a Makefile, then adding the task to the sequencer.
Solved! Go to Solution.
2020-03-05 06:26 AM
Maybe I found another point in the source code that has to be modified. In the file "utilities_conf.h" you can find the following part:
/******************************************************************************
* sequencer
* (any macro that does not need to be modified can be removed)
******************************************************************************/
#define UTIL_SEQ_INIT_CRITICAL_SECTION( )
#define UTIL_SEQ_ENTER_CRITICAL_SECTION( ) UTILS_ENTER_CRITICAL_SECTION( )
#define UTIL_SEQ_EXIT_CRITICAL_SECTION( ) UTILS_EXIT_CRITICAL_SECTION( )
#define UTIL_SEQ_CONF_TASK_NBR (32)
#define UTIL_SEQ_CONF_PRIO_NBR (2)
#define UTIL_SEQ_MEMSET8( dest, value, size ) UTILS_MEMSET8( dest, value, size )
If you have another priority listing with more than the default entries then it's possible that you will have an exception in the scheduler, because there is no entry for the task. I tried it in my own project with an additional priority, so my counter has to be 3 instead of 2. Otherwise I will run into the hard fault...
#define UTIL_SEQ_CONF_PRIO_NBR 3 /*(2)*/
The hardfault occurs when in the function UTIL_SEQ_Run() the last line of the following part is executed:
/** remove from all priority mask the task that has been selected to be executed */
for (counter = UTIL_SEQ_CONF_PRIO_NBR; counter; counter--)
{
TaskPrio[counter - 1].priority &= ~(1 << (CurrentTaskIdx));
}
UTIL_SEQ_EXIT_CRITICAL_SECTION( );
/** Execute the task */
TaskCb[CurrentTaskIdx]( );
You should debug the UTIL_SEQ_RUN() function in your while(1) loop and check at which point the hardfault occurs.
2020-02-27 05:34 AM
There is nothing obviously wrong regarding the way you are programming it.
Just 2 points to check:
1) I see you want to wake up your task every 5s while the task is lasting longer than 5s. So I am just thinking about some overflow somewhere due to the fact that the current StandbyMode task is not completed when a new task is already awaken. Could you try to run this task every 10s just to check if that could be the cause?
2) You add (register) one new task but did you increase the number of task in the system? How do you define CFG_TASK_STANDBY_MODE?
2020-02-27 05:43 AM
I've managed to get a bit more information.
If I replace the sequencer SetTask function with just a printf, it works and prints "queuing standby mode" once every 5 seconds.
void QueueStandbyMode() {
printf("queuing standby mode\n");
//UTIL_SEQ_SetTask(1 << CFG_TASK_STANDBY_MODE, SCH_PRIORITY_STANDBY_MODE);
}
So it's the UTIL_SEQ_SetTask (line 3 in code above) that causes the hard fault.
In app_conf.h I add the task ID and priority:
/**< Add in that list all tasks that never send a ACI/HCI command */
typedef enum
{
CFG_FIRST_TASK_ID_WITH_NO_HCICMD = CFG_LAST_TASK_ID_WITH_HCICMD - 1, /**< Shall be FIRST in the list */
CFG_TASK_SYSTEM_HCI_ASYNCH_EVT_ID,
/* USER CODE BEGIN CFG_Task_Id_With_NO_HCI_Cmd_t */
CFG_TASK_STANDBY_MODE,
/* USER CODE END CFG_Task_Id_With_NO_HCI_Cmd_t */
CFG_LAST_TASK_ID_WITHO_NO_HCICMD /**< Shall be LAST in the list */
} CFG_Task_Id_With_NO_HCI_Cmd_t;
#define CFG_TASK_NBR CFG_LAST_TASK_ID_WITHO_NO_HCICMD
/**
* This is the list of priority required by the application
* Each Id shall be in the range 0..31
*/
typedef enum
{
CFG_SCH_PRIO_0,
CFG_SCH_PRIO_20, /* Standby mode */
CFG_PRIO_NBR,
} CFG_SCH_Prio_Id_t;
(lines 7 and 20 in the code snippet above).
2020-02-27 05:48 AM
And a bit more information: even if I replace StandbyMode() with just a printf, it still enters a hard fault and never executes the printf.
void StandbyMode() {
printf("in standby mode\n");
//BSP_LED_Toggle(LED_RED);
//HAL_Delay(5);
//BSP_LED_Toggle(LED_RED);
}
2020-02-27 06:50 AM
In all cases you tried, it works when you are not adding a new task and it fails as soon as a new task is added whatever is done inside that task.
What is the value of CFG_LAST_TASK_ID_WITH_HCICMD ?
2020-02-27 07:47 AM
CFG_LAST_TASK_ID_WITH_HCICMD has a value of 4.
I noticed that this means that CFG_TASK_HCI_ASYNCH_EVT_ID is 3 which is equal to CFG_FIRST_TASK_ID_WITH_NO_HCICMD.
Could this be the issue? As mentioned we haven't changed these enums and just added our own to the example as downloaded from the ST website.
2020-03-05 06:26 AM
Maybe I found another point in the source code that has to be modified. In the file "utilities_conf.h" you can find the following part:
/******************************************************************************
* sequencer
* (any macro that does not need to be modified can be removed)
******************************************************************************/
#define UTIL_SEQ_INIT_CRITICAL_SECTION( )
#define UTIL_SEQ_ENTER_CRITICAL_SECTION( ) UTILS_ENTER_CRITICAL_SECTION( )
#define UTIL_SEQ_EXIT_CRITICAL_SECTION( ) UTILS_EXIT_CRITICAL_SECTION( )
#define UTIL_SEQ_CONF_TASK_NBR (32)
#define UTIL_SEQ_CONF_PRIO_NBR (2)
#define UTIL_SEQ_MEMSET8( dest, value, size ) UTILS_MEMSET8( dest, value, size )
If you have another priority listing with more than the default entries then it's possible that you will have an exception in the scheduler, because there is no entry for the task. I tried it in my own project with an additional priority, so my counter has to be 3 instead of 2. Otherwise I will run into the hard fault...
#define UTIL_SEQ_CONF_PRIO_NBR 3 /*(2)*/
The hardfault occurs when in the function UTIL_SEQ_Run() the last line of the following part is executed:
/** remove from all priority mask the task that has been selected to be executed */
for (counter = UTIL_SEQ_CONF_PRIO_NBR; counter; counter--)
{
TaskPrio[counter - 1].priority &= ~(1 << (CurrentTaskIdx));
}
UTIL_SEQ_EXIT_CRITICAL_SECTION( );
/** Execute the task */
TaskCb[CurrentTaskIdx]( );
You should debug the UTIL_SEQ_RUN() function in your while(1) loop and check at which point the hardfault occurs.
2020-03-05 06:55 AM
I think your problem is that your task registration is not correct:
UTIL_SEQ_RegTask(CFG_TASK_STANDBY_MODE, UTIL_SEQ_RFU,StandbyMode);
should be
UTIL_SEQ_RegTask ( 1 << CFG_TASK_STANDBY_MODE, UTIL_SEQ_RFU, StandbyMode );
to register it in the correct position (be aware of bit-shifting!).
2020-03-05 07:31 AM
Thank you! Tested and works. However, in the STM32WB workshop documentation the bit-shifting is only done for UTIL_SEQ_SetTask() which is why we missed this. Thanks again!
2021-04-02 08:24 PM
I had the same issue, and it turned out that there was no interrupt routine for RTC call back; i.e. "RTC_WKUP_IRQHandler"
You need to add this function to your "stm32wbxx_it.c"
"
void RTC_WKUP_IRQHandler(void)
{
HW_TS_RTC_Wakeup_Handler();
}
"
and this line to its header "stm32wbxx_it.h"
"
void RTC_WKUP_IRQHandler(void);
"