FREERTOS 手册阅读笔记

郑重声明,版权所有!

转载需说明。

FREERTOS堆栈大小的单位是word,不是byte.

根据处理器架构优化系统的任务优先级不能超过32,If the architecture optimized method is used then configMAX_PRIORITIES cannot be greater than 32.

vTaskDelay() delay from call the vTaskDelay

vTaskDelayUntil delay from last wake up time

 

It is the responsibility of the idle task to free memory allocated to tasks that have since been deleted.

Ready state tasks of equal priority will enter the Running state in turn.  ‘Round Robin Scheduling’

同一优先级任务实行时间片轮转调度。

A time slice is equal to the time between two RTOS tick interrupts.

时间片值等于TICK时钟值

消息序列让局部变量存放在序列中,函数退出时局部变量仍然在序列中

In practice it is very common for a queue to have multiple writers, but much less common for a queue to have multiple readers.

多个任务等待同一序列:Queues can have multiple readers, so it is possible for a single queue to have more than one task blocked on it waiting for data. When this is the case, only one task will be unblocked when data becomes available. The task that is unblocked will always be the highest priority task that is waiting for data. If the blocked tasks have equal priority, then the task that has been waiting for data the longest will be unblocked.

应该任务等待多个序列:Queues can be grouped into sets, allowing a task to enter the Blocked state to wait for data to become available on any of the queues in the set.

创建序列返回的是序列指针,序列本身由OS内部动态分配在OS的Heap中:The xQueueCreate() API function creates a queue and returns a QueueHandle_t that references the queue it created.

清空序列:xQueueReset() API function can be used to return the queue to its original empty state.

xQueueSendToBack() is used to send data to the back (tail) of a queue xQueueSendToFront() is used to send data to the front (head) of a queue.

xQueueSend() = xQueueSendToBack().

xTicksToWait 是0则立即返回,Both xQueueSendToFront() and xQueueSendToBack() will return immediately if xTicksToWait is zero and the queue is already full.

xTicksToWait 是portMAX_DELAY则一直等待:Setting xTicksToWait to portMAX_DELAY will cause the task to wait indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.

请求序列有多少个信息:uxQueueMessagesWaiting() is used to query the number of items that are currently in a queue.

序列传指针注意事项:when queuing pointers, extreme care must be taken to ensure that:

1. The owner of the RAM being pointed to is clearly defined.

2. The RAM being pointed to remains valid.动态分配必须没有被free

序列集:

xQueueAddToSet() adds a queue or semaphore to a queue set

FREERTOS CAN Using a Queue to Create a Mailbox

邮箱是长度为1的序列:In this book the term mailbox is used to refer to a queue that has a length of one

邮箱被读取后并不会被消耗,只会在重新发送时被覆盖:A mailbox is used to hold data that can be read by any task, or any interrupt service routine. The data does not pass through the mailbox, but instead remains in the mailbox until it is overwritten. The sender overwrites the value in the mailbox. The receiver reads the value from the mailbox, but does not remove the value from the mailbox.

邮箱具有广播特性!!!,任务读取后不被覆盖,别的任务依然可以读取,邮箱大小永远是1,只能读到发送的最新的邮件,读消息邮箱每次都会读到,根据时间戳可以判断是不是被更新。

if the queue is already full, then xQueueOverwrite() will overwrite data that is already in the queue.

xQueuePeek() is used to receive (read) an item from a queue without the item being removed from the queue.

参考手册4.7节设计消息邮箱功能。

Software Timer

软件定时器适合的应用场合:

l  事件发生后加一个延迟产生一个动作

l  周期性执行某个函数(任务中系统调用只有delay的任务)

They should be kept short, and must not enter the Blocked state.

会在上下文切换时调用

The xTimerDelete() API function deletes a timer. A timer can be deleted at any time.

All software timer callback functions execute in the context of the same RTOS daemon (or ‘timer service’) task1.

