[PSOC™] 【英飞凌 CY8CKIT-062S2-AI评测】03雷达传感器存在检测

[复制链接]
90|0
EPTmachine 发表于 2025-11-17 09:47 | 显示全部楼层 |阅读模式

upload 附件:02_radar_presence.zip存在检测是雷达传感器常见的一种应用,英飞凌的雷达芯片有相关的DSP支持库用于处理雷达芯片采集到的数据,用于检测区域内的存在检测。同时也有相关的示例程序说明如何使用相关的库函数。

【英飞凌 CY8CKIT-062S2-AI评测】-02雷达芯片初始化和测试
https://bbs.21ic.com/icview-3495993-1-1.html
(出处: 21ic电子技术开**坛)

上述帖子中介绍如何初始化雷达芯片和对其进行测试,本文介绍处理雷达数据用于存在检测。

1、添加FreeRTOS和Sensor-dsp驱动库

英飞凌的library-manager工具可以方便地管理工程中使用的软件组件,通过调用 make library-manager指令即可打开工程的库管理工具,或者使用IDE中对应的工具。VSCode的ModusToolbox扩展中也提供相应的按键用于调用library-manager工具。

VSCode_lib_manager.png

使用library-manager添加FreeRTOS和sensor-dsp支持库。

freertos_lib.png

sensor_dsp_lib.png

更新工程后,可以查看当前工程中使用到的库包括用于串口重定向的retarget-io、freertos支持库、雷达传感器的sensor-xensiv-bgt60trxx库以及传感器信号处理相关的sensor-dsp。

project_libs.png

2、FreeRTOS使用

ModusToolbox中添加的库组件以代码仓库的形式保存在的 mtb_share文件夹中,通过工程中xxx.code-workspace文件打开VSCode,可以在左侧的文件树视图中看到 mtb_share文件夹中的内容。

mtb_share_dir.png

FreeRTOS组件中除了包含FreeRTOS相关的源码,在doc文件夹中有相关的使用说明。

freertos_doc.png

在工程的Makefile文件中,在 COMPONENTS变量中添加FREERTOS

COMPONENTS += FREERTOS

从雷达存在检测示例程序中复制其中的 FreeRTOSConfig.h文件到工程的source文件夹中,使用已经配置好的环境,或者从FreeRTOS仓库的 Source/portable/COMPONENT_(CORE)*路径中复制和芯片内核对应的 FreeRTOSConfig.h文件,并对其进行修改。

在代码中添加FreeRTOS相关的头文件,即可创建FreeRTOS应用程序。

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

3、雷达信号处理

在英飞凌的存在检测示例程序中,可以看到其中有关雷达数据梳理的时序图如下。

system-flow.png

雷达芯片FIFO中的数据就绪后产生中断,MCU接收到中断后读取FIFO中的数据到缓存区,缓存区中的数据达到算法需要的数据后,对对其进行数据处理,进行物体存在检测。

3.1 雷达FIFO数据获取

雷达芯片的数据就绪并产生中断通知MCU读取FIFO中的采样数据,sensor-xensiv-bgt60trxx库中提供相关的fifo处理函数,通过调用 xensiv_bgt60trxx_get_fifo_data读取雷达芯片fifo中的缓存数据。

/*******************************************************************************
* Function Name: read_radar_data
********************************************************************************
* Summary:
* This is the function for reading radar data using buffering
*
* Parameters:
*  * data: pointer to radar data
*  *num_samples: pointer to number of samples per frame
*  samples_ub: maximum number of samples to be copied at a time from owner task/caller
*
* Return:
*  int32_t: 0 if success
*
*******************************************************************************/
int32_t read_radar_data(uint16_t* data, uint32_t *num_samples, uint32_t samples_ub)
{
    if (xensiv_bgt60trxx_get_fifo_data(&bgt60_obj.dev,
            data,
            NUM_SAMPLES_PER_FRAME) == XENSIV_BGT60TRXX_STATUS_OK)
    {
        *num_samples = NUM_SAMPLES_PER_FRAME *2; // in bytes

        if (samples_ub < NUM_SAMPLES_PER_FRAME *2)
        {
            xensiv_bgt60trxx_soft_reset(&bgt60_obj.dev,XENSIV_BGT60TRXX_RESET_FIFO );
        }
    }

    return 0;
}

3.2 数据采集和处理

定义两个FreeRTOS任务,main_task实现

  • processing_task的创建;
  • 雷达外设的初始化;
  • 雷达缓存数据的读取以及数据的预处理;

processing_task实现

  • 初始化存在检测算法运行的环境;
  • 接收预处理数据的通知,并执行存在检测算法,输出结果到串口终端;
