当前位置: 首页 > news >正文

车载雷达实战之Firmware内存优化

内存(Memory)是计算机中最重要的部件之一,计算机运时的程序以及数据都依赖它进行存储。内存主要分为随机存储器(RAM),只读存储器(ROM)以及高速缓存(Cache)。
仅仅雷达的原始回波数据(Radar data cube)就可能达MByte级别的数据体量,这对MCU的内存来说尺寸很大。本篇文章主要介绍了在雷达嵌入式编程中会遇到的MPU(Memory Protect Unit)、Cache以及不同数据格式在内存中的存储格式和雷达基带涉及的加速核与内存区的映射。总而言之,与内存相关的嵌入式编程以及优化方式会在本文中对其进行说明,并从内存优化的角度对可以应用的诸如同址复用等思路进行说明。👻

MPU+Cache

Cache一致性问题一般发生在多核处理器上,单核处理器基本不用考虑这个问题。

现在的处理器一般都有两级(L1cache,L2cache)甚至三级缓存,当核0读写外部存储器如DDR内的数据时,会将数据保存在L2cache和L1Dcache中。后续如果该数据一直在cache中,那么对该数据的读写都会直接操作cache内的数据,而不会去修改DDR中的数据。以此提高CPU的读写速度。但是这可能导致其他主机(如其他核)读取DDR的数据与核0中cache中的数据不一致。例如核0已经将位于DDR中的变量num从11修改为56了,但是其他核读取num时,依然有可能读取到的是11。最新的num数据56可能依旧在核0的cache中,没有写回到DDR中。一般来说,多级缓存之间的一致性不需要我们来维护,我们主要维护不同核之间的数据一致。

    // ...// recieve data from DMA or HW peripheral// addr = cache line aligned buffer address// size = multiple of cache line aligned size in bytes// invalidate contents of cache so that a CPU can see the data written by DMA or HW peripheralCacheP_inv(addr, size, CacheP_TYPE_ALL);

上面的代码为将对应地址空间执行了Writeback-Invalidate操作,其的作用是将Cache写回到DDR中,之后Cache中的数据将会无效。这种操作多用于读取核间共享的存储区域之前。除了Writeback-Invalidate操作,还有Invalidate(将CACHE中的数据视为无效数据)以及Writeback(将CACHE中的数据写回存储器中如DDR)等操作。


MPU定义了存储器不同地址空间的属性和存储器的访问权限。MPU不会提升嵌入式应用的性能,而是用于系统中问题的检测(比如试图访问非法或者不允许的存储器位置所导致的应用错误)。如果检测到有错误,则会触发HardFault异常。实际上,许多微控制器用不到MPU,但MPU可以提高嵌入式系统的健壮性,使得系统更加安全

/** MPU Region Base Address Register Value
*
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
*/
#define ARM_MPU_RBAR(Region, BaseAddress) \(((BaseAddress) & MPU_RBAR_ADDR_Msk) |  \((Region) & MPU_RBAR_REGION_Msk)    |  \(MPU_RBAR_VALID_Msk))#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size)    \((((DisableExec)      << MPU_RASR_XN_Pos)   & MPU_RASR_XN_Msk)                                  | \(((AccessPermission) << MPU_RASR_AP_Pos)   & MPU_RASR_AP_Msk)                                  | \(((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \(((SubRegionDisable) << MPU_RASR_SRD_Pos)  & MPU_RASR_SRD_Msk)                                 | \(((Size)             << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk)                                | \(((MPU_RASR_ENABLE_Msk))))/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec       Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission  Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param TypeExtField      Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable       Region is shareable between multiple bus masters.
* \param IsCacheable       Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable      Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable  Sub-region disable field.
* \param Size              Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size)/* Region 3 setting: Memory with Device type, not shareable, non-cacheable */
MPU->RBAR = ARM_MPU_RBAR(3, 0x31C00000U); //0x30000000U
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_32MB);

上述代码将0x31C00000为起点的32MB数据区域设置为了non-cacheable(意味着所有observers都可以观察该内存的实际值),not shareable(如果被多个observer使用Non-shareable内存,无序的读写的操作顺序会导致异常)。当然,在设置MPU regions时,建议将cache与MPU失能,配置完成之后再使能。

