freertos学习
freertos的基本框架如下
注意有三点很重要:
1.任务的资源
(1)任务优先级:freertos 能够调度的任务优先级在freertosConfig.h中的configMAX_PRIORITIES中定义,每一个任务的优先级都在0~configMAX_PRIORITIES -1 中取值 优先级是数值越小,优先级越小,空闲任务的优先级为0.高优先级的任务必须有延时,低优先级的任务才能获得人物使用权。
任务优先级在定义时,可参考以下的规则:
① IRQ 任务:IRQ 任务是指通过中断服务程序进行触发的任务,此类任务应该设置为所有任务里面优先级最高的。
② 高优先级后台任务:比如按键检测,触摸检测,USB 消息处理,串口消息处理等,都可以归为这一类任务。
③ 低优先级的时间片调度任务:比如 emWin 的界面显示,LED 数码管的显示等不需要实时执行的都可以归为这一类任务。 实际应用中用户不必拘泥于将这些任务都设置为优先级 1 的同优先级任务,可以设置多个优先级,只需注意这类任务不需要高实时性。
(2)任务栈的大小:在freertosConfig.h中定义了一个总的堆栈的大小configTOTAL_HEAP_SIZE。如何这个值不够使用的话可以增大这个值。每个任务的栈都是特别要注意的。如果任务出现不运行,很大可能是任务栈不够用了。在freertos中有一个API可以获取在程序运行到现在,栈的接近历史最高水平线的值。我们需要在配置头文件将宏configCHECK_FOR_STACK_OVERFLOW 打开,这宏可定义为两个值1或者2,这两个值有着不同的检测方法,这两个方法不在赘叙。我们还需要调用任务栈溢出的时候,将溢出的任务的名字打印出来,或者进行其他处理。
2.线程间的通讯
(1)信号量 :二值信号量、计数信号量、互斥信号量。在多个任务等待同一个信号量来进行同步时,当这些任务优先级相等时,他们依次交叉获取 ,当这些任务优先级不同时,就会只有高优先级的任务会获取。
(2)队列:注意取队列的速度和发送队列的速度,与他们的等待时长。注意判断返回值
(3)事件组:事件组相当于一个软件寄存器,每一位都有一个标志。常用于当一个任务同时满足多个条件(与的关系)或者满足多个条件的某一个条件(或的关系)时使用。
3.所有的API都要注意是不是在中断中调用。
其他:软件定时器:本质上就是队列,需要自己注册定时到后的回调函数。
#include "mytask.h"
#include "task.h"
#include "timers.h" /* TASK HANDLERS */
TaskHandle_t startHandle;
TaskHandle_t ledHandle;
TaskHandle_t printfHandle;
TaskHandle_t writeQueueHandle;
TaskHandle_t SemaphoreBinaryHandle;
TaskHandle_t eventgrupHandle;
TimerHandle_t timer;
/* TASK INPUT VARIABLES */
u32 led_params = ;
char *databuf = "hello world";
u8 queue_buff[];
u8 TIMER_ID = ;
/* thread commutication variables */
xQueueHandle myqueue;
xSemaphoreHandle semphorebinary;
EventGroupHandle_t eventgroup;
/* task status */
portBASE_TYPE status; void start_task(void *param)
{
printf("start task\r\n"); myqueue = xQueueCreate(,*sizeof(char)); vSemaphoreCreateBinary(semphorebinary);
timer = xTimerCreate("timer test",/portTICK_PERIOD_MS,pdTRUE,(void*)&TIMER_ID,AutoReloadTimer_Handle_callback);
eventgroup = xEventGroupCreate(); taskENTER_CRITICAL();
xTaskCreate(led_task,"led task",START_STA_SIZE,(void*)&led_params,LED_TASK_PRTO,ledHandle);
xTaskCreate(printf_task,"printf task",PRINTF_STA_SIZE,(void *)databuf,PRTINF_TASK_PRIO,printfHandle);
xTaskCreate(writeQueue_task,"write queue task",WRITEQUEUE_STA_SIZE,NULL,WRITEQUEUE_TASK_PRIO,writeQueueHandle);
xTaskCreate(SemaphoreBinary_task,"xsemphorebinary task",BINARY_STA_SIZE,NULL,PRTINF_TASK_PRIO,SemaphoreBinaryHandle);
xTaskCreate(eventgrup_task,"eventgrup task",EVENT_STA_SIZE,NULL,EVENT_TASK_PRIO,eventgroup);
taskEXIT_CRITICAL();
//xTimerStart(timer,0);
vTaskDelete(NULL);
} void led_task(void*param)
{ while()
{ HAL_GPIO_WritePin(GPIOJ,GPIO_PIN_13,GPIO_PIN_SET); //PB1置1
HAL_GPIO_WritePin(GPIOJ,GPIO_PIN_5, GPIO_PIN_RESET); //PB1置1
vTaskDelay(*(u32*)param);
HAL_GPIO_WritePin(GPIOJ,GPIO_PIN_13,GPIO_PIN_RESET); //PB1置1
HAL_GPIO_WritePin(GPIOJ,GPIO_PIN_5, GPIO_PIN_SET); //PB1置1
vTaskDelay(*(u32*)param);
xEventGroupSetBits(eventgroup,0x1);
} } void printf_task(void*param)
{
while()
{
status = xQueueReceive(myqueue,queue_buff,portMAX_DELAY);
if(status == pdPASS)
{
taskENTER_CRITICAL();
printf("%s\r\n",queue_buff); taskEXIT_CRITICAL();
}
else printf("queue null \r\n");
vTaskDelay();
}
} void writeQueue_task(void *param)
{
u8 i =;
while()
{
status = xQueueSend(myqueue,queue_buff,);
if(status!= pdPASS) printf("queue full\r\n");
i++;
if(!(i%))
{
// xSemaphoreTake(semphorebinary,portMAX_DELAY);
// printf("get once baniry\r\n");
xEventGroupSetBits(eventgroup,0x4);
}
vTaskDelay();
}
} void SemaphoreBinary_task(void*param)
{
u8 i =;
while()
{
i++;
if(!(i%))
{
xSemaphoreGive(semphorebinary); }
vTaskDelay();
xEventGroupSetBits(eventgroup,0x2);
} } void eventgrup_task(void*param)
{
while()
{
xEventGroupWaitBits(eventgroup,0x7,pdTRUE,pdFALSE,portMAX_DELAY);
printf(" event groups test!!! \r\n");
} } void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
{
printf("task overflow name :%s\r\n",pcTaskName); }
void AutoReloadTimer_Handle_callback(TimerHandle_t xTimer)
{
static u32 count = ;
count++;
if(count>)
{
// xTimerReset(timer,0);
xTimerStop(timer,);
}
printf("timer count: %d\r\n",count);
} void print_high_stack_mark_value(void)
{
if(STACK_DEBUG)
{
u8 num =;
num = uxTaskGetStackHighWaterMark(ledHandle);
printf("%s : %d\r\n",pcTaskGetTaskName(ledHandle),num);
num = uxTaskGetStackHighWaterMark(ledHandle);
printf("%s : %d\r\n",pcTaskGetTaskName(ledHandle),num);
num = uxTaskGetStackHighWaterMark(ledHandle);
printf("%s : %d\r\n",pcTaskGetTaskName(ledHandle),num); } }
freertos test code
freertos学习的更多相关文章
- 【FreeRTOS学习05】深度解剖FreeRTOSConfig.h实现对系统的自定义剪裁
ROM/RAM太小,因此要对系统进行剪裁: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 系统的剪裁 2 FreeRTOSConfi ...
- FreeRTOS学习及移植笔记之一:开始FreeRTOS之旅
1.必要的准备工作 工欲善其事,必先利其器,在开始学习和移植之前,相应的准备工作必不可少.所以在开始我们写要准备如下: 测试环境:我准备在STM32F103平台上移植和测试FreeRTOS系统 准备F ...
- FreeRTOS学习笔记——任务间使用队列同步数据
1.前言 在嵌入式操作系统中队列是任务间数据交换的常用手段,队列是生产者消费者模型的重要组成部分.FreeRTOS的队列简单易用,下面结合一个具体例子说明FreeRTOS中的队列如何使用. 2.参考代 ...
- FREERTOS学习笔记
2012-02-25 21:43:40 为提升自己对实时操作系统(RTOS)的认识,我学习了freeRTOS. 理解了OS任务的状态.优先级的概念.信号量的概念.互斥的概念.队列.内存管理.这都是和R ...
- 020 - FreeRTOS学习路线总结
零.为什么写? 在H7-tools预售群里,有位朋友提出如何学习FreeRTOS这类的问题,便由此总结下自己的学习路线.最近又打算接触RTT,和FreeRTOS做个对比. 文章分两步来讲,学习路线和学 ...
- 【FreeRTOS学习06】深度解剖中断与任务之间同步的具体使用场景
嵌入式系统中中断是必不可少的一部分: [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 1 前言 2 中断特点 3 延迟中断处理 3.1 信号量的使用 3.2 ...
- 【FreeRTOS学习04】小白都能懂的 Queue Management 消息队列使用详解
消息队列作为任务间同步扮演着必不可少的角色: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 前言 2 xQUEUE 3 相关概念 3 ...
- 【FreeRTOS学习02】源码结构/数据类型/命名规则总结
个人不是很喜欢FreeRTOS的编程风格,但是没办法,白嫖人家的东西,只能忍了,这里先简单总结一下: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 ...
- 【FreeRTOS学习03】小白都能懂的Task Management 任务管理基本概念介绍
在FreeRTOS中,线程的术语又可以被称之为任务,或许这样更加合适,本文将介绍任务的创建/删除,任务参数的使用,以及任务优先级: 1 软实时和硬实时 硬实时系统的任务运行正确性与响应时限是紧密相关的 ...
- 【FreeRTOS学习01】CubeIDE快速整合FreeRTOS创建第一个任务
整个专栏主要是博主结合自身对FreeRTOS的实战学习以及源码分析,基于STM32F767 Nucleo-144平台,在CubeIDE下进行开发,结合官方的HAL库,将硬件环节的问题减少到最小,将精力 ...
随机推荐
- Linux 笔记 - 第十五章 MySQL 常用操作和 phpMyAdmin
博客地址:http://www.moonxy.com 一.前言 前面几章介绍了 MySQL 的安装和简单的配置,只会这些还不够,作为 Linux 系统管理员,我们还需要掌握一些基本的操作,以满足日常管 ...
- 一个基于vue的时钟
前两天写了一个基于vue的小钟表,给大家分享一下. 其中时针和分针使用的是图片,结合transform制作:表盘刻度是通过transform和transformOrigin配合画的:外面的弧形框框,啊 ...
- 编写优雅代码,从挖掉恶心的if/else 开始
背景 长话短说, 作为开发人员经常需要根据条件灵活查询数据库,不管你是用rawsql 还是EFCore, 以下类似伪代码大家都可能遇到: /// <summary> /// 灵活查询 能耗 ...
- Flask学习之旅--用 Python + Flask 制作一个简单的验证码系统
一.写在前面 现在无论大大小小的网站,基本上都会使用验证码,登录的时候要验证,下载的时候要验证,而使用的验证码也从那些简简单单的字符图形验证码“进化”成了需要进行图文识别的验证码.需要拖动滑块的滑动验 ...
- 今天第一次解决了程序在未装VS和XP下运行的问题
http://www.cnblogs.com/zero5/p/3162948.html 一位素不相识的朋友做的代码雨屏保程序 - 残雪孤侠 - 博客园 上面是我的BLOG 群共享里,有程序和代码 ...
- Spring Cloud Gateway 使用
简介 Spring Cloud Gateway是Spring Cloud官方推出的网关框架,网关作为流量入口,在微服务系统中有着十分重要的作用,常用功能包括:鉴权.路由转发.熔断.限流等. Sprin ...
- 【博客美化】添加github图标
<a href="https://github.com/cai3231" target="_blank"> <img style=" ...
- Spring Boot (十): Spring Boot Admin 监控 Spring Boot 应用
Spring Boot (十): Spring Boot Admin 监控 Spring Boot 应用 1. 引言 在上一篇文章<Spring Boot (九): 微服务应用监控 Spring ...
- 【译】微软的Python入门教程(一)
Getting started with Python(Python入门) Overview 概述 The series of videos on Channel 9 is designed to h ...
- Spark 学习笔记之 distinct/groupByKey/reduceByKey
distinct/groupByKey/reduceByKey: distinct: import org.apache.spark.SparkContext import org.apache.sp ...