FreeRTOS笔记(三)

1.单片机delay函数和FReeRTOS中delay函数的区别

单片机默认的delay函数则一直是cnt++,在计数过程中不会进行其他时间,故会占用很大的资源,影响其然任务的进行。

FReeRTOS中的vTaskDelay函数是由定时器tick进行计数的,当前任务调用delay函数可以理解为将其任务调转到阻塞态,让当前任务放弃调度,定时由FReeRTOS内部的tick计数器完成,它是不会影响其他任务的进行,

2.两个FreeRTOS的delay函数

vTaskDelay可以理解为绝对时间,它就是延迟你所给的时间,而vTaskDelayUntil可以理解为相对时间,好比你规定了一个15ms的总时间,它会根据你任务执行时间的大小动态的调整延时时间,使其总时间达到15ms。因此需要xTaskGetTickCount();来获得当前计数器所计数的时间,也就是传入的第一个参数,第二个参数即为延时的总时间。

3.同步和互斥

在团队活动里,同事A先写完报表,经理B才能拿去向领导汇报。经理B必须等同事A完成报表,AB之间有依赖,B必须放慢脚步,被称为同步。在团队活动中,同事A已经使用会议室了,经理B也想使用,即使经理B是领导,他也得等着,这就叫互斥。经理B跟同事A说:你用完会议室就提醒我。这就是使用"同步"来实现"互斥"。

在裸机程序里,可以使用一个全局变量或静态变量(注意volatile关键字的使用)实现互斥操作,但是在 RTOS 里,使用上述代码实现互斥操作时,会有很小概率出现错误,导致双方任务不能实现互斥。

4.任务之间如何传递信息

1.定义全局变量:但有一定概率达不到互斥的情况,若使用关中断和开中断的办法,假设任务A一直运行,但任务B也在同样运行,一直在判断自己能否使用临界资源,占用了大量的CPU资源。

2.使用环形缓冲区:本质就是一个环形队列,当写的值差读的值1个单位时,此时认为已经满了。适用于两个任务之间,且任务之间不能使用同一个全局变量,以防止出现错误。保证了没有一个变量被同时访问,间接的实现了互斥操作。

3.队列:数据的读写本质就是环形缓冲区,在这个基础上增加了互斥措施、阻塞-唤醒机制。如果这个队列不传输数据,只调整"数据个数的值",它就是信号量(semaphore)。如果信号量中,限定“数据个数”的最大值为1,它就是互斥量(mutex)。

信号量和互斥量的本质都是队列,而队列的本质就是加了保护措施的环形缓冲区。

5.读队列和写队列

读队列和写队列都有三种情况。

读队列:1.队列不为空,直接读出数据;2.队列为空,进入阻塞态,从就绪队列被放入接收队列和delay队列里,在设定的超时时间内有其他任务写入队列,则会被重新移入到就绪队列内,等待任务调度器进行调度,调度完成后读到数据;3.若在超时范围内没有接收到数据,同样会移动到就绪队列内,不过函数会有个错误的返回值,等待处理。

写队列同样的道理。同时,队列内还会存放两个链表,分别指向读和写队列任务的句柄,这样在队列不空或者不满的情况下,可以通知到他们。

任务读写队列时,简单地说:如果读写不成功,则阻塞;可以指定超时时间。口语化地说,就是可以定个闹钟:如果能读写了就马上进入就绪态,否则就阻塞直到超时。

某个任务读队列时,如果队列没有数据,则该任务可以进入阻塞状态:还可以指定阻塞的时间。如果队列有数据了,则该阻塞的任务会变为就绪态。如果一直都没有数据,则时间到之后它也会进入就绪态。

有多个任务在等待同一个队列的数据。当队列中有数据时,哪个任务会进入就绪态:1.优先级最高的任务;2.如果大家的优先级相同,那等待时间最久的任务会进入就绪态

6.队列的基本函数

1、创建队列:

动态分配:

静态分配:

2、复位队列:

3、删除队列:

4、写队列:

