提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
今天学习了空闲函数和钩子函数感觉很不错
一、空闲函数是什么?
就是在FreeRTOS系统运行时主要任务不处理时进行的一个闲的蛋疼的任务, 同时我们可以在空闲函数里面进入低功耗模式来降低单片机的功耗
二、相关API介绍
1.空闲函数环境搭建
只需要打开和关闭下面的宏定义
2.相关API介绍
这里其实只需要重写一个函数就行,这个函数就是空闲任务执行的事情。 重写 vApplicationIdleHook();函数
void vApplicationIdleHook(void){
flag_task1=0;
flag_task2=0;
flag_task3=0;
flag_IDLE=1;
__disable_irq();
__dsb(portSY_FULL_READ_WRITE);
__isb(portSY_FULL_READ_WRITE);
Free_PreSleepProcessing();
__wfi();
Free_PostSleepProcessing();
__dsb(portSY_FULL_READ_WRITE);
__isb(portSY_FULL_READ_WRITE);
__enable_irq();
}
3.案例
空闲函数里面进入低功耗,关闭时钟。
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "Timers.h"
#include "event_groups.h"
#include "stdio.h"
#include "Key.h"
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch,1,HAL_MAX_DELAY);
return ch;
}
TaskHandle_t HandlerTask1;
TaskHandle_t Task_Name4;
BaseType_t xReturn;
SemaphoreHandle_t Task1semaphore;
TimerHandle_t AutoTimerTask;
TimerHandle_t OneTimerTask;
SemaphoreHandle_t semaphoreTask;
void SystemClock_Config(void);
StackType_t xTask3Static[128];
StaticTask_t xTaskTCB;
StackType_t xIdle3Static[128];
StaticTask_t xIdleTCB;
StackType_t xTimerStatic[526];
StaticTask_t xTimerTCB;
uint8_t flag_task1=0;
uint8_t flag_task2=0;
uint8_t flag_task3=0;
uint8_t flag_IDLE=0;
void Free_PreSleepProcessing(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();
}
void Free_PostSleepProcessing(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();
}
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize ){
*ppxIdleTaskTCBBuffer=&xIdleTCB;
*ppxIdleTaskStackBuffer=xIdle3Static;
*pulIdleTaskStackSize=128;
}
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize ){
* ppxTimerTaskTCBBuffer=&xTimerTCB;
* ppxTimerTaskStackBuffer=xTimerStatic;
* pulTimerTaskStackSize=526;
}
void vApplicationIdleHook(void){
flag_task1=0;
flag_task2=0;
flag_task3=0;
flag_IDLE=1;
__disable_irq();
__dsb(portSY_FULL_READ_WRITE);
__isb(portSY_FULL_READ_WRITE);
Free_PreSleepProcessing();
__wfi();
Free_PostSleepProcessing();
__dsb(portSY_FULL_READ_WRITE);
__isb(portSY_FULL_READ_WRITE);
__enable_irq();
}
void Task1Function( void * param){
flag_task1=1;
flag_task2=0;
flag_task3=0;
flag_IDLE=0;
for(;;){
printf("TASK1..\r\n");
vTaskDelay(10);
}
}
void Task2Function(void* param){
flag_task1=0;
flag_task2=1;
flag_task3=0;
flag_IDLE=0;
int num;
BaseType_t err;
for(;;)
{
xSemaphoreGive(semaphoreTask);
err=xSemaphoreTake(semaphoreTask,0);
num =atoi(Rxbuff);
if(num==1){
printf("NUM=%d\r\n",num);
vTaskDelay(1000);
}
vTaskDelay(10);
}
}
void Task3Funtion(void* param){
flag_task1=0;
flag_task2=0;
flag_task3=1;
flag_IDLE=0;
TickType_t st_time=xTaskGetTickCount();
while(1){
uint32_t num =1;
xTaskDelayUntil(&st_time,30);
}
}
void Task4Funtion(void* param){
taskENTER_CRITICAL();
semaphoreTask=xSemaphoreCreateBinary();
xReturn=xTaskCreate(Task1Function,"Task1",128,NULL,2,&HandlerTask1);
xTaskCreate(Task2Function,"Task2",128,NULL,2,NULL);
xTaskCreateStatic(Task3Funtion,"Task3",128,NULL,2,xTask3Static,&xTaskTCB);
if(xReturn == pdPASS){
uint8_t buffS[20]="Task1 Create OK..\r\n";
HAL_UART_Transmit(&huart1,(uint8_t*)buffS,strlen(buffS)*sizeof(char),HAL_MAX_DELAY);
}
vTaskDelete(Task_Name4);
taskEXIT_CRITICAL();
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
xTaskCreate(Task4Funtion,"Task4",600,NULL,1,&Task_Name4);
vTaskStartScheduler();
while (1)
{
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif
总结
空闲函数就是这么简单,好了差不多要入门FreeRTOS的操作系统了。嘿嘿。 春风得意马蹄疾,一日看尽长安花
|