/* RTOS tasks */
#define MAIN_TASK_NAME                      "main_task"
#define MAIN_TASK_STACK_SIZE                (configMINIMAL_STACK_SIZE * 4)
#define MAIN_TASK_PRIORITY                  (configMAX_PRIORITIES - 2)
#define PROCESSING_TASK_NAME                "processing_task"
#define PROCESSING_TASK_STACK_SIZE          (configMINIMAL_STACK_SIZE * 4)
#define PROCESSING_TASK_PRIORITY            (configMAX_PRIORITIES - 3)

static void main_task(void *pvParameters);
static void processing_task(void *pvParameters);

读取雷达FIFO中的数据并缓存,对接收的数据量进行判断,是否满足进行存在检测的数据量,示例程序中提供相关数据的缓存结构体 manager_state_s和操作函数接口 radar_data_manager_s

manager_state_s用于管理数据缓存区和内存分配的接口函数,在使用FreeRTOS时,使用Notify功能实现雷达数据的订阅功能,可以供多个程序读取。

#ifdef FREERTOS_AWARE

/*
 *\def typedef struct  subscribed_task_lists_s
 *
 * Attributes pertaining to every subscriber task
 */
typedef struct {

    bool data_read; /*<<indicate and mark if task has read the data*/

    TaskHandle_t suscriber_task_handle; /*<<The FREERTOS Task handle representing subscriber task*/

}subscribers_task_lists_s;

#endif


/*
 *\def typedef struct  manager_state_s
 *
 * Attributes for managing radar data.
 */
typedef struct {

    uint8_t *buffer; /*<< Pointer to heap for FIFO buffer allocation*/

    uint32_t buff_size; /*<< Total size of buffer in bytes FIFO buffer */

    uint32_t samples; /*<< Total number of bytes in FIFO */

    uint32_t head,tail; /*<< front and back positions of the FIFO queue*/

    uint32_t fill_level; /*<< FIFO water mark level in bytes*/

    uint8_t subscribers; /*<< Number of subscribers (task/callers)*/

#ifdef FREERTOS_AWARE
    subscribers_task_lists_s subscriptions[ACTIVE_SUBSCRIPTION_UB + 1]; /*<<list of all subscriber tasks of type \ref subscribers_task_lists_s*/
#else
    cb_radar_data_event subscriptions[ACTIVE_SUBSCRIPTION_UB + 1]; /*<<list of all subscriber tasks of type \ref cb_radar_data_event*/
#endif

    void* (*malloc_func)(size_t size); /*<<Hold reference to consumer supplied memory allocation*/

    void (* free_func)(void* ptr); /*<Hold reference to consumer supplied definition for releasing allocated memory<*/

}manager_state_s;

操作函数接口 radar_data_manager_s提供数据操作接口,其中 in_read_radar_data有外部提供,用于雷达数据缓存到buffer中的数据输入部分,read_from_buffer用buffer中数据的输出。run用于对缓存区数据的管理以及通知订阅任务读取数据。具体的函数实现可以查看示例中的源码。

/*
 * [url=/u/typedef]@typedef[/url] typedef void (*cb_radar_data_event)(void* data_ptr, uint32_t size)
 * Data subscriber callback prototype. The subscriber's callback function must follow this prototype.
 */
typedef void (*cb_radar_data_event)(void* data_ptr, uint32_t size);


/*
 * @typedef typedef struct  radar_data_manager_s
 * Radar Data Manager (RDM) interface .
 */
typedef struct {
int32_t (*in_read_radar_data) (uint16_t* data, uint32_t *num_samples, uint32_t samples_ub);
#ifdef FREERTOS_AWARE
int32_t (*subscribe)(TaskHandle_t subscriber_task);
int32_t (*read_from_buffer)(int32_t subscription_id, uint16_t **data_ptr, uint32_t *size);
void (*ack_data_read)(int32_t subscription_id);
void (*run)(bool run_from_isr);
#else
int32_t (*subscribe)(cb_radar_data_event call_back);
void (*run)(void);
#endif
void (*unsubscribe)(int32_t subscription_id);
int32_t (*set_fill_level)(int32_t fill_level);
int32_t (*get_fill_level)(void);
}radar_data_manager_s;

模块初始化时设置 in_read_radar_data的函数指针为从雷达FIFO中读取数据的函数 read_radar_date,并设置缓存区的大小以及数据可读的大小。

int main(void)
{
    ...
    mgr.in_read_radar_data = read_radar_data;
    radar_data_manager_init(&mgr, NUM_SAMPLES_PER_FRAME *6, NUM_SAMPLES_PER_FRAME *2);
    radar_data_manager_set_malloc_free(pvPortMalloc,vPortFree);
    ...
}

