Although FreeRTOS is all about creating tasks, you can just use a main loop approach to programms running on it if you want to. You simply need to ocassionally sleep so the RTOS can drop down to the Idle task, do any housekeeping and reset its watchdog timer.
Here's a working example of a main loop implementation
int64_t last_heartbeat = 0;
int64_t heartbeat_difference;
int hb_10ms_timer = 0;
int hb_100ms_timer = 0;
int hb_1sec_timer = 0;
//********************************
//********************************
//********** INITIALISE **********
//********************************
//********************************
void initialise (void)
{
//----- SETUP THE IO PINS -----
//----- SETUP HEARTBEAT TIMER -----
last_heartbeat = esp_timer_get_time();
printf("Project started...\n");
}
//***********************************
//***********************************
//********** MAIN FUNCTION **********
//***********************************
//***********************************
void app_main()
{
//----- CREATE OUR MAIN LOOP TASK -----
//Main loop will operate 1 priority level above idle so it will run in preference to idle, but behind anything else periodic and important
xTaskCreate(my_app_main, "my_app_main", 8192, (void* ) 0, (tskIDLE_PRIORITY + 1), NULL); //<<<<<<<GIVE THIS MAIN TASK PLENTY OF STACK MEMORY (enough for any of the functions it will call) <<<<<<<<<<<
}
void my_app_main (void *pvParameters)
{
//**********************
//**********************
//***** INITIALISE *****
//**********************
//**********************
//GENERAL INITIALISE
initialise();
//*********************
//*********************
//***** MAIN LOOP *****
//*********************
//*********************
printf("STARTING MAIN LOOP\n");
while (1)
{
if (do_main_loop_idle_release >= 2) //We need to let idle run at least once every 4 seconds it seems from testing, otherwise you get "Task watchdog got triggered. The following tasks did not reset the watchdog in time: - IDLE (CPU 0)". using 5 here will cause it, use something lower to ensure it never happens
{
do_main_loop_idle_release = 0;
vTaskDelay(10 / portTICK_PERIOD_MS); //<<<Release to the idle background process, we'll be gone from the main loop for min 10mS before the scheduler comes back to us here
//ESP_LOGI("Main loop", "... idle release");
}
//----- DO HEARTBEAT -----
do_heartbeat();
}
}
//*******************************
//*******************************
//********** HEARTBEAT **********
//*******************************
//*******************************
void do_heartbeat (void)
{
//static int io_state = 0;
static int fast_flashing_1ms_timer = 0;
heartbeat_difference = esp_timer_get_time() - last_heartbeat; //esp_timer_get_time() returns time since startup in uS. int64=292,471 years before overflow!
while (heartbeat_difference > 1000) //<<< Heartbeat every 1mS (1000 uS)
{
//*************************
//***** 1mS HEARTBEAT *****
//*************************
heartbeat_difference -= 1000;
last_heartbeat += 1000; //<<< Heartbeat every 1mS
//Toggle a pin so we can verify the heartbeat is working using an oscilloscope
/*
io_state ^= 1; //Toggle the pins state
gpio_set_direction(GPIO_NUM_5, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_5, io_state);
*/
//********************
//***** 100 mSec *****
//********************
hb_100ms_timer++;
if (hb_100ms_timer >= 100)
{
hb_100ms_timer = 0;
}
//*****************
//***** 1 Sec *****
//*****************
hb_1sec_timer++;
if (hb_1sec_timer >= 1000)
{
hb_1sec_timer = 0;
}
} //while (heartbeat_difference > 1000)
}
USEFUL?
We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through mini sites like this. We hope you find the site helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support on this site. If you need help with a problem please use one of the many online forums.