Just an additional hint: I’d recommend to enable stack overflow checking. See FreeRTOS - stacks and stack overflow checking and define configASSERT
.
As seen you create the tasks with minimal stack size. This might be too small…
Why do you need to do this? Are you not able to use xFLASHWRITINGTASK_Tasks
? Something like the following -
/* Simulation - Kick off the FlashWritingTask every 100 ms. */
void SimulationTask( void * params )
{
extern TaskHandle_t xFLASHWRITINGTASK_Tasks;
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS( 100 );
( void ) params;
/* Initialise the xLastWakeTime variable with the current time. */
xLastWakeTime = xTaskGetTickCount();
for( ;; )
{
/* Wait for the next cycle. */
vTaskDelayUntil( &xLastWakeTime, xFrequency );
/* Kick off the FlashWritingTask. */
xTaskNotifyGive( xFLASHWRITINGTASK_Tasks );
}
}
I am not sure what’s wrong, but the LED is not flashing in the flashwritingtask.c
main.c
/* Bosch IMU BMI160 IRQ - Kick off the FlashWritingTask every 100 ms. */
static void TC3_TimerCallback(TC_TIMER_STATUS status, uintptr_t context) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(FlashWritingTaskHandle, &(xHigherPriorityTaskWoken));
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
int main ( void )
{
/* Initialize all modules */
SYS_Initialize ( NULL );
TC3_TimerCallbackRegister(TC3_TimerCallback, (uintptr_t) NULL);
TC3_TimerStart();
while ( true )
{
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
}
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE );
}
simulationtask.c
void SIMULATIONTASK_Initialize(void) {
/* Place the App state machine in its initial state. */
simulationtaskData.state = SIMULATIONTASK_STATE_INIT;
/* TODO: Initialize your application's state machine and other
* parameters.
*/
}
/******************************************************************************
Function:
void SIMULATIONTASK_Tasks ( void )
Remarks:
See prototype in simulationtask.h.
*/
void SIMULATIONTASK_Tasks(void) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS( 100 );
/* Check the application's current state. */
switch (simulationtaskData.state) {
/* Application's initial state. */
case SIMULATIONTASK_STATE_INIT:
{
bool appInitialized = true;
if (appInitialized) {
/* Initialise the xLastWakeTime variable with the current time. */
xLastWakeTime = xTaskGetTickCount();
simulationtaskData.state = SIMULATIONTASK_STATE_SERVICE_TASKS;
}
break;
}
case SIMULATIONTASK_STATE_SERVICE_TASKS:
{
/* Wait for the next cycle. */
vTaskDelayUntil(&xLastWakeTime, xFrequency);
/* Kick off the FlashWritingTask. */
xTaskNotifyGive(FlashWritingTaskHandle);
break;
}
/* TODO: implement your application state machine.*/
/* The default state should never be executed. */
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}
flashwritingtask.c
TaskHandle_t FlashWritingTaskHandle;
void FLASHWRITINGTASK_Initialize ( void )
{
/* Place the App state machine in its initial state. */
flashwritingtaskData.state = FLASHWRITINGTASK_STATE_INIT;
}
void FLASHWRITINGTASK_Tasks ( void )
{
/* Check the application's current state. */
switch ( flashwritingtaskData.state )
{
/* Application's initial state. */
case FLASHWRITINGTASK_STATE_INIT:
{
bool appInitialized = true;
if (appInitialized)
{
flashwritingtaskData.state = FLASHWRITINGTASK_STATE_SERVICE_TASKS;
}
break;
}
case FLASHWRITINGTASK_STATE_SERVICE_TASKS:
{
/* Wait for a notification to write to flash. */
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
/* Write to flash. */
LED_Toggle();
break;
}
/* TODO: implement your application state machine.*/
/* The default state should never be executed. */
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}
flashwritingtask.h
extern TaskHandle_t FlashWritingTaskHandle;
John, you really should follow @aggarg ‘s task code template to make your tasks work properly. A task is not just a function, it’s a forever loop doing something over and over again. See Writing RTOS tasks in FreeRTOS - implementing tasks as forever loops.
And where is FlashWritingTaskHandle
initialized ? Why not using (global) xFLASHWRITINGTASK_Tasks
directly initialized in your SYS_Tasks
function ?
I modified the simulationtask.c
xTaskNotifyGive(xFLASHWRITINGTASK_Tasks);
and main.c
* Bosch IMU BMI160 IRQ - Kick off the FlashWritingTask every 100 ms. */
static void TC3_TimerCallback(TC_TIMER_STATUS status, uintptr_t context) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(xFLASHWRITINGTASK_Tasks, &(xHigherPriorityTaskWoken));
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
int main ( void )
{
/* Initialize all modules */
SYS_Initialize ( NULL );
TC3_TimerCallbackRegister(TC3_TimerCallback, (uintptr_t) NULL);
TC3_TimerStart();
while ( true )
{
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
but I got an error:
./src/main.c:41:28: error: ‘xFLASHWRITINGTASK_Tasks’ undeclared (first use in this function); did you mean ‘FLASHWRITINGTASK_Tasks’?
although I added:
#include "FreeRTOS.h"
#include "task.h"
even thought the xFLASHWRITINGTASK_Tasks is correctly linked to:
/* Handle for the FLASHWRITINGTASK_Tasks. */
TaskHandle_t xFLASHWRITINGTASK_Tasks;
static void lFLASHWRITINGTASK_Tasks( void *pvParameters )
{
while(true)
{
FLASHWRITINGTASK_Tasks();
}
}
in task.c
I had the problem falling to HardFault_Handler which was cased by forgetting
TaskHandle_t FlashWritingTaskHandle;
in flashwritingtask.c
Now program is working. IRQ period is 100 ms. The only problem is the test GPIO Pin Toggle in FlashWritingTask has the +width 36 µs instead of IRQ +width 100 ms.
The problem is for sure in the:
void SIMULATIONTASK_Tasks(void) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS( 100 );
as I don’t know yet how to add parameters
( void * params )
to the task in the MPLAB X IDE, Harmony.
I didn’t understand that I can’t use aggarg’s program template as he provided it here. There was no mention of it anywhere.
I have to either use the FlashWritingTask run using IRQ (from Bosch IMU or testbench from TC3) or use the Simulationtask not both options at the same time.
When using vTaskDelay(pdMS_TO_TICKS( 100 ))
in Simulationtask, all variants work fine and the FlashWritingTask runs every 100 ms.
At the end I found that the variables
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS( 100 );
for the vTaskDelayUntil(&xLastWakeTime, xFrequency)
function has to be defined in Global Data Definitions section of the Simulationtask i.e. at the beginning of the task (MPLAB X IDE, Harmony).
Now the program is working as expected. Thanks to all who helped me, richard and aggarg especially.
That is right - I should have been explicit that only one of simulation or real hardware IRQ should be used.
Glad that you made it work!