最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

【FreeRTOS】

运维笔记admin21浏览0评论

【FreeRTOS】

【FreeRTOS】

FreeRTOS

  • 一、FreeRTOS任务创建和删除
    • 1.1 动态方式
    • 1.2 静态方式
  • 二、任务挂起和恢复
  • 三、中断管理
  • 四、临界区保护及调度器的挂起和恢复
  • 五、列表项的插入和删除
  • 六、时间片调度
  • 七、任务状态查询API函数介绍
    • 7.1 任务状态查询API
    • 7.2 任务运行时间统计API
  • 八、时间管理
  • 九、队列
  • 十、信号量
    • 10.1 二值信号量
    • 10.2 计数型信号量
    • 10.3 优先级翻转
    • 10.4 互斥信号量
  • 十一、队列集
  • 十二、事件标志组
  • 十三、任务通知
    • 13.1 任务通知模拟二值信号量和计数型信号量
    • 13.2 任务通知模拟消息邮箱
    • 13.3 任务通知模拟事件标志组
  • 十四、软件定时器
  • 十五、低功耗Tickless模式
  • 十六、内存管理

int main(void)
{HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(360, 25, 2, 8);        /* 设置时钟,180Mhz */delay_init(180);                            /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */key_init();                                 /* 初始化按键 */sdram_init();                               /* SRAM初始化 */lcd_init();                                 /* 初始化LCD */my_mem_init(SRAMIN);                        /* 初始化内部内存池 */my_mem_init(SRAMEX);                        /* 初始化外部内存池 */my_mem_init(SRAMCCM);                       /* 初始化CCM内存池 */freertos_demo();
}

一、FreeRTOS任务创建和删除



1.1 动态方式