Data representation

在基带模块中主要涉及的数据类型如下:

  • 定点实数/复数

  • 浮点复数

  • 伪浮点复数

定点实数/复数

下图是一个8位定点实数的Bit图,高四位是整数,第四位是小数。实数1.5对应表示为00011000。

定点的复数如下图为高32位为实部,低32位为虚部。0-12bit位为虚部的小数部分,13-31bit为虚部的整数部分。32-44bit为实部小数部分,45-63bit为实部的整数部分。

浮点复数

如下图所示,浮点复数的实部和虚部是由两个符合IEEE754标准的单精度短浮点数的标准的32位数表示。

单精度短浮点数的由1位符号位,8位指数位和23位有效数字位构成。实际上有效数字位是24位,因为第一位有效数字总是“1”,不必存储。有效数字位是一个二进制纯小数。8位指数位中第一位是符号位,这符号位和一般的符号位不同,它用“1”代表正,用”0“代表负。整个单精度短浮点数的符号位用“1”代表负,“0”代表正。指数位为正代表有效数字位需要右移指数+1,为负则代表需要左翼左移指数按位取反。距离举个转换的例子:

==

伪浮点复数

伪浮点复数这种数据存储格式能够有效的减少内存压力,它将需要64位存储的浮点复数用32位来存储。结构如下:

实部和虚部都以14位数表示,他们的浮点位置由高4位计算得出。复数的实数部分数值=,复数的虚数部分数值=。下面举个例子,复数-7+4i在内存中以伪浮点复数存储为0x34002400。

Memory Map

雷达的MCU一般都是多核的,成本高一点的会是多个ARM核与DSP核,成本低一点的也会有ARM核与各种加速核。这些核心都有对RAM进行读写的需要。我们针对低成本芯片集成电路蓝本,大约简化以下几个主体。

  • Bus Master:ARM核,我们编写的代码就是跑在这个核心。

  • PREP:主要用于原始的AD回波数据的存储组织。

  • BB_DMA:Direct Memory Access.它可以解放核心,提供内存间拷贝的功能。也可以为诸如FFT这种核心提供内存块数据的逐条/个数据的读取等操作。

  • P1:提供在距离维之前的数据处理功能,包括幅相等校准与Zeros的工作。

  • P2:提供在速度维之前的数据处理工作,包括复数的累加求信号均值等操作。

  • FFT:提供快速傅里叶变化算法实现。

  • CFAR:提供各种恒虚警算法实现。

我们把RAM分为两部分,BUF1和BUF2,BUF1存储包括FFT的原始与结果数据,BUF2存储一些窗口数据。MCU中的每个核心都对RAM有不同位宽的读写需求,核心直接也有相互写入的需求。我们把数据想象成水流,而各个加速核想象成水处理池,而我们嵌入式工程师就像是水管工,将核心根据需要用RAM中的数据连接起来,来搭建一个信号处理流程。下表是这些核心与RAM不同位宽的读写关系图(纵向表头为请求方,表格中的读写是请求方的读写,横向为响应方)。

P1_ZO

P1_MUL

FFT

P2

CFAR

BUF1

BUF2

BUS Master

32/64读/写

32/64读/写

BB_DMA

16写

32写

32写

8/16/32/64读

8/16/32写

8/16/32/64读

8/16/32写

PREP

64写

P1

32写

32写

FFT

32写

16/32读

32写

P2

32写

32读

32写

32读

32写

CFAR

32读

64写

BUF1可以根据存储的数据种类进一步划分,比如可以划分为存储AD回波数据的区域,存储距离维FFT结果数据区,速度维FFT结果数据,这么存储可以进行更好的调试信号处理调试以及更灵活的信号处理流程搭建,但是一旦流程固定之后,我们完全可以将一些数据区域复用,比如ADC_SAMPLE_ADDR与FFT1D_CACHE_ADDR可以指向一个地址,这样处理可以大大减少对内存空间的压力。


