FreeRTOS 定时器中断内存CPU
Posted 为了维护世界和平_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FreeRTOS 定时器中断内存CPU相关的知识,希望对你有一定的参考价值。
一、定时器任务
创建定时器
TimerHandle_t xTimerCreate( const char * const pcTimerName,//定时器名
const TickType_t xTimerPeriodInTicks,//定时周期
const UBaseType_t uxAutoReload,//周期模式
void * const pvTimerID,//ID
TimerCallbackFunction_t pxCallbackFunction )//回调函数
启动定时器
xTimerStart()
启动定时器(中断)
xTimerStartFromISR()
关闭定时器
xTimerStop()
关闭定时器(中断)
xTimerStopFromISR()
实例
static TimerHandle_t Swtmr1_Handle =NULL; /* */
static uint32_t TmrCb_Count1 = 0; /* 回调函数调用次数 */
static void AppTaskCreate(void)
taskENTER_CRITICAL();
Swtmr1_Handle=xTimerCreate((const char* )"AutoReloadTimer",
(TickType_t )1000,/*定时周期 */
(UBaseType_t )pdTRUE,/* 周期模式*/
(void* )1,/*定时任务ID 唯一 */
(TimerCallbackFunction_t)Swtmr1_Callback); //回调函数
if(Swtmr1_Handle != NULL)
xTimerStart(Swtmr1_Handle,0);
vTaskDelete(AppTaskCreate_Handle);
taskEXIT_CRITICAL();
//回调函数
static void Swtmr1_Callback(void* parameter)
TickType_t tick_num1;
TmrCb_Count1++;
tick_num1 = xTaskGetTickCount(); /* 获取滴答计数器值 */
printf("Swtmr1_Callback函数计数 %d ´Î\\n", TmrCb_Count1);
printf("滴答计数=%d\\n", tick_num1);
二、内存管理
FreeRTOS 的 V9.0.0 提供了 5 种内存管理算法,分别是 heap_1.c、heap_2.c、heap_3.c、heap_4.c、heap_5.c,源文件存放于MemMang 路径下,选择其中一个添加到我们的工程中即可
内存管理模块通过对内存的申请、释放操作,来管理用户和系统对内存的使用,使内存的利用率和使用效率达到最优,同时最大限度地解决系统可能产生的内存碎片问题。
内存管理方案详解
文件 | 说明 |
---|---|
heap_1.c | 只能申请不能释放,申请内存的时间是一个常量;没有释放,不会产生内存碎片;内存利用率不高 |
heap_2.c | 支持释放内存,采用最佳匹配算法,在空闲内存中找到合适申请大小的空间,不能把两个小的内存合并成一个大的内存块,容易产生碎片 |
heap_3.c | 简单封装了C库中的malloc,free函数,操作内存前挂起调度器、完成后再恢复调度器 |
heap_4.c | 最佳匹配和合并算法,空闲块以单链表的形式连接起来,可作为有先选择使用 |
heap_5.c | 最佳匹配和合并算法,允许跨多个非连续的内存区(多个物理内存) |
获取当前内存大小xPortGetFreeHeapSize()
申请内存pvPortMalloc( size_t xWantedSize );
释放内存vPortFree()
uint8_t *Test_Ptr = NULL;
uint32_t g_memsize;
//获取系统内存
g_memsize = xPortGetFreeHeapSize();
printf("系统内存大小\\n",g_memsize);
//申请内存1024
Test_Ptr = pvPortMalloc(1024);
//向内存中写数据
sprintf((char*)Test_Ptr,"TickCount = %d \\n",xTaskGetTickCount());
printf("%s \\n",(char*)Test_Ptr);
三、中断管理
在中断中使用
void KEY1_IRQHandler(void)
BaseType_t pxHigherPriorityTaskWoken;
uint32_t ulReturn;
/* 进入临界段 ,可以嵌套(被另外的中断打断)*/
ulReturn = taskENTER_CRITICAL_FROM_ISR();
if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET)
/*将数据写入队列中,等待时间0 */
xQueueSendFromISR(Test_Queue, /*消息队列句柄 */
&send_data1,/* 发送消息内容*/
&pxHigherPriorityTaskWoken);
//如果需要进行一次任务切换
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
//清除中断标志位
EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
//退出临界段
taskEXIT_CRITICAL_FROM_ISR( ulReturn );
四、CPU使用率统计
输出系统中的每个任务占用 CPU 的时间,从而得知系统设计的是否合理
static void CPU_Task(void* parameter)
uint8_t CPU_RunInfo[400]; //任务运行时间信息
while (1)
memset(CPU_RunInfo,0,400);
vTaskList((char *)&CPU_RunInfo); //获取任务运行时间信息
printf("---------------------------------------------\\r\\n");
printf("任务名 任务状态 优先级 剩余栈 任务序号\\r\\n");
printf("%s", CPU_RunInfo);
printf("---------------------------------------------\\r\\n");
memset(CPU_RunInfo,0,400);
vTaskGetRunTimeStats((char *)&CPU_RunInfo);
printf("任务名 运行计数 利用率\\r\\n");
printf("%s", CPU_RunInfo);
printf("---------------------------------------------\\r\\n\\n");
vTaskDelay(1000);
串口输出
---------------------------------------------
任务名 任务状态 优先级 剩余栈 任务序号
CPU_Task R 4 361 5
IDLE R 0 106 2
LED2_Task B 3 468 4
LED1_Task B 2 460 3
---------------------------------------------
任务名 运行计数 利用率
CPU_Task 354 3%
LED1_Task 47 <1%
IDLE 8854 95%
LED2_Task 90 <1%
---------------------------------------------
以上是关于FreeRTOS 定时器中断内存CPU的主要内容,如果未能解决你的问题,请参考以下文章
原子STM32带freeRTOS程序使用Timer3定时器时持续进入中断的问题解决
原子STM32带freeRTOS程序使用Timer3定时器时持续进入中断的问题解决