队列默认都是写尾部,也就是SendToBack,若想写在头部,则是xQueueSendToFront。ISR指的是中断服务程序,意思是在中断中操作队列。

5、读队列:

7.队列集

假设我有一个设备,可以使用多种方式来控制这个设备,但每种控制的方法是不一样的,好比方法一是串口接收、方法二是按键接收、方法三是陀螺仪控制,因此我们每一个方法的处理逻辑是不一样的,为了防止过度耦合,我们就可以创建三个队列,然后设定一个队列集,并将这三个队列加入到队列集内,队列集本质记录的是各个队列的句柄的先后顺序,当写入队列时,它也同样会被记入到队列集内。这样我们就可以读队列集,得到有数据的队列句柄,然后根据不同队列名称,处理不同的方法。最后在将处理好的数据写入到最终需要控制设备的队列。

8.队列集函数

创建队列:

把队列加入队列集

读取队列集

9.信号量

消息队列用于传输多个数据,但是有时候我们只需要传递状态,就采用了信号量。可以表示cpu的资源,好比我可以执行四个任务,若开始一个任务,信号量--。释放一个任务,信号量++。

信号:起通知作用;量:还可以用来表示资源的数量

当"量"没有限制时,它就是"计数型信号量"(Counting Semaphores)

当"量"只有0、1两个取值时,它就是"二进制信号量"(Binary Semaphores)

支持的动作:"give"给出资源,计数值加1;"take"获得资源,计数值减1。

作用:简单性和效率:二值信号的机制简单,只需要一个计数器就可以表示资源是否可用,信号量的获取和释放不需要像队列一样创建、拷贝、存储和删除等操作,效率更高。资源的管理:非常适合用于表示有限资源的数量,如资源池中有多少资源可用。而对于那些不需要传递任何数据,只是单纯想同步任务执行顺序的情况,信号量是一个很好的选择。实现同步

二进制信号量跟计数型的唯一差别,就是计数值的最大值被限定为1。

10.信号量函数

创建二进制信号量

创建计数型信号量

删除信号量:

Give和Take:

Give(+1):

Take(-1):

11.信号量和队列的区别

信号量本质就是一种队列,它相比队列而言不具备读写功能,只具备了计数功能,可以看做是一个票数,可实现计数的加或减,同时它会提供了等待链表,就我想要获取信号量,但信号量已经不够的情况下,我可以等待,等待它“发票”,但提供票数的人不需要等待,只需要发或者不发。

FreeRTOS是一个开源的实时操作系统(RTOS),专门用于嵌入式系统。它提供了一套可移植的API,使开发者能够轻松地编写多任务应用程序。 以下是一些关于FreeRTOS笔记: 1. 任务(Tasks):FreeRTOS使用任务实现并行执行。每个任务都有自己的独立堆栈空间优先级。任务可以创建、删除挂起。 2. 调度器(Scheduler):FreeRTOS的调度器负责决定哪个任务应该在给定时间运行。它使用优先级调度算法,并且可以配置为使用抢占式或协作式调度。 3. 信号量(Semaphores):信号量是一种用于同步通信的对象。它可以用于任务之间的互斥访问共享资源或任务之间的通信。 4. 队列(Queues):队列提供了一种任务之间传递数据的方式。任务可以将数据发送到队列,另一个任务可以从队列中接收数据。 5. 事件标志组(Event Flags):事件标志组用于任务之间的同步通信。一个任务可以等待一组特定的事件标志发生,另一个任务可以设置或清除这些事件标志。 6. 定时器(Timers):FreeRTOS提供了软件定时器,可以在指定时间间隔内运行回调函数。 7. 内存管理(Memory Management):FreeRTOS提供了内存管理功能,可以动态分配释放内存。 8. 中断(Interrupts):FreeRTOS可以与硬件中断一起使用,以实现任务的抢占式调度。 这些只是FreeRTOS的一些基本概念功能,它还有很多其他特性组件。如果你对某个特定方面有更多的兴趣,请告诉我,我会提供更详细的信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值