/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   128
TaskHandle_t    task3_handler;
void task3( void * pvParameters );
/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );xTaskCreate((TaskFunction_t         )   task3,(char *                 )   "task3",(configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK3_PRIO,(TaskHandle_t *         )   &task3_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{while(1){printf("task1正在运行!!!\r\n");LED0_TOGGLE();vTaskDelay(500);}
}/* 任务二,实现LED1每500ms翻转一次 */
void task2( void * pvParameters )
{while(1){printf("task2正在运行!!!\r\n");LED1_TOGGLE();vTaskDelay(500);}
}/* 任务三,判断按键KEY0,按下KEY0删除task1 */
void task3( void * pvParameters )
{uint8_t key = 0;while(1){printf("task3正在运行!!!\r\n");key = key_scan(0);if(key == KEY0_PRES){if(task1_handler != NULL){printf("删除task1任务\r\n");vTaskDelete(task1_handler);task1_handler = NULL;}}vTaskDelay(10);}
}

1.2 静态方式


/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
StackType_t     start_task_stack[START_TASK_STACK_SIZE];
StaticTask_t    start_task_tcb;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
StackType_t     task1_stack[TASK1_STACK_SIZE];
StaticTask_t    task1_tcb;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
StackType_t     task2_stack[TASK2_STACK_SIZE];
StaticTask_t    task2_tcb;
void task2( void * pvParameters );/* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   128
TaskHandle_t    task3_handler;
StackType_t     task3_stack[TASK3_STACK_SIZE];
StaticTask_t    task3_tcb;
void task3( void * pvParameters );
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    start_task_handler = xTaskCreateStatic( (TaskFunction_t )   start_task,(char *         )   "start_task", (uint32_t       )   START_TASK_STACK_SIZE,(void *         )   NULL,(UBaseType_t    )   START_TASK_PRIO,(StackType_t *  )   start_task_stack,(StaticTask_t * )   &start_task_tcb );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */task1_handler = xTaskCreateStatic(  (TaskFunction_t )   task1,(char *         )   "task1", (uint32_t       )   TASK1_STACK_SIZE,(void *         )   NULL,(UBaseType_t    )   TASK1_PRIO,(StackType_t *  )   task1_stack,(StaticTask_t * )   &task1_tcb );task2_handler = xTaskCreateStatic(  (TaskFunction_t )   task2,(char *         )   "task2", (uint32_t       )   TASK2_STACK_SIZE,(void *         )   NULL,(UBaseType_t    )   TASK2_PRIO,(StackType_t *  )   task2_stack,(StaticTask_t * )   &task2_tcb );task3_handler = xTaskCreateStatic(  (TaskFunction_t )   task3,(char *         )   "task3", (uint32_t       )   TASK3_STACK_SIZE,(void *         )   NULL,(UBaseType_t    )   TASK3_PRIO,(StackType_t *  )   task3_stack,(StaticTask_t * )   &task3_tcb );vTaskDelete(start_task_handler);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{while(1){printf("task1正在运行!!!\r\n");LED0_TOGGLE();vTaskDelay(500);}
}/* 任务二,实现LED1每500ms翻转一次 */
void task2( void * pvParameters )
{while(1){printf("task2正在运行!!!\r\n");LED1_TOGGLE();vTaskDelay(500);}
}/* 任务三,判断按键KEY0,按下KEY0删除task1 */
void task3( void * pvParameters )
{uint8_t key = 0;while(1){printf("task3正在运行!!!\r\n");key = key_scan(0);if(key == KEY0_PRES){if(task1_handler != NULL){printf("删除task1任务\r\n");vTaskDelete(task1_handler);task1_handler = NULL;}}vTaskDelay(10);}
}

二、任务挂起和恢复




/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   128
TaskHandle_t    task3_handler;
void task3( void * pvParameters );
/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );xTaskCreate((TaskFunction_t         )   task3,(char *                 )   "task3",(configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK3_PRIO,(TaskHandle_t *         )   &task3_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{uint32_t task1_num = 0;while(1){printf("task1_num:%d\r\n",++task1_num);LED0_TOGGLE();vTaskDelay(500);}
}/* 任务二,实现LED1每500ms翻转一次 */
void task2( void * pvParameters )
{uint32_t task2_num = 0;while(1){printf("task2_num:%d\r\n",++task2_num);LED1_TOGGLE();vTaskDelay(500);}
}/* 任务三,判断按键KEY0,按下KEY0删除task1 */
void task3( void * pvParameters )
{uint8_t key = 0;while(1){key = key_scan(0);if(key == KEY0_PRES){printf("挂起task1\r\n");vTaskSuspend(task1_handler);}else if(key == KEY1_PRES){printf("在任务中恢复task1\r\n");vTaskResume(task1_handler);}vTaskDelay(10);}
}

三、中断管理










int main(void)
{HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(360, 25, 2, 8);        /* 设置时钟,180Mhz */delay_init(180);                            /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */key_init();                                 /* 初始化按键 */sdram_init();                               /* SRAM初始化 */lcd_init();                                 /* 初始化LCD */btim_timx_int_init(10000 - 1 ,9000 - 1);    /* 1s中断一次 */btim_tim7_int_init(10000 - 1 ,9000 - 1);    /* 1s中断一次 */my_mem_init(SRAMIN);                        /* 初始化内部内存池 */my_mem_init(SRAMEX);                        /* 初始化外部内存池 */my_mem_init(SRAMCCM);                       /* 初始化CCM内存池 */freertos_demo();
}
#ifndef __BTIM_H
#define __BTIM_H
#include "./SYSTEM/sys/sys.h"
/******************************************************************************************/
/* 基本定时器 定义 *//* TIMX 中断定义 * 默认是针对TIM6/TIM7* 注意: 通过修改这4个宏定义,可以支持TIM1~TIM8任意一个定时器.*/#define BTIM_TIMX_INT                       TIM6
#define BTIM_TIMX_INT_IRQn                  TIM6_DAC_IRQn
#define BTIM_TIMX_INT_IRQHandler            TIM6_DAC_IRQHandler
#define BTIM_TIMX_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM6_CLK_ENABLE(); }while(0)  /* TIM6 时钟使能 */#define BTIM_TIM7_INT                       TIM7
#define BTIM_TIM7_INT_IRQn                  TIM7_IRQn
#define BTIM_TIM7_INT_IRQHandler            TIM7_IRQHandler
#define BTIM_TIM7_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM7_CLK_ENABLE(); }while(0)  /* TIM6 时钟使能 *//******************************************************************************************/void btim_timx_int_init(uint16_t arr, uint16_t psc);    /* 基本定时器 定时中断初始化函数 */
void btim_tim7_int_init(uint16_t arr, uint16_t psc);    /* 基本定时器 定时中断初始化函数 */
#endif#include "./BSP/LED/led.h"
#include "./BSP/TIMER/btim.h"
#include "./SYSTEM/usart/usart.h"TIM_HandleTypeDef g_timx_handle;         /* 定时器参数句柄 */
TIM_HandleTypeDef g_tim7_handle;         /* 定时器参数句柄 */
/*** @brief       基本定时器TIMX定时中断初始化函数* @note*              基本定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候*              基本定时器的时钟为APB1时钟的2倍, 而APB1为45M, 所以定时器时钟 = 90Mhz*              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.*              Ft=定时器工作频率,单位:Mhz** @param       arr : 自动重装值。* @param       psc : 时钟预分频数* @retval      无*/
void btim_timx_int_init(uint16_t arr, uint16_t psc)
{g_timx_handle.Instance = BTIM_TIMX_INT;                      /* 定时器x */g_timx_handle.Init.Prescaler = psc;                          /* 分频 */g_timx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */g_timx_handle.Init.Period = arr;                             /* 自动装载值 */HAL_TIM_Base_Init(&g_timx_handle);HAL_TIM_Base_Start_IT(&g_timx_handle);                       /* 使能定时器x和定时器更新中断 */
}/* TIM7初始化函数 */
void btim_tim7_int_init(uint16_t arr, uint16_t psc)
{g_tim7_handle.Instance = BTIM_TIM7_INT;                      /* 定时器x */g_tim7_handle.Init.Prescaler = psc;                          /* 分频 */g_tim7_handle.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */g_tim7_handle.Init.Period = arr;                             /* 自动装载值 */HAL_TIM_Base_Init(&g_tim7_handle);HAL_TIM_Base_Start_IT(&g_tim7_handle);                       /* 使能定时器x和定时器更新中断 */
}
/*** @brief       定时器底层驱动,开启时钟,设置中断优先级此函数会被HAL_TIM_Base_Init()函数调用* @param       无* @retval      无*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if (htim->Instance == BTIM_TIMX_INT){BTIM_TIMX_INT_CLK_ENABLE();                     /* 使能TIMx时钟 */HAL_NVIC_SetPriority(BTIM_TIMX_INT_IRQn, 6, 0); /* 抢占6,子优先级0 */HAL_NVIC_EnableIRQ(BTIM_TIMX_INT_IRQn);         /* 开启ITMx中断 */}if(htim->Instance == BTIM_TIM7_INT){BTIM_TIM7_INT_CLK_ENABLE();                     /* 使能TIM7时钟 */HAL_NVIC_SetPriority(BTIM_TIM7_INT_IRQn, 4, 0); /* 抢占4,子优先级0 */HAL_NVIC_EnableIRQ(BTIM_TIM7_INT_IRQn);         /* 开启ITM7中断 */}
}/*** @brief       基本定时器TIMX中断服务函数* @param       无* @retval      无*/
void BTIM_TIMX_INT_IRQHandler(void)
{HAL_TIM_IRQHandler(&g_timx_handle);  /* 定时器回调函数 */
}/* TIM7中断服务函数 */
void BTIM_TIM7_INT_IRQHandler(void)
{HAL_TIM_IRQHandler(&g_tim7_handle);  /* 定时器回调函数 */
}/*** @brief       回调函数,定时器中断服务函数调用* @param       无* @retval      无*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if (htim->Instance == BTIM_TIMX_INT){printf("TIM6优先级为6的正在运行!!!\r\n");}else if(htim->Instance == BTIM_TIM7_INT){printf("TIM7优先级为4的正在运行!!!!!\r\n");}
}
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{uint8_t task1_num = 0;while(1){if(++task1_num == 5){task1_num = 0;printf("关中断!!\r\n");portDISABLE_INTERRUPTS();delay_ms(5000);printf("开中断!!!\r\n");portENABLE_INTERRUPTS();}vTaskDelay(1000);}
}

四、临界区保护及调度器的挂起和恢复


五、列表项的插入和删除









/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************/List_t          TestList;           /* 定义测试列表 */
ListItem_t      ListItem1;          /* 定义测试列表项1 */
ListItem_t      ListItem2;          /* 定义测试列表项2 */
ListItem_t      ListItem3;          /* 定义测试列表项3 */
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{while(1){LED0_TOGGLE();vTaskDelay(500);}
}/* 任务二,列表项的插入和删除实验 */
void task2( void * pvParameters )
{vListInitialise(&TestList);         /* 初始化列表 */vListInitialiseItem(&ListItem1);    /* 初始化列表项1 */vListInitialiseItem(&ListItem2);    /* 初始化列表项2 */vListInitialiseItem(&ListItem3);    /* 初始化列表项3 */ListItem1.xItemValue = 40;ListItem2.xItemValue = 60;ListItem3.xItemValue = 50;/* 第二步:打印列表和其他列表项的地址 */printf("/**************第二步:打印列表和列表项的地址**************/\r\n");printf("项目\t\t\t地址\r\n");printf("TestList\t\t0x%p\t\r\n", &TestList);printf("TestList->pxIndex\t0x%p\t\r\n", TestList.pxIndex);printf("TestList->xListEnd\t0x%p\t\r\n", (&TestList.xListEnd));printf("ListItem1\t\t0x%p\t\r\n", &ListItem1);printf("ListItem2\t\t0x%p\t\r\n", &ListItem2);printf("ListItem3\t\t0x%p\t\r\n", &ListItem3);printf("/**************************结束***************************/\r\n");printf("\r\n/*****************第三步:列表项1插入列表******************/\r\n");vListInsert((List_t*    )&TestList,         /* 列表 */(ListItem_t*)&ListItem1);       /* 列表项 */printf("项目\t\t\t\t地址\r\n");printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));printf("/**************************结束***************************/\r\n");/* 第四步:列表项2插入列表 */printf("\r\n/*****************第四步:列表项2插入列表******************/\r\n");vListInsert((List_t*    )&TestList,         /* 列表 */(ListItem_t*)&ListItem2);       /* 列表项 */printf("项目\t\t\t\t地址\r\n");printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));printf("/**************************结束***************************/\r\n");/* 第五步:列表项3插入列表 */printf("\r\n/*****************第五步:列表项3插入列表******************/\r\n");vListInsert((List_t*    )&TestList,         /* 列表 */(ListItem_t*)&ListItem3);       /* 列表项 */printf("项目\t\t\t\t地址\r\n");printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));printf("/**************************结束***************************/\r\n");/* 第六步:移除列表项2 */printf("\r\n/*******************第六步:移除列表项2********************/\r\n");uxListRemove((ListItem_t*   )&ListItem2);   /* 移除列表项 */printf("项目\t\t\t\t地址\r\n");printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));printf("/**************************结束***************************/\r\n");/* 第七步:列表末尾添加列表项2 */printf("\r\n/****************第七步:列表末尾添加列表项2****************/\r\n");TestList.pxIndex = &ListItem1;vListInsertEnd((List_t*     )&TestList,     /* 列表 */(ListItem_t* )&ListItem2);   /* 列表项 */printf("项目\t\t\t\t地址\r\n");printf("TestList->pxIndex\t\t0x%p\r\n", TestList.pxIndex);printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));printf("/************************实验结束***************************/\r\n");while(1){vTaskDelay(1000);}
}

