
FreeRTOS
文章平均质量分 68
时间自由
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
STM32F407 越界问题定位【2】CmBacktrace
屏蔽原代码中的 HardFault_Handler 函数,cmb_fault.S 中使用了 HardFault_Handler 函数,保存关键寄存器后跳转到 cm_backtrace_fault。由于源代码 CmBacktrace 只打印一次,如果出错时没有接串口,可能会错过问题的复现,所以这里稍微修改源码 cm_backtrace.c,保证持续打印错误信息。(4)CMB_CPU_PLATFORM_TYPE # 选择 CPU 平台,STM32F4 的 CPU 是 M4 架构。原创 2025-02-05 18:04:20 · 885 阅读 · 0 评论 -
FreeRTOS【18】系统运行监控
基于 FreeRTOS 的学习已经接近尾声,事实上看似没问题的任务可能存在分配合理的地方,某个线程任务长期占用控制器,甚至是线程任务的内存已经开始慢慢泄漏并且越界使用,如果全然不知可能导致程序崩溃。代码中使用了 2 种方法获取任务的运行时间,不推荐使用 vTaskGetRunTimeStats,因为返回的数据是一大段字符串,很容易出现内存溢出,当然带来的好处就是显示清晰明了。理论上应该使用更高的时钟去监控系统的行为,这里只是要粗略估算 CPU 的使用率,所以直接使用了系统时钟,计算比较粗糙。原创 2024-12-06 10:02:18 · 529 阅读 · 0 评论 -
FreeRTOS【17】常用功能使用
上述是部分源码,可以看出 xPortSysTickHandler 中断调用 xTaskIncrementTick,进而实现每次中断 xTickCount 递增,并且当 xConstTickCount 递增到 0 时(计数器16位或者24位)会触发xNumOfOverflows溢出计数递增。基于 FreeRTOS 熟悉使用其他 API 接口。获取局部变量或者使用。原创 2024-10-10 09:30:30 · 446 阅读 · 0 评论 -
FreeRTOS【16】直达任务通知使用
事实上本人使用得比较少,常用的项目内存都比较多,对响应时间也没有特别苛刻,需要快速响应的最好还是硬实时中断。直达任务通知,FreeRTOS 的线程任务提供的接口,可以用作线程唤醒,或者是传递数据,因为是基于线程本身的操作,是轻量级,速度响应更快,适合小内存芯片使用。ulBitsToClearOnExit 写入 0xFFFFFFFF 在成功触发后清除所有位。ulBitsToClearOnEntry 写入 0xFFFFFFFF 在调用前清除所有位。原创 2024-06-03 14:32:54 · 459 阅读 · 0 评论 -
FreeRTOS【15】事件组使用
其中信号量可以实现线程同步,对标的是裸机的 Flag 标识,但是在裸机中经常使用的不止一个标识,如果用二值信号量去实现无疑是增加了系统内存开销,申请多个信号量,实现本质是队列,消耗比较大并且带有迟滞性,所以 FreeRTOS 针对这种情况设计了事件组。事件组是按 bit 操作的,每一个位都可以触发事件,需要注意的是时钟的配置会影响可用的位配置,源码解释如果设置 configUSE_16_BIT_TICKS 系统时钟 16 位,只能用 0~7bit,否则可以使用 0~23 bit。设计试验2:位事件同步。原创 2024-06-03 11:42:08 · 589 阅读 · 0 评论 -
FreeRTOS【14】软件定时器使用
基于以上的章节,这个篇章主题是软件定时器使用,能使用 FreeRTOS 的基本都是从裸机 MCU 过来的,基本都知道 MCU 最基本的功能之一就是定时器,确切的说是硬件定时器,外围电路已经构建好的,精度很高,基本都是微秒级别定时,稳定性也不错,唯一的缺点就是资源太少,定时器的数目有限。既然实现的方式是线程,那就必须配置线程的参数,例如线程优先级考核堆栈大小,定时器的回调函数实际是运行在定时器线程中的,注意堆栈大小,如果想要定时器回调快速响应就需要提高优先级。注意查看的是,打圈的就是软件定时器控制线程。原创 2024-06-01 15:08:04 · 595 阅读 · 0 评论 -
FreeRTOS【13】流缓冲区使用
其中,队列的使用规定了队伍成员的大小,然而现实使用场景下,很多数据不都是定长大小了,例如不定长的通讯协议亦或者是缓存日志信息,如果在这种场景下使用队列传递信息显然不合适,会导致队伍中空间没有利用起来。创建流缓存区还需要注意的是,触发的字节数 xTriggerLevelBytes,接收数据的时候需要达到触发字节数才会触发接收,一般设置为 1 即可。:流缓冲区相对于队列没有设置临界区保护,只有一对一传输才是安全的,一对多或者多对多需要自行进入临界区保护。3)接收线程接收流缓存区的数据。原创 2024-06-01 11:26:46 · 605 阅读 · 0 评论 -
FreeRTOS【12】队列集使用
基于以上的章节,了解了 FreeRTOS 多线程间的信号量、队列的使用,已经满足了日常使用场景。这个篇章要介绍的是队列集,实际上队列的升级版,存储信号量和队列等的触发事件。队列集在实际的开发项目中应用相对比较少,事件存储在队列中,在一定程度上影响了系统的实时性,优点就是一个线程处理多种事件,减少了线程的个数,适合资源使用比较少的场景。1)创建 2 个线程,控制线程和接收线程。3)接收线程接收队列集后再获取对应的信息。2)控制线程发送不同的信号量和队列。原创 2024-05-31 14:38:59 · 391 阅读 · 0 评论 -
FreeRTOS【11】递归互斥锁使用
基于上一个篇章,解释了 FreeRTOS 的互斥锁,可以看出互斥锁是可以保护资源访问的完整性,但是,随着代码的复杂程度提高,有可能存在代码段递归的情况,这样就有可能会出现多次上锁的情况,而 FreeRTOS 提供了递归上锁的操作,即一个锁可以在一个线程中多次上锁,只有解锁同等次数才能真正解锁。实际上,递归互斥锁是互斥锁的一种特殊形态,类似计数信号量和二值信号量的关系,当然,递归互斥锁拥有和互斥锁相同的特性,那就是优先级继承。2)其中一个线程多次上锁后解锁同等次数。3)另一个线程等待多次解锁完成。原创 2024-05-30 14:29:03 · 387 阅读 · 0 评论 -
FreeRTOS【10】互斥锁使用
【如果另一个更高优先级的任务尝试获取相同的互斥锁, 则将暂时提高“获取”互斥锁的任务的优先级。这意味着必须始终“归还”互斥锁,否则 优先级较高的任务将始终无法获得互斥锁,而优先级较低 的始终无法“取消继承”优先级。FreeRTOS 提供了多线程控制,并且是支持高低优先级抢占,这就意味着低优先级线程在执行任务时有可能被高优先级线程打断,如果两个线程共同操作同一个资源可能会导致不可意料的结果,因此,访问共享内存时需要添加互斥操作,因此互斥锁就有了。4)等待高优先级线程获取互斥锁后,再获取当前线程优先级。原创 2024-05-30 11:09:02 · 939 阅读 · 0 评论 -
FreeRTOS【9】计数信号量使用
FreeRTOS 基于上一篇了解了二值信号量后,如果需要设计需要累计信号量的次数就不行了,所以有了计数信号量,可以设置计数的最大值。同样,可以理解二值信号量是计数信号量的一种特例,即二值信号量是计数信号量最大计数为1时的特例。由上图和代码可以分析,本实验设置最大信号量值为5,发送的信号量次数为10,实际上计数信号量累计到最大计数值就不会继续累计了。2)发送线程发送多个信号量,信号量个数大于计数信号量的最大值;1)接收线程一直等待信号量唤醒;3)按键中断发送信号量;原创 2024-05-29 15:14:20 · 345 阅读 · 0 评论 -
FreeRTOS【8】二值信号量使用
FreeRTOS 提供了队列可以在线程间快速交换信息,那么还有没有其他交互渠道?答案是有的,相对于队列传递信息,还有更轻量级的线程唤醒操作,那就是信号量,而二值信号量就是最简单的一种。二值信号量就是二进制的 0 和 1,或者是 bool 类型的 true 和 false,二值信号量代替了传统编程中的循环等待。1)接收线程一直等待信号量唤醒;2)发送线程发送信号量;3)按键中断发送信号量;原创 2024-05-29 14:44:49 · 475 阅读 · 0 评论 -
FreeRTOS【7】队列使用
问题就来了,为了提高子线程的响应实时性,需要频繁判断,导致CPU占用率极高,显然这样的设计是不合理的,所以队列的存在就变得合理了。操作系统提供了多线程并行的操作,为了方便代码的维护,各个线程都分配了专用的内存并处理对应的内容。但是线程间也是需要协助操作的,例如一个主线程接收信息,会把接收的信息并发到其他线程,即主线程不阻塞,子线程做实际的处理。FreeRTOS 的队列传递信息采用的是内存拷贝,队列在接收信息的时候会阻塞线程,释放CPU,降低 CPU 的使用率,相当于线程间信息的交互交给内核去统筹。原创 2024-05-29 13:49:24 · 1205 阅读 · 0 评论 -
FreeRTOS【6】线程优先级
如图在第 0 秒,线程 0 和线程 1 具备相同的优先级,就算线程 0 不阻塞,系统也会定时切换到线程 1,在第 3 秒时提高的线程 0 的优先级,线程 1 无法继续运行,直至第 6 秒的时候降低了线程 0 的优先级后线程 1 才可以继续运行,符合设计预期。2)控制线程在 3000ms 后将线程 0 优先级设置为 2,再过 3000ms 将线程 0 优先级设置为 0,这里涉及到的接口有获取线程优先级的 uxTaskPriorityGet,设置优先级接口 vTaskPrioritySet。原创 2024-05-15 19:57:49 · 554 阅读 · 0 评论 -
FreeRTOS【5】线程阻塞
其实在上一篇已经使用了线程阻塞,如果高优先级线程一直不阻塞占用 CPU,程序会直接卡死在高优先级线程中,常用的阻塞方式 vTaskDelay,这个在 FreeRTOS 中非常常用,需要配置宏 INCLUDE_vTaskDelay。由于我们设置的时钟节拍是 1ms,而 vTaskDelay 的输入参数就是时钟节拍,FreeRTOS 的参数基本都是以时钟节拍为单位,如果时钟节拍不是 1ms,则需要注意换算。3)控制线程定期解除阻塞,这里引入了一个接口 eTaskGetState,可以获取指定线程的状态。原创 2024-05-15 15:29:07 · 1204 阅读 · 0 评论 -
FreeRTOS【4】线程挂起和恢复
Blocked:即阻塞态,因为线程存在高低优先级,如果高优先级线程一直运行会导致低优先级线程一直抢占不到 CPU 的使用权,如果使用挂起的方式去挂起高优先级线程,那么高优先级线程的实时性就会大打折扣,所以就引入了阻塞的概念,高优先级线程可以一直阻塞在某个事件,在阻塞期间会让出 CPU 的使用权,但是一旦高优先级线程满足指定事件就会立刻抢占低优先级线程的 CPU 使用权,这样就保证了高优先级线程的实时性。1)线程删除后会释放内存,由于现在的线程都是在系统堆栈动态开辟的,所以线程删除后内存会回归系统内存堆栈。原创 2024-05-14 20:43:19 · 1762 阅读 · 0 评论 -
FreeRTOS【3】任务线程创建
一般情况下掌握动态创建线程即可,但是有时候我们需要创建多个线程,而且线程的工作内容都基本相同的情况下,为了充分提炼相同代码,多个线程共用一个函数,可以通过传参来区分不同的线程,需要注意的是传参参数(pvParameters)需要常驻内存,否则后续线程访问指针会获取到错误信息。FreeRTOS 创建任务现成的方法有 2 种,动态创建和静态创建,动态创建交由系统统一管理内存,而静态创建则需要使用者指定线程使用的内存区域,创建方法更加原始和繁琐,不推荐使用。这个是线程句柄,后续可以通过句柄实现线程的挂起和删除。原创 2024-05-13 15:24:06 · 1809 阅读 · 0 评论 -
FreeRTOS【2】配置文件
configTOTAL_HEAP_SIZE 配置分配给系统的堆栈大小,芯片的 RAM 会分出一部分给到系统,如果配置的内存比较小,可能会导致任务创建失败甚至是系统启动失败,分配过大会导致芯片剩余 RAM 不足,单位是 /Bytes。configMAX_PRIORITIES 配置最大优先级,这里设置的是10,能用的优先级为 0~9,最大的设置值为 32,其中空闲任务的优先级为0,如果系统处于空闲状态,PC 指针会一直在空闲任务中打转。上面的配置有部分是必须的,FreeRTOS 中会标定。原创 2024-05-11 16:45:46 · 541 阅读 · 0 评论 -
FreeRTOS【1】简介和移植
基于微型控制器程序的开发,最开始是裸机开发,即所有的事务都是在 while(1) 循环中实现,实际上 CPU 大部分的时间都在做循环操作,性能没有完全利用起来,代码的可维护性也不足,所以操作系统(OS)应运而生,由于微型控制器实时性要求,有了实时操作系统(RTOS)由于我这边是 MDK 环境所以选择 keil 参考工程并打开,打开工程发现,例程配置如下,tasks.c、list.c、queue.c、port.c、heap_x.c,其中 heap 可以选择多种模式。工程移植参考这个即可。原创 2024-05-10 20:32:07 · 545 阅读 · 0 评论 -
FreeRTOS 切换上下文问题
信号量发送后执行切换上下文操作,实时性增强,仅仅30微秒,从中可以看出,如果我们不主动切换上下文,内核是不知道有信号改变的,这就需要等待内核自己刷新才能响应信号量,内核刷新时间这里是 1000us。在使用 FreeRTOS 情况下发现 CAN 通讯速度没有达到理论速度,相差比较多。发送信号量后不切换上下文,系统响应时间700+微秒,实时性很差。原创 2023-10-07 11:09:51 · 210 阅读 · 0 评论