有效帧频率作为雷达一个非常核心的指标,它代表了雷达探测识别的速度,速度越快,后级各项智能驾驶功能就能得到更快、更有效的判断。本篇文章首先从硬件的角度,提供了一种合理利用片上资源提高探测识别速度的常用方法,然后又根据不同芯片平台资源情况,提供了两种嵌入式软件能够提高有效帧频率的两种方法,为各位读者在类似的工作中提供一些思路。
目录
利用DMA实现乒乓操作
设计步骤与注意事项
软件流程图与代码
瓶颈优化策略
“乒乓操作”是一种典型的用空间换时间操作,它本身并不能弥补高速数据流与低速计算单元之间的矛盾,高速数据流还是要“等待”低速运算完成,但是“乒乓操作”给高速数据流提供了两条独立的数据存储的链路,使得运算单元能够提前起跑,降低了整个链路的时间。
在雷达编程中这种乒乓操作实现在高速ADC采样和FFT运算之间,这里读者可以把DMA想象成一个专用的核心,它的功能仅仅是对数据进行搬运。DMA通常用于将数据传输到一个缓冲器,同时 CPU使用另一个缓冲器进行FFT运算。如下图所示,蓝色路径显示 DMA 将数据传输到缓冲区 1,CPU 从缓冲区 2 获取数据。当路径切换时,DMA 将数据传输到缓冲区 2,CPU 从 缓冲区 1 获取数据。这种技术的好处是整个应用程序的运行时更短,因为 CPU 在任何时候都可以自由地对一部分 数据进行操作。在该示例中,ADC 配置为单次转换模式,DMA 和 CPU 将在每次转换后在缓冲区之间切换。
设计步骤如下:
设计要注意的事项如下:
软件流程图如下:
Ti实现代码如下,用户可以根据注释获得这种“乒乓操作”更直观的认识。
/*
* Copyright (c) 2021, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ti_msp_dl_config.h"
#define ADC_SAMPLE_SIZE (64)
/* When FIFO is enabled 2 samples are compacted in a single word */
#define ADC_FIFO_SAMPLES (ADC_SAMPLE_SIZE / 2)
uint16_t gADCSamplesPing[ADC_SAMPLE_SIZE];
uint16_t gADCSamplesPong[ADC_SAMPLE_SIZE];
volatile bool gCheckADC;
int main(void) {
uint16_t maxReading;
bool ping = true;
uint16_t *ADCSamplesCurrDataPtr;
SYSCFG_DL_init();
/* Configure DMA source, destination and size */
DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID,
(uint32_t)DL_ADC12_getFIFOAddress(ADC12_0_INST));
DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)&gADCSamplesPing[0]);
DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_FIFO_SAMPLES);
DL_DMA_Full_Ch_setEarlyInterruptThreshold(
DMA, DMA_CH0_CHAN_ID, DL_DMA_EARLY_INTERRUPT_THRESHOLD_HALF);
DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
/* Setup interrupts on device */
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
gCheckADC = false;
DL_ADC12_enableConversions(ADC12_0_INST);
DL_ADC12_startConversion(ADC12_0_INST);
while (1) {
while (false == gCheckADC) {
__WFE();
}
// Breakpoint here to check the buffers and watch the ping pong operation.
// The data should be alternating between each buffer.
__BKPT(0);
if (ping) { // Switch to pong
ADCSamplesCurrDataPtr = gADCSamplesPing;
DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)&gADCSamplesPong[0]);
DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_FIFO_SAMPLES);
DL_DMA_Full_Ch_setEarlyInterruptThreshold(
DMA, DMA_CH0_CHAN_ID, DL_DMA_EARLY_INTERRUPT_THRESHOLD_HALF);
DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
gCheckADC = false;
ping = false;
DL_ADC12_enableDMA(ADC12_0_INST);
DL_ADC12_enableConversions(ADC12_0_INST);
DL_ADC12_startConversion(ADC12_0_INST);
} else { // Switch to Ping
ADCSamplesCurrDataPtr = gADCSamplesPong;
DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)&gADCSamplesPing[0]);
DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_FIFO_SAMPLES);
DL_DMA_Full_Ch_setEarlyInterruptThreshold(
DMA, DMA_CH0_CHAN_ID, DL_DMA_EARLY_INTERRUPT_THRESHOLD_HALF);
DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
gCheckADC = false;
ping = true;
DL_ADC12_enableDMA(ADC12_0_INST);
DL_ADC12_enableConversions(ADC12_0_INST);
DL_ADC12_startConversion(ADC12_0_INST);
}
}
}
void ADC12_0_INST_IRQHandler(void) {
switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
case DL_ADC12_IIDX_DMA_DONE:
gCheckADC = true;
break;
default:
break;
}
}
整个雷达工作周期的瓶颈,来自一头一尾:头调频连续波到ADC回波采样的射频模拟部分,尾是从点云到航迹目标的数据处理部分。针对这个头,可以针对产品情景进行一些包括调频时长等相关参数的调整来达到帧周期的缩短,这部分我就不赘述了,感兴趣的朋友可以从《雷达编程实战之功耗优化技术(低功耗)》文章中寻求到方法,而这篇文章主要针对这个数据处理的尾巴来讲一下两个优化的策略,而这两个优化策略主要针对两种不同平台资源的情况进行选择。
首先如果我们的芯片平台存在多个DSP核心以及ARM核心,那么我们完全可以合理分配计算资源,达到理论上最快的帧频率,下面是几点分配的原则。
如果我们芯片平台仅仅存在一个DSP核心和一个ARM核心,那么我们就需要为整体的产品性能来考虑一些事情了。依然有一个DSP核心承担了信号处理流程的计算工作,而且很有可能它已经没有多余的RAM空间来进行别的计算了,芯片本身很可能在设计之初就没有考虑要进行数据处理(直接出点云给域控制器),而如果我们要硬上(毕竟要做一些数据处理算法来当作研发亮点),那就只可能放在ARM来跑,不过很可惜,这个方案是个陷阱,下面我来介绍一种在这种平台跑算法的方案。
十六宿舍 原创作品,转载必须标注原文链接。
©2023 Yang Li. All rights reserved.
欢迎关注 『十六宿舍』,大家喜欢的话,给个,更多关于嵌入式相关技术的内容持续更新中。