The daemon task is a standard FreeRTOS task that is created automatically when the scheduler is started. Its priority and stack size are set by the configTIMER_TASK_PRIORITY and configTIMER_TASK_STACK_DEPTH compile time configuration constants respectively. Both constants are defined within FreeRTOSConfig.h.

软件定时器回调函数由系统守护进程(定时器服务)调用,在配置里可以配置它的优先级和堆栈大小。

configTIMER_TASK_STACK_DEPTH决定最多由多少个在线软件定时器,为保证软件定时器无阻塞正常执行,执行后不需要的定时器需要删除

xTimerChangePeriod()改变定时器周期

软件定时器可以做超时检测并处理,类似于看门狗,当正常接收时reset定时器,溢出时调用定时器回调函数做超时处理

 

 

任务优先级低于任何硬件的中断优先级,任务无法抢占中断!

Tasks will only run when there are no ISRs running, so the lowest priority interrupt will interrupt the highest priority task, and there is no way for a task to pre-empt an ISR.

任务中函数引起上下文切换立即切换,中断引起的上下文切换在中断退出后开始切换(中断优先级高于内核调度)

中断中如需进行上下文切换需调用portYIELD_FROM_ISR()如不调用,则中断引起的上下文切换会在下一次上下文切换时发生(最晚在ostick中断中发生)

中断尽量短,中断把工作延迟给任务有以下优点:

最高优先级任务优先级比中断低,中断过长阻塞高优先级任务

中断是随机的,影响任务执行的连续性

中断中有新中断产生优先级比当前中断低则会被延迟

中断嵌套会增加调度复杂性,中断短之后嵌套概率变小

短时间可以执行完的在中断内执行,否则延迟到任务执行

二进制信号量和互斥信号量的区别:

二进制信号量进程本身获得之后不需要再给出,而互斥信号量必须是谁获得谁给出。

二进制信号量只借不还,互斥信号量有借有还!

互斥信号量不同于二进制信号量的是互斥信号量有优先级继承特性(防止优先级反转)

二进制信号量与计数信号量

慢速信号或单次信号可以通过二进制信号量进行同步,连续快速随机信号可以通过计数信号量缓存,保证信号不被丢失,计数值表示产生的信号数与已经处理的信号数之差,如果计数信号量一直处于满的状态说明信号处理程序过慢不能达到要求

同时计数信号量还可以用于有限个资源管理,进程需要资源时获取信号量,使用完资源后释放信号量。

低时间延迟要求的事件可以通过xTimerPendFunctionCallFromISR()直接调用守护进程执行事件处理函数,减少单独处理任务,简化设计。

中断产生消息序列不太可取(这样使用操作系统API速度会变慢速度慢),最好用DMA或者环形缓冲区

中断逻辑优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY不会被FREERTOS临界段屏蔽,小于等于的的会被屏蔽

只有逻辑优先级小于等于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断可以调用OS的API

Typically, functionality that requires very strict timing accuracy (motor control, for example) would use a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY to ensure the scheduler does not introduce jitter into the interrupt response time.

If a function does not access any data other than data stored on the stack or held in a

register, then the function is reentrant, and thread safe

尽量减少任务共享资源,所有任务共享资源需要保护。

进出临界段只会屏蔽优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断

taskENTER_CRITICAL()

taskEXIT_CRITICAL(),

Basic critical sections must be kept very short, otherwise they will adversely affect interrupt response times. 临界段要短!

挂起和解挂调度(未关闭中断)

vTaskSuspendAll()

xTaskResumeAll()

最好把使用互斥信号量的功能写成函数,保证“有借有还”,成对使用。

it is normally bad practice for a task to wait indefinitely (without a time out) to obtain a mutex.没用TIMEOUT的等待可能导致死锁

递归互斥信号量可以被同一任务连续多次请求,然后多次释放。

vApplicationTickHook()中的OS函数必须用FromISR()形式,因为tick函数是再tick中断中调用的。

