2013-01-21 77 views
2

我试图用queue来缓存来自我的UART ISR的字符到后台任务。我想队列的长度是512字节。这是不可能的,因为size参数的类型是unsigned portBASE_TYPE,对于xmega256a3是单字节(char)。是否有一个队列的最大尺寸与portBASE_TYPE浮动的原因?而不是uint16_t?令人沮丧的FreeRTOS xQueueCreate()限制

我很好奇,如果别人有同样的限制,以及他们已经做了什么,如果有的话。

+0

我不熟悉FreeRTOS的细节。在将其视为一般情况时,是否可以分配一个缓冲区来收集字符并将指针指向该缓冲区的队列? – NeonGlow

+0

在这种情况下,是否会有原子访问问题或其他假设使BASE_TYPE成为首选? – XTL

回答

3

出于效率原因,对于大多数变量使用portBASE_TYPE是很自然的。 AVR是8位体系结构,因此处理8位队列算法的效率将高于16位。对于某些应用来说,这种效率可能很关键

使用uint16_t不作在32位架构的意义,你会注意到,portBASE_TYPE的ARM内核是一个32位的值,因此在选择uint16_t作为队列长度的默认类型将上是人工的限制这些核心。

这里有一些选择:

  • 重构你的任务从队列中更经常读。除非其他任务窃取了太多处理时间,否则应该可以降低ISR队列长度并缓存读线程中的数据。
  • 用不同的portBASE_TYPE重新编译FreeRTOS。我没有尝试过,但是我没有看到为什么这样做不起作用的原因,除非FreeRTOS中有一些汇编代码需要8位portBASE_TYPE。我看了一眼,没有看到汇编代码需要8位类型的明显迹象。
  • 使用您自己的排队库,可以根据需要存储尽可能多的数据。使用其他FreeRTOS基元(如信号量)向您的任务发出数据已添加到您的队列的信号。它不会阻塞队列读取,而会阻塞信号量。在信号灯被发信号后,您可以使用自己的排队库来读取排队的数据。
4

理查德·巴里(FreeRTOS的作者)发布的FreeRTOS的邮件列表如下回应:

这仅仅是对8位架构的情况。已经提到过几次(您可以在FreeRTOS网站上搜索支持档案),但由于大多数新项目使用的是32位体系结构,因此这种情况并没有多年。简单的做法是改变portmacro.h中的portBASE_TYPE的定义,但它会使你的代码变得更大,效率更低。另外,许多FreeRTOS演示使用队列来传递字符进出中断,以提​​供任务和中断通信的简单示例,但除非吞吐量非常低(例如命令控制台),否则它不是编写生产代码的推荐方式。使用循环缓冲区,最好使用DMA,效率更高。