车载雷达实战之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内存优化
内存(Memory)是计算机中最重要的部件之一,计算机运时的程序以及数据都依赖它进行存储。内存主要分为随机存储器(RAM),只读存储器(ROM)以及高速缓存(Cache)。仅仅雷达的原…...
【剑指Offer】JZ14--剪绳子
剪绳子详解1.问题描述2.解题思路3.具体实现1.问题描述 2.解题思路 首先想到的思路:因为是求乘积的最大值,所以如果截取剩下的是1,那还是它本身就没有意义。从此出发,考虑绳子长度是2、3、4、5…通过穷举法来找规律。 值–》拆分–…...
raspberry pi播放音视频
文章目录目的QMediaPlayerGStreamerwhat is GStreamer体系框架优势omxplayerwhat is omxplayercommand Linekey bindings运行过程中错误ALSA目的 实现在树莓派下外接扬声器, 播放某段音频, 进行回音测试。 QMediaPlayer 首先我的安装是5.11版本。 优先…...
【电子学会】2022年12月图形化二级 -- 老鹰捉小鸡
老鹰捉小鸡 小鸡正在农场上玩耍,突然从远处飞来一只老鹰,小鸡要快速回到鸡舍中,躲避老鹰的抓捕。 1. 准备工作 (1)删除默认白色背景,添加背景Farm; (2)删除默认角色小…...
C++的双端队列
双端队列介绍1.双端队列知识需知2.大试牛刀1.双端队列知识需知 由于队列是一种先进先出(FIFO)的数据结构,因此无法直接从队列的底部删除元素。如果希望从队列的底部删除元素,可以考虑使用双端队列(deque)。…...
【独家】华为OD机试 - 拼接 URL(C 语言解题)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...
为什么使用Junit单元测试?Junit的详解
Hi I’m Shendi 为什么使用Junit单元测试?Junit的详解 Junit简介 Junit是一个Java语言的单元测试框架。 单元测试是一个对单一实体(类或方法)的测试 JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression test…...
怎么学好嵌入式Linux系统和驱动
嵌入式专业是一门实践性非常强的学科,只有多动手,多实践,多编程,多调试,多看书,多思考才能真正掌握好嵌入式开发技术。 现在很多同学也意识到了学校培养模式和社会需求脱节问题,有一部分同学也先…...
Spring Aware总结
概述 Spring中Aware到底是什么意思? 我们在看Spring源码的时候,经常可以看到xxxAwarexxx的身影,通常我会很疑惑,Aware到底是什么意思呢? 比如图片中这些包含Aware关键字的类或者接口。 我对下面3个类或接口进行了解…...
【RocketMQ】源码详解:Broker端消息刷盘流程
消息刷盘 同步入口:org.apache.rocketmq.store.CommitLog.GroupCommitService 异步入口:org.apache.rocketmq.store.CommitLog.FlushRealTimeService 刷盘有同步和异步两种,在实例化Commitlog的时候,会根据配置创建不同的服务 p…...
编码器SIQ-02FVS3驱动
一.简介 此编码器可以是功能非常强大,可以检测左右转动,和按键按下,所以说这一个编码器可以抵三个按键,而且体积非常小,使用起来比三个按键要高大尚,而且驱动也简单。唯一不足的点就是价格有点小贵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:链接&…...
常用训练tricks,提升你模型的鲁棒性
目录一、对抗训练FGM(Fast Gradient Method): ICLR2017代码实现二、权值平均1.指数移动平均(Exponential Moving Average,EMA)为什么EMA会有效?代码实现2. 随机权值平均(Stochastic Weight Averaging,SWA&a…...
具有精密内部基准的 DACx0502 简介及驱动应用示例
DACx0502 说明 16 位 DAC80502、14 位 DAC70502 和 12 位DAC60502 (DACx0502) 数模转换器 (DAC) 均为具有电压输出的高精度、低功耗器件。 DACx0502 线性度小于 1LSB。凭借高精度和微型封装特性,DACx0502 非常适合以下 应用: 增益和失调电压校准、电流…...
C语言函数:字符串函数及模拟实现strncpy()、strncat()、strncmp()
C语言函数:字符串函数及模拟实现strncpy()、strncat()、strncmp() 在了解strncpy、strncat()、前,需要先了解strcpy()、strncat(): C语言函数:字符串函数及模拟实现strlen() 、strcpy()、 strcat()_srhqwe的博客-CSDN博客 strncp…...
学术论文插图要求简介
1. 类型 位图和矢量图是两种不同的图像类型,它们在存储和处理图像时使用不同的方法。以下是它们之间的详细区别: 图像构成方式:位图使用像素(或图像的最小单元)来构建图像,每个像素都有自己的颜色和亮度值。…...
【独家】华为OD机试 - 斗地主 2(C 语言解题)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...
力扣-计算特殊奖金
大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目: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框架,提出了一种高效、低复杂度、无锚的目标检测器,该检测器可以在边缘计算平台上实时实现。为了有效抑制训练过程中的过拟合,我们开发了一种…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