Gatekeeper Tasks(守门员任务):此任务用来替代互斥信号量,避免出现优先级反转或死锁的情况,此任务由用户自己设计,所有任务中只有此任务可以访问共享资源,此任务轮询等待一个消息,得到消息后此任务开始对共享资源进行访问,之后继续挂起等待消息。需要访问共享资源的任务想此任务发送消息,之后此由任务进行共享资源访问。

事件标志组可以用于多个任务同步,具有广播特性。

 

事件标志组可以让一个任务等待多个事件,或者让一个任务等待多个事件之一;

 

事件标志组可以让多个任务等待多个事件,或者让多个任务等待多个事件之一;

 

等待事件标志组函数的参数可以配置函数调用后是否清除uxBitsToWaitFor对应事件位

 

可以单独通过函数xEventGroupClearBits()清除事件标志位

事件标志组进行多任务同步(多个任务同时等待多个事件,期望同时进入就绪态)需要使用xEventGroupSync()进行同步,直接使用事件标志组挂起函数会导致调度不能同步。

 

Task Notifications

更加快速通知任务,更节省RAM空间。

针对单个任务的通知,中断不能接收通知,但中断可以发出通知

非缓存,非广播。

task’s notification类似于一个针对任务的计数信号量,give让任务通知加一,take收到并让通知减一或清零。

xTaskNotify()可以看作是轻量级的二进制信号量,计数信号量,事件标志组,甚至是通知任务的消息邮箱。

调试手段

ConfigASSERT()

FREERTOS+Trace

DEBUG HOOK

Viewing run-time and task state information (statistics)

常见问题:

调用操作系统API的中断优先级必须小于等于configMAX_SYSCALL_INTERRUPT_PRIORITY

Cortex-m内核处理器确保所有的中断优先级都分配非抢占优先级,不要子优先级;

堆栈溢出问题:

uxTaskGetStackHighWaterMark() 获取任务再整个系统运行过程中堆栈的最小剩余值

 

设置configCHECK_FOR_STACK_OVERFLOW为1或2

重写函数vApplicationStackOverflowHook(),这个函数再上下文切换中断中调用,其入口参数是任务句柄和任务名

针对嵌入式系统改进(重写)printf()函数

Printf-stdarg.c是个不错的选择,其中的sprintf是一个最小实现,其中的printf是相对慢的,占用较大堆栈的,直接输出的。

 

如果系统堆栈不足导致vTaskStartScheduler()失败,vTaskStartScheduler()会返回Including a null loop [ for(;;); ] after the call to vTaskStartScheduler() can make this error easier to debug.

时间: 2024-11-05 11:33:28

FREERTOS 手册阅读笔记的相关文章

CI框架源码阅读笔记3 全局函数Common.php

