IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> <FreeRTOS入门第十一节>空闲函数和钩子函数 -> 正文阅读

[嵌入式]<FreeRTOS入门第十一节>空闲函数和钩子函数

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

今天学习了空闲函数和钩子函数感觉很不错


一、空闲函数是什么?

就是在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__ //printf重定向
#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);
		//printf("NUM=%d\r\n",num);
		
			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)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif /* USE_FULL_ASSERT */


总结

空闲函数就是这么简单,好了差不多要入门FreeRTOS的操作系统了。嘿嘿。
春风得意马蹄疾,一日看尽长安花

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:22:30  更:2022-08-19 19:26:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 12:25:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码