除了上述两种场景,还有一种应用场景:串口接收数据长度位置,频率未知,不要求实时处理的场景。如果采用上述方案,接收一帧数据立即处理,那么在处理的时候来的数据包就“丢失”了。这个时候就需要缓冲队列来解决这个问题。
02、缓冲区
缓冲区看名字就知道,是缓冲数据用的。实现缓冲区最简单的办法时,定义多个数组,接收一包数据到数组A,就把接收数据的地址换成数组B,每个数据有个标记字节用于表示这个数组是否收到数据,收到数据是否处理完成。
上述方案是完全可行的,但有缺点:
①缓冲数据组数一定,且有多变量,代码结构不太清晰。
②接收数据长度可能大于数组大小,也可能小于数组大小。不灵活,需要接收数据很长时容易出错,且内存利用率低。
解决这个问题的好办法是:环形缓冲区。
环形缓冲区就是一个带“头指针”和“尾指针”的数组。“头指针”指向环形缓冲区中可读的数据,“尾指针”指向环形缓冲区中可写的缓冲空间。通过移动“头指针”和“尾指针”就可以实现缓冲区的数据读取和写入。在通常情况下,应用程序读取环形缓冲区的数据仅仅会影响“头指针”,而串口接收数据仅仅会影响“尾指针”。当串口接收到新的数组,则将数组保存到环形缓冲区中,同时将“尾指针”加1,以保存下一个数据;应用程序在读取数据时,“头指针”加1,以读取下一个数据。当“尾指针”超过数组大小,则“尾指针”重新指向数组的首元素,从而形成“环形缓冲区”!,有效数据区域在“头指针”和“尾指针”之间。如下图
图片
如上面说的,环形缓冲区其实就是一个数组,将其“剪开”,然后“拉直”后如下图
STM32控制器芯片内部有一定大小的SRAM及FLASH作为内存和程序存储空间,但当程序较大,内存和程序空间不足时,就需要在STM32芯片的外部扩展存储器了。STM32F4系列芯片可以扩展外部SRAM用作内存。__TM32芯片扩展内存与给PC扩展内存的原理是一样的,只是PC上一般以内存条的形式扩展,而且内存条实质是由多个内存颗粒(即SDRAM芯片)组成的通用标准模块,而STM32扩展时,直接与SRAM芯片连接。
_蔡婊娲⑵? SRAM的存储单元以锁存器来存储数据。这种电路结构不需要定时刷新充电,就能保持状态(当然,如果断电了,数据还是会丢失的),所以这种存储器被称为“静态(Static)”RAM。
_栽谑导视τ贸『现校_RAM 一般只用于 CPU 内部的高速缓存(Cache),而外部扩展的内存一般使用 DRAM。
设定合适的编译优化选项。STM32正常运行时对程序运行效率要求不是很高,但是在中断中要求快进快出,尤其是中断数量多且中断里处理的任务较多时,对程序的运行时间及效率要求比较苛刻,可以从以下几点优化程序:设定合适的编译优化选项
Optimization level -O0
-O0禁用所有优化。使用-O0可以加快编译和构建时间,但是生成的代码比其他优化级别要满。与其他优化级别相比,-O0的代码大小和堆栈使用率明显要高。生成的代码与源代码密切相关,但生成的代码要多得多,包括死代码。
Optimization level -O1
-O1支持编译器中的核心优化。因为这个级别比-O0提供了更好的代码质量,因此它能提供了很好的调试体验。堆栈的使用也在-O0的基础上有所提高。为了获得良好的调试体验,Arm推荐使用此选项。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)