主页 | 常见问题
FreeRTOS 常见问题- FreeRTOS API
以下是常见问题 节选
为什么有这么多 API 函数?
为什么中断使用单独的 API?
为什么 ISR 中使用的 API 设置 xHigherPriorityTaskWoken 而不实际执行上下文切换?
为什么信号量和队列一样大?
如何有效地使用信号量?
为什么任务不能通过退出其实现函数来删除任务自身?
为什么我的 N 个滴答延迟没有引发 N 个滴答 * tick_period 的延迟?
以下为常见问题节选
为什么有这么多 API 函数?
出现这种情况的原因有以下几点:
- FreeRTOS 早在 2004 年之前便已面世,拥有庞大的用户群体,而这些用户是其发展的主要驱动因素。如果有足够多的用户想要新的 API 来实现功能,我们便会增添 API。
- 我们选择将任务中使用的 API 与中断中使用的 API 分开。请参阅常见问题“为什么中断使用单独的 API ?”,了解具体原因。
- 我们很少(多年来都未曾)打破向后兼容性,以确保新的 FreeRTOS 版本能向后与旧的 FreeRTOS 版本兼容。为避免打破向后兼容性,我们会选择添加新的 API 函数,而不是更改现有 API 函数。例如,早期版本的 FreeRTOS 不包括静态分配 RTOS 对象的选项,因此当添加该功能时,我们也相应添加了可实现静态分配功能的 API。
为什么中断使用单独的 API?
总而言之,为了达到简洁高效。我们理解,需要权衡在中断和任务中使用同一 API 或是在中断和任务中使用单独的 API。
使用单独的 API 意味着:
- 用于中断的 API 函数可针对该用例优化;它们不需要以编程方式检查其是否从中断调用,不需要根据其是从中断或任务上下文调用而采取不同的操作,也不需要块时间等参数(当从任务上下文调用 API 时,需要用到此类参数,而当从中断上下文调用 API 时,并不需要此类参数)。
- 无需特殊的中断条目代码(例如保持对中断嵌套深度计数,或设置标志以指示中断上下文)。
- 在实现中断服务程序时,应用程序编写器不需采取任何具体步骤,或添加任何其他代码。
为什么 ISR 中使用的 API 设置 xHigherPriorityTaskWoken 而不实际执行上下文切换?
总之,为使应用程序编写器自行决定是否需要执行上下文切换,可授权应用程序编写器阻断任何不必要的上下文切换崩溃。
作为示例,设想一个可以逐字符接收字符串的中断服务程序。相较于在接收到每个字符之后执行上下文切换,在接收到整个字符串后执行上下文切换可能更高效。
为什么信号量和队列一样大?
如何有效地使用信号量?
FreeRTOS 的最初版本是在 2004 年前开发的,当时使用简单和最小化代码大小是两个首要设计目标。与此同时,FreeRTOS队列是主要的任务间通信方式。然后,通过定义使用预存队列的功能的宏增添 FreeRTOS信号量的功能,实现最小化代码大小的目标(信号量功能不会增加代码大小),但代价是信号量比预期的更大、速度更慢。
虽然最小化代码大小仍然很重要,但其不再是首要目标。因此,我们着眼于为我们的用户提供更小、更快的选择。然而,我们并没有重新实现信号量,而是针对主要信号量用例进行优化,并引入直达任务通知。在大多数情况下,可以使用直达任务通知来代替信号量。由于直达任务通知不使用中间对象(信号量等) ,因此它们更快,并且使用的 RAM 更少。
如果您的用例不在中断*的范围内,则可使用事件组作为信号量的有效替代方案,因此事件组不仅小,而且单个事件组可以用作多达 24 个不同的二进制信号量。
*为解释关于仅在中断之外使用事件组作为信号量的替代方案的警告:FreeRTOS 制定一项策略——不在关键部分内部或中断内部执行非确定性操作。事件组是一种广播机制:它们可以解锁多个任务,因此具有不确定性,无法预测出有多少任务将被解锁。因此,在中断中执行的事件组操作被推迟到 RTOS 守护程序任务,这需要对 RTOS 守护程序任务执行额外的上下文切换。
为什么任务不能通过退出其实现函数来删除任务自身?
可以节省堆栈空间。
FreeRTOS的最初版本是在 2004 年前开发的,当时微控制器的内存要小得多。要使任务仅通过运行其实现函数直至结束或退出该实现函数后便能自行删除,需要将则此任务返回特定函数,该函数随后将清理任务使用的内存,并且需要在任务的堆栈中设置此函数的指针以及相关参数。
如果任务退出异常,FreeRTOS 的最新版本将触发 assert()。
为什么我的 N 个滴答延迟没有引发 N 个刻滴答 * tick_period 的延迟?
请参阅滴答分辨率。
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.