从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap引导文件都会最先引入全局函数,以便于之后的处理工作). 打开Common.php中,第一行代码就非常诡异: if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 上一篇(CI框架源码阅读笔记2 一切的入口 index

CI框架源码阅读笔记4 引导文件CodeIgniter.php

到了这里,终于进入CI框架的核心了.既然是"引导"文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.com/usr/reg 经过引导文件,实际上会交给Application中的UsrController控制器的reg方法去处理. 这之中,CodeIgniter.php做了哪些工作?我们一步步来看. 1.    导入预定义常量.框架环境初始化 之前的一篇博客(CI框架源码阅读笔记2 一切的入

面对软件错误构建可靠的分布式系统(阅读笔记)

阅读笔记 joe Armstrong 段先德 译 核心问题:如何在存在软件错误的情况下编写具有合理行为的软件 ,如何避免像死锁.死循环等问题 ERLANG的世界观,一切皆进程.将任务分离成层次化的一系列任务,强隔离的进程负责来执行每个具体化的任务,进程之间不共享状态(实际上ETS跨越了这个准则). 只能通过消息传递来通信,必须注意进程消息的堵塞问题 工作者和监督者构成一个完整的系统,监督者的作用就是监控整个系统的运行状况.并对突发情况进行可靠的处理. behaviour库的设计思想就是将程序的并

Percona XtraBackup User Manual 阅读笔记

XtraBackup XtraBackup.. 1 2 安装XtraBackup.. 1 2.1 安装XtraBackup binary版本... 1 2.1.1 yum的安装方法:... 1 2.1.2 直接下载rpm包安装... 1 3 XtraBackup使用手册... 1 3.1 使用innobackupex脚本... 1 3.1.1 备份预备工作... 1 3.1.2 全备和全备还原... 1 3.1.2.1 使用innobackupex创建全备... 1 3.1.2.2 使用inno

Google C++ Style Guide 阅读笔记 系列

Google C++ 编程风格手册里面提到了许多编程时需要注意到的问题,对规范代码还是有帮助的.这里是一些阅读时的笔记,也算是归纳的一些要点. - Google C++ Style Guide 阅读笔记 1 - Google C++ Style Guide 阅读笔记 2 - Google C++ Style Guide 阅读笔记 3 - Google C++ Style Guide 阅读笔记 4 - Google C++ Style Guide 阅读笔记 5 - Google C++ Style

《构建之法阅读笔记02》

这次主要对<构建之法>的第四章“两人合作”作一次阅读笔记. 首先是代码规范问题. 我过去对于代码规范问题并没有做到注意.在编程中,许多变量和函数的命名都非常的简单而没有实际的意义.而且编程时不注意对齐缩进.很多时候也不加注释,导致对这些简单的变量名称不熟悉. 这样做会使得很多人读代码费劲,甚至是自己都要花时间再次阅读懂自己的代码.而且很多没必要的注释也会使得注释失去意义.当自己再次在原基础上编程时,可能要重新编程等问题. 因此,通过阅读“代码规范”,我找到一些解决方法.代码的风格要简明.易读.

《代码阅读方法与实践》阅读笔记之二

时间过得真快,一转眼,10天就过去了,感觉上次写阅读笔记的场景仿佛还历历在目.<代码阅读方法与实践>这本书真的很难写笔记,本来我看这本书的名字还以为书里大概写的都是些代码阅读的简易方法,心想着这就好写笔记了,没想到竟然好多都是我们之前学过的东西,这倒让我有点无从下手了.大概像我们这些还没有太多经历的大学生,总是习惯于尽量避免自己的工作量,总是试图找到一些完成事情的捷径吧.总之,尽管我不想承认,但我自己心里很清楚,我就是这种人.下面开始言归正传,说说接下来的几章内容归纳. 这本书在前面已经分析了

《大道至简》阅读笔记1

<大道至简>阅读笔记1 不知不觉间看完了第一章,从这个章节里我看到了一些我们都明白可是却自己很难做到的道理. 书中从愚公移山的故事和编程相结合给出了编程的精义就是顺序.分支.循环,这些都是我们所熟悉的,也是老师在教学中耳提面命的,可是我们又有几个人能做到呢. 我们总是在找着各种各样的学不好学不会理由,“它太难了”,“我太笨了”,认真的想一想难道真的是它太难了或者是自己太笨了么?不,答案是否定的,追根究底是懒惰,是没能坚持.从根本上来说,不存在会不会写程序的问题,除了先天智障和后天懒惰者,这要你

构建之法阅读笔记05

2017.5.20 今天阅读的是<构建之法>第8章需求分析的阅读笔记,我们如果要开始做一个软件,最先要进行的就是需求分析,我们应该充分的了解我们这个软件是否具有前景,我们为用户提供的服务是不是用户所需要的,这一章详细的叙述了如何进行需求分析. 首先是获取和引导需求,我们应该找到软件的利益相关者,了解挖掘他们对软件的需求,引导他们表达出真实的需求.然后分析和定义需求,对各个方面的需求进行规整,定义需求内涵,从各个角度将需求量化,然后估计实现这些需求所需要的时间和资源,确定各个需求的优先级.紧接着