六、时间片调度


/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         2
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{uint32_t task1_num = 0;while(1){taskENTER_CRITICAL();               /* 进入临界区 */printf("task1运行次数:%d\r\n",++task1_num);taskEXIT_CRITICAL();                /* 退出临界区 */delay_ms(10);}
}/* 任务二,列表项的插入和删除实验 */
void task2( void * pvParameters )
{uint32_t task2_num = 0;while(1){taskENTER_CRITICAL();               /* 进入临界区 */printf("task2运行次数:%d\r\n",++task2_num);taskEXIT_CRITICAL();                /* 退出临界区 */delay_ms(10);}
}

七、任务状态查询API函数介绍

7.1 任务状态查询API

#include "FreeRTOS.h"
#include "task.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{while(1){LED0_TOGGLE();vTaskDelay(500);}
}char task_buff[500];
/* 任务二,实现任务状态查询API函数使用 */
void task2( void * pvParameters )
{UBaseType_t priority_num = 0;UBaseType_t task_num = 0;UBaseType_t task_num2 = 0;TaskStatus_t * status_array = 0;TaskStatus_t * status_array2 = 0;TaskHandle_t task_handle = 0;UBaseType_t task_stack_min = 0;eTaskState state = 0;uint8_t i = 0;vTaskPrioritySet( task2_handler,4 );priority_num = uxTaskPriorityGet( NULL );printf("task2任务优先级为%ld\r\n",priority_num);task_num = uxTaskGetNumberOfTasks();printf("任务数量:%ld\r\n",task_num);status_array = mymalloc(SRAMIN,(sizeof(TaskStatus_t) * task_num));task_num2 = uxTaskGetSystemState( status_array,task_num,NULL);printf("任务名\t\t任务优先级\t任务编号\r\n");for(i = 0; i < task_num2; i++){printf("%s\t\t%ld\t%ld\r\n",status_array[i].pcTaskName,status_array[i].uxCurrentPriority,status_array[i].xTaskNumber);}status_array2 = mymalloc(SRAMIN,sizeof(TaskStatus_t));vTaskGetInfo( task2_handler,status_array2,pdTRUE,eInvalid);printf("任务名:%s\r\n",status_array2->pcTaskName);printf("任务优先级:%ld\r\n",status_array2->uxCurrentPriority);printf("任务编号:%ld\r\n",status_array2->xTaskNumber);printf("任务状态:%d\r\n",status_array2->eCurrentState);task_handle = xTaskGetHandle( "task1" );printf("任务句柄:%#x\r\n",(int)task_handle);printf("task1的任务句柄:%#x\r\n",(int)task1_handler);state = eTaskGetState( task2_handler );printf("当前task2的任务状态为:%d\r\n",state);vTaskList( task_buff );printf("%s\r\n",task_buff);while(1){
//        task_stack_min = uxTaskGetStackHighWaterMark( task2_handler );
//        printf("task2历史剩余最小堆栈为%ld\r\n",task_stack_min);vTaskDelay(1000);}
}

7.2 任务运行时间统计API



/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{while(1){LED0_TOGGLE();vTaskDelay(500);}
}char task_buff[500];
/* 任务二,实现任务运行时间统计API函数的使用 */
void task2( void * pvParameters )
{uint8_t key = 0;while(1){key = key_scan(0);if(key == KEY0_PRES){vTaskGetRunTimeStats(task_buff);printf("%s\r\n",task_buff);}vTaskDelay(10);}
}

八、时间管理


/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         5
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,演示相对延时函数 */
void task1( void * pvParameters )
{while(1){LED0_TOGGLE();      /* PB1 */delay_ms(20);vTaskDelay(500);}
}/* 任务二,演示绝对延时函数 */
void task2( void * pvParameters )
{TickType_t xLastWakeTime;xLastWakeTime = xTaskGetTickCount();while(1){LED1_TOGGLE();      /* PB0 */delay_ms(20);vTaskDelayUntil(&xLastWakeTime,500);}
}

九、队列














/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   128
TaskHandle_t    task3_handler;
void task3( void * pvParameters );
/******************************************************************************************************/
QueueHandle_t key_queue;        /* 小数据句柄 */
QueueHandle_t big_date_queue;   /* 大数据句柄 */
char buff[100] = {"我是一个大数组,大大的数组 124214 uhsidhaksjhdklsadhsaklj"};
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    /* 队列的创建 */key_queue = xQueueCreate( 2, sizeof(uint8_t) );if(key_queue != NULL){printf("key_queue队列创建成功!!\r\n");}else printf("key_queue队列创建失败!!\r\n");big_date_queue = xQueueCreate( 1, sizeof(char *) );if(big_date_queue != NULL){printf("big_date_queue队列创建成功!!\r\n");}else printf("big_date_queue队列创建失败!!\r\n");xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );xTaskCreate((TaskFunction_t         )   task3,(char *                 )   "task3",(configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK3_PRIO,(TaskHandle_t *         )   &task3_handler );                vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现入队 */
void task1( void * pvParameters )
{uint8_t key = 0;char * buf;BaseType_t   err = 0;buf = &buff[0]; /* buf = &buff[0] */while(1) {key = key_scan(0);if(key == KEY0_PRES || key == KEY1_PRES){err = xQueueSend( key_queue, &key, portMAX_DELAY );if(err != pdTRUE){printf("key_queue队列发送失败\r\n");}}else if(key == WKUP_PRES){err = xQueueSend( big_date_queue, &buf, portMAX_DELAY );if(err != pdTRUE){printf("key_queue队列发送失败\r\n");}}vTaskDelay(10);}
}/* 任务二,小数据出队 */
void task2( void * pvParameters )
{uint8_t key = 0;BaseType_t err = 0;while(1){err = xQueueReceive( key_queue,&key,portMAX_DELAY);if(err != pdTRUE){printf("key_queue队列读取失败\r\n");}else {printf("key_queue读取队列成功,数据:%d\r\n",key);}}
}/* 任务三,大数据出队 */
void task3( void * pvParameters )
{char * buf;BaseType_t err = 0;while(1){err = xQueueReceive( big_date_queue,&buf,portMAX_DELAY);if(err != pdTRUE){printf("big_date_queue队列读取失败\r\n");}else {printf("数据:%s\r\n",buf);}}
}

十、信号量

10.1 二值信号量







/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
QueueHandle_t semphore_handle;
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    semphore_handle = xSemaphoreCreateBinary();if(semphore_handle != NULL){printf("二值信号量创建成功!!!\r\n");}xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,释放二值信号量 */
void task1( void * pvParameters )
{uint8_t key = 0;BaseType_t err;while(1) {key = key_scan(0);if(key == KEY0_PRES){if(semphore_handle != NULL){err = xSemaphoreGive(semphore_handle);if(err == pdPASS){printf("信号量释放成功!!\r\n");}else printf("信号量释放失败!!\r\n");}}vTaskDelay(10);}
}/* 任务二,获取二值信号量 */
void task2( void * pvParameters )
{uint32_t i = 0;BaseType_t err;while(1){err = xSemaphoreTake(semphore_handle,portMAX_DELAY); /* 获取信号量并死等 */if(err == pdTRUE){printf("获取信号量成功\r\n");}else printf("已超时%d\r\n",++i);}
}

10.2 计数型信号量




/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
QueueHandle_t count_semphore_handle;
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    count_semphore_handle = xSemaphoreCreateCounting(100 , 0);  /* 创建计数型信号量 */if(count_semphore_handle != NULL){printf("计数型信号量创建成功!!!\r\n");}xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,释放计数型信号量 */
void task1( void * pvParameters )
{uint8_t key = 0;while(1) {key = key_scan(0);if(key == KEY0_PRES){if(count_semphore_handle != NULL){xSemaphoreGive(count_semphore_handle);      /* 释放信号量 */}}vTaskDelay(10);}
}/* 任务二,获取计数型信号量 */
void task2( void * pvParameters )
{BaseType_t err = 0;while(1){err = xSemaphoreTake(count_semphore_handle,portMAX_DELAY); /* 获取信号量并死等 */if(err == pdTRUE){printf("信号量的计数值为:%d\r\n",(int)uxSemaphoreGetCount(count_semphore_handle));}vTaskDelay(1000);}
}

10.3 优先级翻转

/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    low_task_handler;
void low_task( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    middle_task_handler;
void middle_task( void * pvParameters );/* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   128
TaskHandle_t    high_task_handler;
void high_task( void * pvParameters );/******************************************************************************************************/
QueueHandle_t semphore_handle;
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    semphore_handle = xSemaphoreCreateBinary();if(semphore_handle != NULL){printf("二值信号量创建成功!!!\r\n");}xSemaphoreGive(semphore_handle);        /* 释放一次信号量 */xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   low_task,(char *                 )   "low_task",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &low_task_handler );xTaskCreate((TaskFunction_t         )   middle_task,(char *                 )   "middle_task",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &middle_task_handler );xTaskCreate((TaskFunction_t         )   high_task,(char *                 )   "high_task",(configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK3_PRIO,(TaskHandle_t *         )   &high_task_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,低优先级任务 */
void low_task( void * pvParameters )
{while(1) {printf("low_task获取信号量\r\n");xSemaphoreTake(semphore_handle,portMAX_DELAY);printf("low_task正在运行!!!\r\n");delay_ms(3000);printf("low_task释放信号量\r\n");xSemaphoreGive(semphore_handle); vTaskDelay(1000);}
}/* 任务二,中优先级任务 */
void middle_task( void * pvParameters )
{while(1){printf("middle_task正在运行!!!\r\n");vTaskDelay(1000);}
}/* 任务三,高优先级任务 */
void high_task( void * pvParameters )
{while(1){printf("high_task获取信号量\r\n");xSemaphoreTake(semphore_handle,portMAX_DELAY);printf("high_task正在运行!!!\r\n");delay_ms(1000);printf("high_task释放信号量\r\n");xSemaphoreGive(semphore_handle); vTaskDelay(1000);}
}

10.4 互斥信号量






/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    low_task_handler;
void low_task( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    middle_task_handler;
void middle_task( void * pvParameters );/* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   128
TaskHandle_t    high_task_handler;
void high_task( void * pvParameters );/******************************************************************************************************/
QueueHandle_t mutex_semphore_handle;
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    mutex_semphore_handle = xSemaphoreCreateMutex();    /* 创建互斥信号量,并且主动释放一次信号量 */if(mutex_semphore_handle != NULL){printf("互斥信号量创建成功!!!\r\n");}xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   low_task,(char *                 )   "low_task",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &low_task_handler );xTaskCreate((TaskFunction_t         )   middle_task,(char *                 )   "middle_task",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &middle_task_handler );xTaskCreate((TaskFunction_t         )   high_task,(char *                 )   "high_task",(configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK3_PRIO,(TaskHandle_t *         )   &high_task_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,低优先级任务 */
void low_task( void * pvParameters )
{while(1) {printf("low_task获取信号量\r\n");xSemaphoreTake(mutex_semphore_handle,portMAX_DELAY);printf("low_task正在运行!!!\r\n");delay_ms(3000);printf("low_task释放信号量\r\n");xSemaphoreGive(mutex_semphore_handle); vTaskDelay(1000);}
}/* 任务二,中优先级任务 */
void middle_task( void * pvParameters )
{while(1){printf("middle_task正在运行!!!\r\n");vTaskDelay(1000);}
}/* 任务三,高优先级任务 */
void high_task( void * pvParameters )
{while(1){printf("high_task获取信号量\r\n");xSemaphoreTake(mutex_semphore_handle,portMAX_DELAY);printf("high_task正在运行!!!\r\n");delay_ms(1000);printf("high_task释放信号量\r\n");xSemaphoreGive(mutex_semphore_handle); vTaskDelay(1000);}
}

十一、队列集



/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
QueueSetHandle_t queueset_handle;
QueueHandle_t    queue_handle;
QueueHandle_t    semphr_handle;
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();                               /* 进入临界区 */queueset_handle = xQueueCreateSet( 2 );             /* 创建队列集,可以存放2个队列 */if(queueset_handle != NULL){printf("队列集创建成功!!\r\n");}queue_handle = xQueueCreate( 1, sizeof(uint8_t) );  /* 创建队列 */ semphr_handle = xSemaphoreCreateBinary();           /* 创建二值信号量 */xQueueAddToSet( queue_handle,queueset_handle);xQueueAddToSet( semphr_handle,queueset_handle);xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,实现队列发送以及信号量释放 */
void task1( void * pvParameters )
{uint8_t key = 0;BaseType_t err = 0;while(1) {key = key_scan(0);if(key == KEY0_PRES){err = xQueueSend( queue_handle, &key, portMAX_DELAY );if(err == pdPASS){printf("往队列queue_handle写入数据成功!!\r\n");}}else if(key == KEY1_PRES){err = xSemaphoreGive(semphr_handle);if(err == pdPASS){printf("释放信号量成功!!\r\n");}}vTaskDelay(10);}
}/* 任务二,获取队列集的消息 */
void task2( void * pvParameters )
{QueueSetMemberHandle_t member_handle;uint8_t key;while(1){member_handle = xQueueSelectFromSet( queueset_handle,portMAX_DELAY);if(member_handle == queue_handle){xQueueReceive( member_handle,&key,portMAX_DELAY);printf("获取到的队列数据为:%d\r\n",key);}else if(member_handle == semphr_handle){xSemaphoreTake( member_handle, portMAX_DELAY );printf("获取信号量成功!!\r\n");}}
}

十二、事件标志组





/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
EventGroupHandle_t  eventgroup_handle;
#define EVENTBIT_0  (1 << 0)
#define EVENTBIT_1  (1 << 1)
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */eventgroup_handle = xEventGroupCreate();if(eventgroup_handle != NULL){printf("事件标志组创建成功!!\r\n");}xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,释放二值信号量 */
void task1( void * pvParameters )
{uint8_t key = 0;while(1) {key = key_scan(0);if(key == KEY0_PRES){xEventGroupSetBits( eventgroup_handle, EVENTBIT_0); /* 将事件标志组的bit0位置1 */}else if(key == KEY1_PRES){xEventGroupSetBits( eventgroup_handle, EVENTBIT_1); /* 将事件标志组的bit1位置1 */}vTaskDelay(10);}
}/* 任务二,获取二值信号量 */
void task2( void * pvParameters )
{EventBits_t event_bit = 0;while(1){event_bit = xEventGroupWaitBits( eventgroup_handle,         /* 事件标志组句柄 */EVENTBIT_0 | EVENTBIT_1,   /* 等待事件标志组的bit0和bit1位 */pdTRUE,                    /* 成功等待到事件标志位后,清除事件标志组中的bit0和bit1位 */pdTRUE,                    /* 等待事件标志组的bit0和bit1位都置1,就成立 */portMAX_DELAY );           /* 死等 */printf("等待到的事件标志位值为:%#x\r\n",event_bit);}
}

十三、任务通知














13.1 任务通知模拟二值信号量和计数型信号量

/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,发送任务通知值 */
void task1( void * pvParameters )
{uint8_t key = 0;while(1) {key = key_scan(0);if(key == KEY0_PRES){printf("任务通知模拟二值信号量释放!\r\n");xTaskNotifyGive(task2_handler);}vTaskDelay(10);}
}/* 任务二,接收任务通知值 */
void task2( void * pvParameters )
{uint32_t rev = 0;while(1){rev = ulTaskNotifyTake(pdTRUE , portMAX_DELAY);if(rev != 0){printf("接收任务通知成功,模拟获取二值信号量!\r\n");}}
}
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,发送任务通知值 */
void task1( void * pvParameters )
{uint8_t key = 0;while(1) {key = key_scan(0);if(key == KEY0_PRES){printf("任务通知模拟计数型信号量释放!\r\n");xTaskNotifyGive(task2_handler);}vTaskDelay(10);}
}/* 任务二,接收任务通知值 */
void task2( void * pvParameters )
{uint32_t rev = 0;while(1){rev = ulTaskNotifyTake(pdFALSE , portMAX_DELAY);if(rev != 0){printf("rev:%d\r\n",rev);}vTaskDelay(1000);}
}

13.2 任务通知模拟消息邮箱

/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,发送任务通知值 */
void task1( void * pvParameters )
{uint8_t key = 0;while(1) {key = key_scan(0);if((key != 0) && (task2_handler != NULL)){printf("任务通知模拟消息邮箱发送,发送的键值为:%d\r\n",key);xTaskNotify( task2_handler, key, eSetValueWithOverwrite );}vTaskDelay(10);}
}/* 任务二,接收任务通知值 */
void task2( void * pvParameters )
{uint32_t noyify_val = 0;while(1){xTaskNotifyWait( 0, 0xFFFFFFFF, &noyify_val, portMAX_DELAY );switch(noyify_val){case KEY0_PRES:{printf("接收到的通知值为:%d\r\n",noyify_val);LED0_TOGGLE();break;}case KEY1_PRES:{printf("接收到的通知值为:%d\r\n",noyify_val);LED1_TOGGLE();break;}default : break;}}
}

13.3 任务通知模拟事件标志组

/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
#define EVENTBIT_0  (1 << 0)
#define EVENTBIT_1  (1 << 1)
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,发送任务通知值*/
void task1( void * pvParameters )
{uint8_t key = 0;while(1) {key = key_scan(0);if(key == KEY0_PRES){printf("将bit0位置1\r\n");xTaskNotify( task2_handler, EVENTBIT_0, eSetBits );}else if(key == KEY1_PRES){printf("将bit1位置1\r\n");xTaskNotify( task2_handler, EVENTBIT_1, eSetBits );}vTaskDelay(10);}
}/* 任务二,接收任务通知值 */
void task2( void * pvParameters )
{uint32_t notify_val = 0,event_bit = 0;while(1){xTaskNotifyWait( 0, 0xFFFFFFFF, &notify_val, portMAX_DELAY );if(notify_val & EVENTBIT_0){event_bit |= EVENTBIT_0;}if(notify_val & EVENTBIT_1){event_bit |= EVENTBIT_1;}if(event_bit == (EVENTBIT_0|EVENTBIT_1)){printf("任务通知模拟事件标志组接收成功!!\r\n");event_bit = 0;}}
}

十四、软件定时器












/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );void timer1_callback( TimerHandle_t pxTimer );
void timer2_callback( TimerHandle_t pxTimer );
/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}TimerHandle_t timer1_handle = 0;    /* 单次定时器 */
TimerHandle_t timer2_handle = 0;    /* 周期定时器 */void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 *//* 单次定时器 */timer1_handle = xTimerCreate( "timer1", 500,pdFALSE,(void *)1,timer1_callback );/* 周期定时器 */timer2_handle = xTimerCreate( "timer2", 2000,pdTRUE,(void *)2,timer2_callback );xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,按键扫描并控制软件定时器 */
void task1( void * pvParameters )
{uint8_t key = 0;while(1) {key = key_scan(0);if(key == KEY0_PRES){xTimerStart(timer1_handle,portMAX_DELAY);xTimerStart(timer2_handle,portMAX_DELAY);}else if(key == KEY1_PRES){xTimerStop(timer1_handle,portMAX_DELAY);xTimerStop(timer2_handle,portMAX_DELAY);}vTaskDelay(10);}
}/* timer1的超时回调函数 */
void timer1_callback( TimerHandle_t pxTimer )
{static uint32_t timer = 0;printf("timer1的运行次数:%d\r\n",++timer);
}/* timer2的超时回调函数 */
void timer2_callback( TimerHandle_t pxTimer )
{static uint32_t timer = 0;printf("timer2的运行次数:%d\r\n",++timer);
}

十五、低功耗Tickless模式




/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );/******************************************************************************************************/
QueueHandle_t semphore_handle;
/* 进入低功耗前所需要执行的操作 */
void PRE_SLEEP_PROCESSING(void)
{__HAL_RCC_GPIOA_CLK_DISABLE();__HAL_RCC_GPIOB_CLK_DISABLE();__HAL_RCC_GPIOC_CLK_DISABLE();__HAL_RCC_GPIOD_CLK_DISABLE();__HAL_RCC_GPIOE_CLK_DISABLE();__HAL_RCC_GPIOF_CLK_DISABLE();__HAL_RCC_GPIOG_CLK_DISABLE();
}
/* 退出低功耗后所需要执行的操作 */
void POST_SLEEP_PROCESSING(void)
{__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOE_CLK_ENABLE();__HAL_RCC_GPIOF_CLK_ENABLE();__HAL_RCC_GPIOG_CLK_ENABLE();
}
/*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    semphore_handle = xSemaphoreCreateBinary();if(semphore_handle != NULL){printf("二值信号量创建成功!!!\r\n");}xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );xTaskCreate((TaskFunction_t         )   task2,(char *                 )   "task2",(configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK2_PRIO,(TaskHandle_t *         )   &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,释放二值信号量 */
void task1( void * pvParameters )
{uint8_t key = 0;BaseType_t err;while(1) {key = key_scan(0);if(key == KEY0_PRES){if(semphore_handle != NULL){err = xSemaphoreGive(semphore_handle);if(err == pdPASS){printf("信号量释放成功!!\r\n");}else printf("信号量释放失败!!\r\n");}}vTaskDelay(10);}
}/* 任务二,获取二值信号量 */
void task2( void * pvParameters )
{uint32_t i = 0;BaseType_t err;while(1){err = xSemaphoreTake(semphore_handle,portMAX_DELAY); /* 获取信号量并死等 */if(err == pdTRUE){printf("获取信号量成功\r\n");}else printf("已超时%d\r\n",++i);}
}

十六、内存管理












/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );/******************************************************************************************************//*** @brief       FreeRTOS例程入口函数* @param       无* @retval      无*/
void freertos_demo(void)
{    xTaskCreate((TaskFunction_t         )   start_task,(char *                 )   "start_task",(configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   START_TASK_PRIO,(TaskHandle_t *         )   &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL();               /* 进入临界区 */xTaskCreate((TaskFunction_t         )   task1,(char *                 )   "task1",(configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,(void *                 )   NULL,(UBaseType_t            )   TASK1_PRIO,(TaskHandle_t *         )   &task1_handler );vTaskDelete(NULL);taskEXIT_CRITICAL();                /* 退出临界区 */
}/* 任务一,申请内存以及释放内存,并显示空闲内存大小 */
void task1( void * pvParameters )
{uint8_t key = 0, t = 0;uint8_t * buf = NULL;while(1) {key = key_scan(0);if(key == KEY0_PRES){buf = pvPortMalloc(30);                 /* 申请内存 */if(buf != NULL){printf("申请内存成功!\r\n");}else printf("申请内存失败\r\n");}else if(key == KEY1_PRES){if(buf != NULL){vPortFree(buf);                     /* 释放内存 */printf("释放内存!!\r\n");}                }if(t++ > 50){t = 0;printf("剩余的空闲内存大小为:%d\r\n",xPortGetFreeHeapSize());}vTaskDelay(10);}
}
发布评论

评论列表(0)

  1. 暂无评论