除了上述的可供ARM核心读写的BUF1+BUF2内存区域(我们称之为原始数据区),具有加速核的雷达SOC还有一些"影子RAM",这么称呼是因为他们仿佛是原始数据区域的影子一样,这些区域ARM核心并不能直接写,但是可以读,每当我们向原始数据区写入的后,不同的影子RAM会自动写入对应原始数据经过一种固定运算或者更改存储格式后的数据.

正如上图,第一个影子RAM是对应原始复数数据经过i.e.abs,log2,log运算之后的幅度实数数据,CFAR加速核进行相应算法的原始数据就来自这里。第二个影子RAM是对应以伪浮点数存储的原始数据以符合IEEE754标准的浮点数进行存储,P1/2的涉及的一些复数运算来源于这里。


十六宿舍 原创作品,转载必须标注原文链接。
©2023 Yang Li. All rights reserved.
欢迎关注 『十六宿舍』 ,大家喜欢的话,给个 👍 ,更多关于嵌入式相关技术的内容持续更新中。

相关文章:

车载雷达实战之Firmware内存优化

内存&#xff08;Memory&#xff09;是计算机中最重要的部件之一&#xff0c;计算机运时的程序以及数据都依赖它进行存储。内存主要分为随机存储器&#xff08;RAM&#xff09;,只读存储器&#xff08;ROM&#xff09;以及高速缓存&#xff08;Cache&#xff09;。仅仅雷达的原…...

【剑指Offer】JZ14--剪绳子

剪绳子详解1.问题描述2.解题思路3.具体实现1.问题描述 2.解题思路 首先想到的思路&#xff1a;因为是求乘积的最大值&#xff0c;所以如果截取剩下的是1&#xff0c;那还是它本身就没有意义。从此出发&#xff0c;考虑绳子长度是2、3、4、5…通过穷举法来找规律。 值–》拆分–…...

raspberry pi播放音视频

文章目录目的QMediaPlayerGStreamerwhat is GStreamer体系框架优势omxplayerwhat is omxplayercommand Linekey bindings运行过程中错误ALSA目的 实现在树莓派下外接扬声器&#xff0c; 播放某段音频&#xff0c; 进行回音测试。 QMediaPlayer 首先我的安装是5.11版本。 优先…...

【电子学会】2022年12月图形化二级 -- 老鹰捉小鸡

老鹰捉小鸡 小鸡正在农场上玩耍&#xff0c;突然从远处飞来一只老鹰&#xff0c;小鸡要快速回到鸡舍中&#xff0c;躲避老鹰的抓捕。 1. 准备工作 &#xff08;1&#xff09;删除默认白色背景&#xff0c;添加背景Farm&#xff1b; &#xff08;2&#xff09;删除默认角色小…...

C++的双端队列

双端队列介绍1.双端队列知识需知2.大试牛刀1.双端队列知识需知 由于队列是一种先进先出&#xff08;FIFO&#xff09;的数据结构&#xff0c;因此无法直接从队列的底部删除元素。如果希望从队列的底部删除元素&#xff0c;可以考虑使用双端队列&#xff08;deque&#xff09;。…...

【独家】华为OD机试 - 拼接 URL(C 语言解题)

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...

为什么使用Junit单元测试?Junit的详解

Hi I’m Shendi 为什么使用Junit单元测试&#xff1f;Junit的详解 Junit简介 Junit是一个Java语言的单元测试框架。 单元测试是一个对单一实体&#xff08;类或方法&#xff09;的测试 JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架&#xff08;regression test…...

怎么学好嵌入式Linux系统和驱动

嵌入式专业是一门实践性非常强的学科&#xff0c;只有多动手&#xff0c;多实践&#xff0c;多编程&#xff0c;多调试&#xff0c;多看书&#xff0c;多思考才能真正掌握好嵌入式开发技术。 现在很多同学也意识到了学校培养模式和社会需求脱节问题&#xff0c;有一部分同学也先…...

Spring Aware总结

