雷达编程实战之Firmware内存优化

内存()是计算机中最重要的部件之一,计算机运时的程序以及数据都依赖它进行存储 。内存主要分为随机存储器(RAM),只读存储器(ROM)以及高速缓存(Cache) 。
仅仅雷达的原始回波数据(Radar data cube)就可能达MByte级别的数据体量,这对MCU的内存来说尺寸很大 。本篇文章主要介绍了在雷达嵌入式编程中会遇到的MPU(Unit)、Cache以及不同数据格式在内存中的存储格式和雷达基带涉及的加速核与内存区的映射 。总而言之,与内存相关的嵌入式编程以及优化方式会在本文中对其进行说明,并从内存优化的角度对可以应用的诸如 同址复用等思路进行说明 。MPU+Cache
Cache一致性问题一般发生在多核处理器上,单核处理器基本不用考虑这个问题 。
现在的处理器一般都有两级(,)甚至三级缓存,当核0读写外部存储器如DDR内的数据时,会将数据保存在和中 。后续如果该数据一直在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);
上面的代码为将对应地址空间执行了-操作,其的作用是将Cache写回到DDR中,之后Cache中的数据将会无效 。这种操作多用于读取核间共享的存储区域之前 。除了-操作,还有(将CACHE中的数据视为无效数据)以及(将CACHE中的数据写回存储器中如DDR)等操作 。
MPU定义了存储器不同地址空间的属性和存储器的访问权限 。MPU不会提升嵌入式应用的性能,而是用于系统中问题的检测(比如试图访问非法或者不允许的存储器位置所导致的应用错误) 。如果检测到有错误,则会触发异常 。实际上,许多微控制器用不到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 DisableExecInstruction access disable bit, 1= disable instruction fetches.* \param AccessPermissionData access permissions, allows you to configure read/write access for User and Privileged mode.* \param TypeExtFieldType extension field, allows you to configure memory access type, for example strongly ordered, peripheral.* \param IsShareableRegion is shareable between multiple bus masters.* \param IsCacheableRegion is cacheable, i.e. its value may be kept in cache.* \param IsBufferableRegion is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.* \param SubRegionDisableSub-region disable field.* \param SizeRegion 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); //0x30000000UMPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_32MB);