Complete Examples + State Machine Implementation
#include "driver/gpio.h"
#include "esp_log.h"
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/timers.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
void my_task(void *pvParam)
{
while(1)
{
printf("Hello Shuva, What's up?\n");
fflush(stdout);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
xTaskCreate(my_task, "myTask", 1024, NULL, 1, NULL);
}
void my_task(void *pvParam)
{
while(1)
{
printf("Hello Shuva, What's up?\n");
fflush(stdout);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
TaskHandle_t myTaskHandeler = NULL;
xTaskCreate(my_task, "myTask", 1024, NULL, 1, &myTaskHandeler);
vTaskDelay(3000 / portTICK_PERIOD_MS);
if(myTaskHandeler != NULL)
{
vTaskDelete(myTaskHandeler);
}
printf("Task has been deleted.");
while(1)
{
printf("\nFrom main function.\n");
fflush(stdout);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
TaskHandle_t TaskAHandle = NULL;
void TaskA(void *pvParameters)
{
while (1)
{
printf("Task A is running!\n");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void TaskB(void *pvParameters)
{
while (1)
{
printf("Task B: Suspending Task A\n");
vTaskSuspend(TaskAHandle);
vTaskDelay(pdMS_TO_TICKS(5000)); // Wait 5 seconds
printf("Task B: Resuming Task A\n");
vTaskResume(TaskAHandle);
vTaskDelay(pdMS_TO_TICKS(5000)); // Repeat every 10 seconds
}
}
void app_main()
{
xTaskCreate(TaskA, "Task A", 2048, NULL, 1, &TaskAHandle);
xTaskCreate(TaskB, "Task B", 2048, NULL, 2, NULL); // Higher priority
}
SemaphoreHandle_t xSemaphore = NULL;
TaskHandle_t myTaskHandle = NULL;
TaskHandle_t myTaskHandle2 = NULL;
void Demo_Task(void *arg)
{
while (1)
{
xSemaphoreTake(xSemaphore, portMAX_DELAY);
printf("Message Sent! [%ld Sec] \n", pdTICKS_TO_MS(xTaskGetTickCount())/1000);
vTaskDelay(pdMS_TO_TICKS(3000));
xSemaphoreGive(xSemaphore);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void Demo_Task2(void *arg)
{
while (1)
{
xSemaphoreTake(xSemaphore, portMAX_DELAY);
printf("\033[0;34mReceived Message [%ld Sec] \n\033[0;37m", pdTICKS_TO_MS(xTaskGetTickCount())/1000);
vTaskDelay(pdMS_TO_TICKS(2000));
xSemaphoreGive(xSemaphore);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void app_main(void)
{
xSemaphore = xSemaphoreCreateBinary();
xSemaphoreGive(xSemaphore);
xTaskCreate(Demo_Task, "Demo_Task", 4096, NULL, 10, &myTaskHandle);
vTaskDelay(pdMS_TO_TICKS(500));
xTaskCreatePinnedToCore(Demo_Task2, "Demo_Task2", 4096, NULL, 10, &myTaskHandle2, 1);
}
void vPrintFunction(void *parameter)
{
while(1)
{
printf("From myTask, Parameter = %d\n", *((int *)parameter));
vTaskDelay(1000/portTICK_PERIOD_MS);
}
}
void app_main()
{
int num = 5;
xTaskCreate(vPrintFunction, "myTask", 2048, (void *) &num, 1, NULL);
}
void vPrintFunction(void *parameter)
{
while(1)
{
printf("From myTask, 1st Parameter = %d\n", *((int *)parameter));
printf("From myTask, 2nd Parameter = %d\n", *((int *)parameter + 1));
printf("From myTask, 3rd Parameter = %d\n", *((int *)parameter + 2));
printf("From myTask, 4th Parameter = %d\n", *((int *)parameter + 3));
vTaskDelay(1000/portTICK_PERIOD_MS);
}
}
void app_main()
{
int num[] = {5, 6, 7, 8};
xTaskCreate(vPrintFunction, "myTask", 2048, (void *) num, 1, NULL);
}
typedef struct struc{
int Member1;
char Member2;
}xStruct;
void vPrintFunction(void *parameter)
{
while(1)
{
printf("From myTask, 1st Parameter = %d\n", ((xStruct *)parameter)->Member1);
printf("From myTask, 2nd Parameter = %c\n", ((xStruct *)parameter)->Member2);
vTaskDelay(1000/portTICK_PERIOD_MS);
}
}
void app_main()
{
xStruct *obj = NULL;
obj = (xStruct *)malloc(sizeof(xStruct));
obj->Member1 = 5;
obj->Member2 = 'S';
xTaskCreate(vPrintFunction, "myTask", 2048, (void *) obj, 1, NULL);
}
#define QUEUE_SIZE 5
QueueHandle_t myQueue;
void ProducerTask(void *arg)
{
int count = 0;
while (1)
{
if (xQueueSend(myQueue, &count, pdMS_TO_TICKS(100)) == pdTRUE)
{
printf("Produced: %d\n", count);
count++;
}
else
{
printf("Queue Full!\n");
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void ConsumerTask(void *arg)
{
int rxValue;
while (1)
{
if (xQueueReceive(myQueue, &rxValue, portMAX_DELAY))
{
printf("Consumed: %d\n", rxValue);
}
}
}
void app_main(void)
{
myQueue = xQueueCreate(QUEUE_SIZE, sizeof(int));
if (myQueue != NULL)
{
xTaskCreate(ProducerTask, "ProducerTask", 2048, NULL, 1, NULL);
xTaskCreate(ConsumerTask, "ConsumerTask", 2048, NULL, 1, NULL);
}
else
{
printf("Failed to create queue.\n");
}
}
TimerHandle_t myTimer;
void TimerCallback(TimerHandle_t xTimer)
{
static int counter = 0;
printf("Timer Callback executed! Counter = %d\n", counter++);
}
void app_main(void)
{
myTimer = xTimerCreate("MyTimer", // Timer name
pdMS_TO_TICKS(2000), // Timer period: 2 seconds
pdTRUE, // Auto-reload (periodic)
(void *)0, // Timer ID
TimerCallback); // Callback function
if (myTimer != NULL)
{
xTimerStart(myTimer, 0); // Start the timer immediately
printf("Timer started!\n");
}
else
{
printf("Failed to create timer.\n");
}
}
typedef enum{
APP_SM_EVENT_ENTRY,
APP_EVENT_SYSTEM_INIT,
APP_EVENT_SYSTEM_NEXT,
APP_SM_EVENT_EXIT,
} app_sm_t;
typedef enum {
APP_SM_STATUS_HANDLED,
APP_SM_STATUS_IGNORED,
APP_SM_STATUS_TRAN,
} app_smStatus_t;
QueueHandle_t gEventQH;
#define APP_CONFIG_EVENT_QUEUE_SIZE 10
typedef struct app_smInst app_smInst_t;
typedef app_smStatus_t (*app_smStateHandle_t)(app_smInst_t *const pInstance, app_sm_t pParam);
struct app_smInst {
app_smStateHandle_t active;
app_smStateHandle_t nextState;
};
static app_smInst_t gAppSmInt;
static void AppPostEvent(app_sm_t event);
static void AppDispatcher();
// Create State Machine's Functuions
app_smStatus_t AppState1(app_smInst_t *const pInstance, app_sm_t pEventParam);
app_smStatus_t AppState2(app_smInst_t *const pInstance, app_sm_t pEventParam);
app_smStatus_t AppState1(app_smInst_t *const pInstance, app_sm_t pEventParam) {
app_smStatus_t returnStatus = APP_SM_STATUS_HANDLED;
switch (pEventParam) {
case APP_SM_EVENT_ENTRY: {
ESP_LOGI("TAG", "APP_SM_EVENT_ENTRY 1");
AppPostEvent(APP_EVENT_SYSTEM_INIT);
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
case APP_EVENT_SYSTEM_INIT: {
ESP_LOGI("TAG", "APP_EVENT_SYSTEM_INIT 1");
AppPostEvent(APP_EVENT_SYSTEM_NEXT);
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
case APP_EVENT_SYSTEM_NEXT: {
ESP_LOGI("TAG", "APP_EVENT_SYSTEM_NEXT 1");
pInstance->nextState = AppState2;
returnStatus = APP_SM_STATUS_TRAN;
break;
}
case APP_SM_EVENT_EXIT: {
ESP_LOGI("TAG", "APP_SM_EVENT_EXIT 1");
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
default: {
ESP_LOGE("TAG", "%s : %d : Ignored event 1 %d : %d", __func__, __LINE__, pEventParam, returnStatus);
returnStatus = APP_SM_STATUS_IGNORED;
break;
}
}
return returnStatus;
}
app_smStatus_t AppState2(app_smInst_t *const pInstance, app_sm_t pEventParam) {
app_smStatus_t returnStatus = APP_SM_STATUS_HANDLED;
switch (pEventParam) {
case APP_SM_EVENT_ENTRY: {
ESP_LOGW("TAG", "APP_SM_EVENT_ENTRY 2");
AppPostEvent(APP_EVENT_SYSTEM_INIT);
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
case APP_EVENT_SYSTEM_INIT: {
ESP_LOGW("TAG", "APP_EVENT_SYSTEM_INIT 2");
AppPostEvent(APP_EVENT_SYSTEM_NEXT);
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
case APP_EVENT_SYSTEM_NEXT: {
ESP_LOGW("TAG", "APP_EVENT_SYSTEM_NEXT 2");
pInstance->nextState = AppState1;
returnStatus = APP_SM_STATUS_TRAN;
break;
}
case APP_SM_EVENT_EXIT: {
ESP_LOGW("TAG", "APP_SM_EVENT_EXIT 2");
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
default: {
ESP_LOGE("TAG", "%s : %d : Ignored event 2 %d : %d", __func__, __LINE__, pEventParam, returnStatus);
returnStatus = APP_SM_STATUS_IGNORED;
break;
}
}
return returnStatus;
}
static void AppPostEvent(app_sm_t event) {
if (xQueueSend(gEventQH, &event, 100) != pdTRUE) {
ESP_LOGW("TAG", " %s : %d : Failed to post event", __func__, __LINE__);
}
}
static void AppDispatcher(void *pvParam) {
app_sm_t event;
app_smStatus_t ret;
while (1) {
xQueueReceive(gEventQH, &event, portMAX_DELAY);
ret = gAppSmInt.active(&gAppSmInt, event);
if (ret == APP_SM_STATUS_TRAN) {
event = APP_SM_EVENT_EXIT;
gAppSmInt.active(&gAppSmInt, event);
if (gAppSmInt.nextState != NULL) {
gAppSmInt.active = gAppSmInt.nextState;
event = APP_SM_EVENT_ENTRY;
gAppSmInt.active(&gAppSmInt, event);
} else {
ESP_LOGE("TAG", "%s : %d : State Change Requested, but NextSate is NULL", __func__, __LINE__);
}
}
}
vTaskDelete(NULL);
}
void app_main(void)
{
gEventQH = xQueueCreate(APP_CONFIG_EVENT_QUEUE_SIZE, sizeof(app_sm_t));
gAppSmInt.active = AppState1;
app_sm_t event = APP_SM_EVENT_ENTRY;
gAppSmInt.active(&gAppSmInt, event);
gAppSmInt.nextState = NULL;
xTaskCreate(AppDispatcher, "AppDispatcherTask", 2048, NULL, 1, NULL);
}
typedef enum{
APP_SM_EVENT_ENTRY,
APP_EVENT_SYSTEM_INIT,
APP_EVENT_SYSTEM_NEXT,
APP_SM_EVENT_EXIT,
} app_sm_t;
typedef struct {
app_sm_t event;
union {
struct {
uint8_t param1;
uint16_t param2;
} var1;
struct {
char *param3;
uint16_t param4;
} var2;
};
} app_eventParam_t;
typedef enum {
APP_SM_STATUS_HANDLED,
APP_SM_STATUS_IGNORED,
APP_SM_STATUS_TRAN,
} app_smStatus_t;
QueueHandle_t gEventQH;
#define APP_CONFIG_EVENT_QUEUE_SIZE 10
typedef struct app_smInst app_smInst_t;
typedef app_smStatus_t (*app_smStateHandle_t)(app_smInst_t *const pInstance, app_eventParam_t *pEventParam);
struct app_smInst {
app_smStateHandle_t active;
app_smStateHandle_t nextState;
};
static app_smInst_t gAppSmInt;
static void AppPostEvent(app_eventParam_t *pEventParam);
static void AppDispatcher();
// Create State Machine's Functuions
app_smStatus_t AppState1(app_smInst_t *const pInstance, app_eventParam_t *pEventParam);
app_smStatus_t AppState2(app_smInst_t *const pInstance, app_eventParam_t *pEventParam);
app_smStatus_t AppState1(app_smInst_t *const pInstance, app_eventParam_t *pEventParam) {
app_eventParam_t eventParam;
app_smStatus_t returnStatus = APP_SM_STATUS_HANDLED;
switch (pEventParam->event) {
case APP_SM_EVENT_ENTRY: {
ESP_LOGI("TAG", "APP_SM_EVENT_ENTRY 1 (param 1,2 posted)");
eventParam.event = APP_EVENT_SYSTEM_INIT;
eventParam.var1.param1 = 0x10;
eventParam.var1.param2 = 0x6F85;
AppPostEvent(&eventParam);
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
case APP_EVENT_SYSTEM_INIT: {
ESP_LOGI("TAG", "APP_EVENT_SYSTEM_INIT 1 (param1: 0x%X, param2: 0x%X)", pEventParam->var1.param1, pEventParam->var1.param2);
eventParam.event = APP_EVENT_SYSTEM_NEXT;
AppPostEvent(&eventParam);
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
case APP_EVENT_SYSTEM_NEXT: {
ESP_LOGI("TAG", "APP_EVENT_SYSTEM_NEXT 1");
pInstance->nextState = AppState2;
returnStatus = APP_SM_STATUS_TRAN;
break;
}
case APP_SM_EVENT_EXIT: {
ESP_LOGI("TAG", "APP_SM_EVENT_EXIT 1");
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
default: {
ESP_LOGE("TAG", "%s : %d : Ignored event 1 %d : %d", __func__, __LINE__, pEventParam->event, returnStatus);
returnStatus = APP_SM_STATUS_IGNORED;
break;
}
}
return returnStatus;
}
app_smStatus_t AppState2(app_smInst_t *const pInstance, app_eventParam_t *pEventParam) {
app_eventParam_t eventParam;
app_smStatus_t returnStatus = APP_SM_STATUS_HANDLED;
switch (pEventParam->event) {
case APP_SM_EVENT_ENTRY: {
ESP_LOGW("TAG", "APP_SM_EVENT_ENTRY 2 (param 3,4 posted)");
eventParam.event = APP_EVENT_SYSTEM_INIT;
eventParam.var2.param3 = (char *)malloc(10 * sizeof(char));
memset(eventParam.var2.param3, 0, 10 * sizeof(char));
strcpy(eventParam.var2.param3, "Shuva is good");
eventParam.var2.param4 = 0x2048;
AppPostEvent(&eventParam);
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
case APP_EVENT_SYSTEM_INIT: {
ESP_LOGW("TAG", "APP_EVENT_SYSTEM_INIT 2 (param3: %s, param4: 0x%X)", pEventParam->var2.param3, pEventParam->var2.param4);
free(pEventParam->var2.param3);
pEventParam->var2.param3 = NULL;
eventParam.event = APP_EVENT_SYSTEM_NEXT;
AppPostEvent(&eventParam);
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
case APP_EVENT_SYSTEM_NEXT: {
ESP_LOGW("TAG", "APP_EVENT_SYSTEM_NEXT 2");
pInstance->nextState = AppState1;
returnStatus = APP_SM_STATUS_TRAN;
break;
}
case APP_SM_EVENT_EXIT: {
ESP_LOGW("TAG", "APP_SM_EVENT_EXIT 2");
returnStatus = APP_SM_STATUS_HANDLED;
break;
}
default: {
ESP_LOGE("TAG", "%s : %d : Ignored event 2 %d : %d", __func__, __LINE__, pEventParam->event, returnStatus);
returnStatus = APP_SM_STATUS_IGNORED;
break;
}
}
return returnStatus;
}
static void AppPostEvent(app_eventParam_t *pEventParam) {
if (xQueueSend(gEventQH, pEventParam, 100) != pdTRUE) {
ESP_LOGW("TAG", " %s : %d : Failed to post event", __func__, __LINE__);
}
}
static void AppDispatcher(void *pvParam) {
app_eventParam_t eventParam;
app_smStatus_t ret;
while (1) {
xQueueReceive(gEventQH, &eventParam, portMAX_DELAY);
ret = gAppSmInt.active(&gAppSmInt, &eventParam);
if (ret == APP_SM_STATUS_TRAN) {
eventParam.event = APP_SM_EVENT_EXIT;
gAppSmInt.active(&gAppSmInt, &eventParam);
if (gAppSmInt.nextState != NULL) {
gAppSmInt.active = gAppSmInt.nextState;
eventParam.event = APP_SM_EVENT_ENTRY;
gAppSmInt.active(&gAppSmInt, &eventParam);
} else {
ESP_LOGE("TAG", "%s : %d : State Change Requested, but NextSate is NULL", __func__, __LINE__);
}
}
}
vTaskDelete(NULL);
}
void app_main(void)
{
app_eventParam_t eventParam;
gEventQH = xQueueCreate(APP_CONFIG_EVENT_QUEUE_SIZE, sizeof(app_eventParam_t));
gAppSmInt.active = AppState1;
eventParam.event = APP_SM_EVENT_ENTRY;
gAppSmInt.active(&gAppSmInt, &eventParam);
gAppSmInt.nextState = NULL;
xTaskCreate(AppDispatcher, "AppDispatcherTask", 2048, NULL, 1, NULL);
}