概述 Spring中Aware到底是什么意思&#xff1f; 我们在看Spring源码的时候&#xff0c;经常可以看到xxxAwarexxx的身影&#xff0c;通常我会很疑惑&#xff0c;Aware到底是什么意思呢&#xff1f; 比如图片中这些包含Aware关键字的类或者接口。 我对下面3个类或接口进行了解…...

【RocketMQ】源码详解:Broker端消息刷盘流程

消息刷盘 同步入口&#xff1a;org.apache.rocketmq.store.CommitLog.GroupCommitService 异步入口&#xff1a;org.apache.rocketmq.store.CommitLog.FlushRealTimeService 刷盘有同步和异步两种&#xff0c;在实例化Commitlog的时候&#xff0c;会根据配置创建不同的服务 p…...

编码器SIQ-02FVS3驱动

一.简介 此编码器可以是功能非常强大&#xff0c;可以检测左右转动&#xff0c;和按键按下&#xff0c;所以说这一个编码器可以抵三个按键&#xff0c;而且体积非常小&#xff0c;使用起来比三个按键要高大尚&#xff0c;而且驱动也简单。唯一不足的点就是价格有点小贵6-8元才…...

【2021.9.7】记一次exe手动添加shellcode

【2021.9.7】记一次exe手动添加shellcode 文章目录【2021.9.7】记一次exe手动添加shellcode0.大致思路1.获取MessageBox的真实地址VA2.通过OD在代码段添加shellcode3.dump出数据,设置程序OEP4.测试dump出来的exe5.方法总结测试的exe和添加了shellcode的exe&#xff1a;链接&…...

常用训练tricks,提升你模型的鲁棒性

目录一、对抗训练FGM(Fast Gradient Method): ICLR2017代码实现二、权值平均1.指数移动平均&#xff08;Exponential Moving Average&#xff0c;EMA&#xff09;为什么EMA会有效&#xff1f;代码实现2. 随机权值平均&#xff08;Stochastic Weight Averaging&#xff0c;SWA&a…...

具有精密内部基准的 DACx0502 简介及驱动应用示例

DACx0502 说明 16 位 DAC80502、14 位 DAC70502 和 12 位DAC60502 (DACx0502) 数模转换器 (DAC) 均为具有电压输出的高精度、低功耗器件。 DACx0502 线性度小于 1LSB。凭借高精度和微型封装特性&#xff0c;DACx0502 非常适合以下 应用&#xff1a; 增益和失调电压校准、电流…...

C语言函数:字符串函数及模拟实现strncpy()、strncat()、strncmp()

C语言函数&#xff1a;字符串函数及模拟实现strncpy()、strncat()、strncmp() 在了解strncpy、strncat()、前&#xff0c;需要先了解strcpy()、strncat()&#xff1a; C语言函数&#xff1a;字符串函数及模拟实现strlen() 、strcpy()、 strcat()_srhqwe的博客-CSDN博客 strncp…...

学术论文插图要求简介

1. 类型 位图和矢量图是两种不同的图像类型&#xff0c;它们在存储和处理图像时使用不同的方法。以下是它们之间的详细区别&#xff1a; 图像构成方式&#xff1a;位图使用像素&#xff08;或图像的最小单元&#xff09;来构建图像&#xff0c;每个像素都有自己的颜色和亮度值。…...

【独家】华为OD机试 - 斗地主 2(C 语言解题)

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...

力扣-计算特殊奖金

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1873. 计算特殊奖金二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总…...

华为校招机试真题目录

专栏介绍 本专栏将逐步收集历年华为校招算法真题 专栏权益 每篇博客都包含: 算法考点解析(文字+画图)算法源码(支持 Java / JS / Python)每晚9:00 ~ 11:00 在线答疑 真题目录 时间题目考点 or 实现2022.11.27...

EdgeYOLO学习笔记

EdgeYOLO学习笔记 EdgeYOLO: An Edge-Real-Time Object Detector Abstract 本文基于最先进的YOLO框架&#xff0c;提出了一种高效、低复杂度、无锚的目标检测器&#xff0c;该检测器可以在边缘计算平台上实时实现。为了有效抑制训练过程中的过拟合&#xff0c;我们开发了一种…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...