在需要读取数据的任务中调用订阅的接口。这样在任务的循环部分,等待通知即可实现雷达数据的传递。

static __NO_RETURN void main_task(void *pvParameters)
{
    mgr.subscribe(main_task_handler);

    for(;;)
    {
        /* Wait for the GPIO interrupt to indicate that another slice is available */
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        mgr.read_from_buffer(1, &data_buff, &sz);
    }
}

接收的雷达原始数据需要进行格式转换和归一化处理。输出预处理完成后,通知 processing_task对数据进行处理

static __NO_RETURN void main_task(void *pvParameters)
{

    for(;;)
    {
        /* Data preprocessing */
        uint16_t *bgt60_buffer_ptr = data_buff;
        float32_t *frame_ptr = &frame[0];
        for (int32_t sample = 0; sample < NUM_SAMPLES_PER_FRAME * 2; ++sample)
        {
            *frame_ptr++ = ((float32_t)(*bgt60_buffer_ptr++) / 4096.0F);
        }

        mgr.ack_data_read(1);

        /* calculate the average of the chirps first */
        arm_fill_f32(0, avg_chirp, NUM_SAMPLES_PER_CHIRP);

        for (int chirp = 0; chirp < NUM_CHIRPS_PER_FRAME * 2; chirp++)
        {
            arm_add_f32(avg_chirp, &frame[NUM_SAMPLES_PER_CHIRP * chirp], avg_chirp, NUM_SAMPLES_PER_CHIRP);
        }

        arm_scale_f32(avg_chirp, 1.0f / NUM_CHIRPS_PER_FRAME, avg_chirp, NUM_SAMPLES_PER_CHIRP);

        if(ce_app_state.last_reported_event.timestamp != last_timestamp)
        {
            last_timestamp = ce_app_state.last_reported_event.timestamp; // save latest timestamp
        }

        /* Tell processing task to take over */
        xTaskNotifyGive(processing_task_handler);
    }
}

雷达存在检测的算法在英飞凌官方示例中的 xensiv_radar_presence.c/h中提供相关的源码,将文件复制到工程中,并引用头文件即可使用。调用 xensiv_radar_presence_process_frame对预处理的雷达帧数据处理,可以得到存在检测的结果。

static __NO_RETURN void processing_task(void *pvParameters)
{
    (void)pvParameters;

    xensiv_radar_presence_handle_t handle;
    //cy_rslt_t result;

    xensiv_radar_presence_set_malloc_free(pvPortMalloc,
                                          vPortFree);

    if (xensiv_radar_presence_alloc(&handle, &default_config) != 0)
    {
        CY_ASSERT(0);
    }

    xensiv_radar_presence_set_callback(handle, presence_detection_cb, NULL);

    for(;;)
    {
        /* Wait for frame data available to process */
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        xensiv_radar_presence_process_frame(handle, avg_chirp, xTaskGetTickCount() * portTICK_PERIOD_MS);
        process_verbose_cmd(handle, xTaskGetTickCount() * portTICK_PERIOD_MS);
    }
}

在存在检测的回调函数中,根据结果输出不同的信息,或者执行其他函数调用供程序的其余部分调用。

void presence_detection_cb(xensiv_radar_presence_handle_t handle,
                           const xensiv_radar_presence_event_t* event,
                           void *data)
{
    (void)handle;
    (void)data;

    if (!ce_app_state.verbose)
    {
        switch (event->state)
        {
            case XENSIV_RADAR_PRESENCE_STATE_MACRO_PRESENCE:
                cyhal_gpio_write(USER_LED1, true);
                cyhal_gpio_write(USER_LED2, false);
                printf("[INFO] macro presence %" PRIi32 " %" PRIi32 "\n",
                        event->range_bin,
                        event->timestamp);
                break;

            case XENSIV_RADAR_PRESENCE_STATE_ABSENCE:
                printf("[INFO] absence %" PRIu32 "\n", event->timestamp);
                cyhal_gpio_write(USER_LED1, false);
                cyhal_gpio_write(USER_LED2, true);
                break;

            default:
                printf("[MSG] ERROR: Unknown reported state in event handling\n");
                break;
        }

    }

    /* save the last reported event state */
    ce_app_state.last_reported_event = *event;
}

程序编译并下载到开发板后的输出如下,存在检测的结果根据检测区域内的变化而产生输出。

radar_presence_detect.png

4、总结

英飞凌雷达存在检测的示例代码结构清晰,而且都是公开的源码,对于学习使用英飞凌雷达存在检测开发是很好的学习材料。
upload 附件:01_Radar_Test_Mode.zip

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

693

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部