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学习的更多相关文章

  1. 【FreeRTOS学习05】深度解剖FreeRTOSConfig.h实现对系统的自定义剪裁

    ROM/RAM太小,因此要对系统进行剪裁: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 系统的剪裁 2 FreeRTOSConfi ...

  2. FreeRTOS学习及移植笔记之一:开始FreeRTOS之旅

    1.必要的准备工作 工欲善其事,必先利其器,在开始学习和移植之前,相应的准备工作必不可少.所以在开始我们写要准备如下: 测试环境:我准备在STM32F103平台上移植和测试FreeRTOS系统 准备F ...

  3. FreeRTOS学习笔记——任务间使用队列同步数据

    1.前言 在嵌入式操作系统中队列是任务间数据交换的常用手段,队列是生产者消费者模型的重要组成部分.FreeRTOS的队列简单易用,下面结合一个具体例子说明FreeRTOS中的队列如何使用. 2.参考代 ...

  4. FREERTOS学习笔记

    2012-02-25 21:43:40 为提升自己对实时操作系统(RTOS)的认识,我学习了freeRTOS. 理解了OS任务的状态.优先级的概念.信号量的概念.互斥的概念.队列.内存管理.这都是和R ...

  5. 020 - FreeRTOS学习路线总结

    零.为什么写? 在H7-tools预售群里,有位朋友提出如何学习FreeRTOS这类的问题,便由此总结下自己的学习路线.最近又打算接触RTT,和FreeRTOS做个对比. 文章分两步来讲,学习路线和学 ...

  6. 【FreeRTOS学习06】深度解剖中断与任务之间同步的具体使用场景

    嵌入式系统中中断是必不可少的一部分: [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 1 前言 2 中断特点 3 延迟中断处理 3.1 信号量的使用 3.2 ...

  7. 【FreeRTOS学习04】小白都能懂的 Queue Management 消息队列使用详解

    消息队列作为任务间同步扮演着必不可少的角色: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 前言 2 xQUEUE 3 相关概念 3 ...

  8. 【FreeRTOS学习02】源码结构/数据类型/命名规则总结

    个人不是很喜欢FreeRTOS的编程风格,但是没办法,白嫖人家的东西,只能忍了,这里先简单总结一下: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 ...

  9. 【FreeRTOS学习03】小白都能懂的Task Management 任务管理基本概念介绍

    在FreeRTOS中,线程的术语又可以被称之为任务,或许这样更加合适,本文将介绍任务的创建/删除,任务参数的使用,以及任务优先级: 1 软实时和硬实时 硬实时系统的任务运行正确性与响应时限是紧密相关的 ...

  10. 【FreeRTOS学习01】CubeIDE快速整合FreeRTOS创建第一个任务

    整个专栏主要是博主结合自身对FreeRTOS的实战学习以及源码分析,基于STM32F767 Nucleo-144平台,在CubeIDE下进行开发,结合官方的HAL库,将硬件环节的问题减少到最小,将精力 ...

随机推荐

  1. 如何部署 H5 游戏到云服务器?

    在自学游戏开发的路上,最有成就感的时刻就是将自己的小游戏做出来分享给朋友试玩,原生的游戏开可以打包分享,小游戏上线流程又长,那 H5 小游戏该怎么分享呢?本文就带大家通过 nginx 将构建好的 H5 ...

  2. 基于python-django框架的支付宝支付案例

    目录 @ 一. 开发前的准备 1. 必须了解的知识 SDK:软件开发工具包,可以为开发者提供快速开发的工具 沙箱环境:也就是测试环境 支付宝支付金额的精度:小数点后两位(面试) 支付宝用的什么加密方式 ...

  3. 字符串之————三向字符串快速排序(Quick3string)

    上一篇介绍了字符串的两种经典排序方法(LSD MSD): https://www.cnblogs.com/Unicron/p/11531111.html 下面我们来介绍一种通用的字符串排序方法——三向 ...

  4. [Leetcode] 第331题 验证二叉树的前序序列化

    一.题目描述 序列化二叉树的一种方法是使用前序遍历.当我们遇到一个非空节点时,我们可以记录下这个节点的值.如果它是一个空节点,我们可以使用一个标记值记录,例如 #. _9_ / \ 3 2 / \ / ...

  5. Pytorch-数学运算

    引言 本篇介绍tensor的数学运算. 基本运算 add/minus/multiply/divide matmul pow sqrt/rsqrt round 基础运算 可以使用 + - * / 推荐 ...

  6. Redis 相关功能和实用命令(五)

    慢查询原因分析 由于 Redis 是单线程的,它内部维护了一个命令队列,所以当有耗时的命令出现时,比如 keys *,后面的命令会被阻塞,通查查出慢查询可以对服务进一步优化. 设置慢查询阀值:默认10 ...

  7. Windows10安装多个版本的PostgreSQL数据库,但是均没有自动注册Windows服务的解决方法

    1.确保正确安装了PostgreSQL数据库,注意端口号不能相同 我的安装目录如图: 其中9.6版本的端口号为5432,10版本的端口号为5433,11版本的端口号为5434.若不知道端口号,可在Po ...

  8. redis常用操作-键的生存时间

    System.out.println("设置 key001的过期时间为5秒:"+jedis.expire("key001", 5)); System.out.p ...

  9. mysql查询数据库中每一张表的内存大小

    SELECT TABLE_NAME,DATA_LENGTH+INDEX_LENGTH,TABLE_ROWS,concat(round((DATA_LENGTH+INDEX_LENGTH)//,), ' ...

  10. spring cache常用注解使用

    1.@CacheConfig 主要用于配置该类中会用到的一些共用的缓存配置.示例: @CacheConfig(cacheNames = "users") public interf ...