TI AWR1642 评估板 77G行人检测雷达代码分析(1)-main函数分析(MSS工程)

TI AWR1642 评估板 77G行人检测雷达代码分析(1)-main函数分析(MSS工程)

大家好,这里是电子与数学方法专栏,今天带领大家一起来分析 TI AWR1642评估板的行人检测代码,考虑到本代码的结构比较复杂,因此会分为很多部分进行拆解,走读完一个例程,可以举一反三,别的例程也就基本会了。

那么下面我们就开始吧。

首先我选择的例程是mmwave_industrial_toolbox_2_2_0\labs\lab0011-pplcount。

在开始之前,我想大家应该能够自己配置好雷达,并能够实现开机演示,这些教程在这个例程的docs文档中都有说明,按照步骤一步一步地来应该不会有问题。

一、工程结构
大家都知道AWR1642芯片是双核处理器,一个是DSP,另一个是AWR。所以工程也有两个,一个是DSS,在DSP处理器上运行,另一个是MSS,在AWR处理器上运行。如下图所示:

在这里插入图片描述
二、代码结构

1.main

int main (void)
{
    Task_Params     taskParams;
    int32_t         errCode;
    SOC_Cfg         socCfg;

    /* Initialize the ESM: */
    ESM_init(0U); //dont clear errors as TI RTOS does it

    /* Initialize and populate the demo MCB */
    memset ((void*)&gMmwMssMCB, 0, sizeof(MmwDemo_MCB));

    /* Initialize the SOC confiugration: */
    memset ((void *)&socCfg, 0, sizeof(SOC_Cfg));

    /* Populate the SOC configuration: */
    socCfg.clockCfg = SOC_SysClock_INIT;

    /* Initialize the SOC Module: This is done as soon as the application is started
     * to ensure that the MPU is correctly configured. */
    gMmwMssMCB.socHandle   = SOC_init (&socCfg, &errCode);
    if (gMmwMssMCB.socHandle  == NULL)
    {
        System_printf ("Error: SOC Module Initialization failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Initialize the DEMO configuration: */
    gMmwMssMCB.cfg.sysClockFrequency = MSS_SYS_VCLK;
    gMmwMssMCB.cfg.loggingBaudRate   = 921600;
    gMmwMssMCB.cfg.commandBaudRate   = 115200;
    gMmwMssMCB.pcEnable = 1;
    Cycleprofiler_init();

    /* Debug Message: */
    System_printf ("**********************************************\n");
    System_printf ("Debug: Launching the Millimeter Wave Demo\n");
    System_printf ("**********************************************\n");

    /* Initialize the Task Parameters. */
    Task_Params_init(&taskParams);
    taskParams.priority = 3;
    Task_create(MmwDemo_mssInitTask, &taskParams, NULL);

    /* Start BIOS */
    BIOS_start();
    return 0;
}

2.逐句分析:今天讲的是MSS部分
(1)

  Task_Params     taskParams;

这个是任务参数,在ccs中按F3可以进一步看到 :

   #define Task_Params ti_sysbios_knl_Task_Params;

可以看到这是sysbios系统的一个参数,不知道什么意思,继续F3:

  typedef struct ti_sysbios_knl_Task_Params   ti_sysbios_knl_Task_Params;

同样不明白是什么意思,

继续F3,可以看到:

 * ======== PER-INSTANCE TYPES ========
 */
/* Params */
struct ti_sysbios_knl_Task_Params {
    size_t __size;
    const void *__self;
    void *__fxns;
    xdc_runtime_IInstance_Params *instance;
    xdc_UArg arg0;
    xdc_UArg arg1;
    xdc_Int priority;
    xdc_Ptr stack;
    xdc_SizeT stackSize;
    xdc_runtime_IHeap_Handle stackHeap;
    xdc_Ptr env;
    xdc_Bool vitalTaskFlag;
    xdc_UInt affinity;
    xdc_runtime_IInstance_Params __iprms;
};

这里一个一个地看,大体上可以看出这些是后面操作系统执行任务所需要的一些参数,比如数据指针、堆栈、标志位、优先级等等。后面会有具体的解释,这里先暂时略过。我们继续返回mian往下看。

(2)

 int32_t         errCode;

这个就是简单地定义了一个参数,int型,32位的,这个参数的作用是用来接收后面函数执行的错误信息的,这暂时先不讲,后面详细说明。

(3)

  SOC_Cfg         socCfg;

这个是片上系统配置,CSS中按F3进一步细看。

typedef struct SOC_Cfg_t
{
    /**
     * @brief
     *  System clock configuration
     */
    SOC_SysClock        clockCfg;
}SOC_Cfg;

可以看到这是一个结构体,包含了1个元素,是系统时钟。继续F3进一步:

typedef enum SOC_SysClock_e
{
    /**
     * @brief
     *  System Clocks need to be initialized
     */
    SOC_SysClock_INIT           = 0x1,

    /**
     * @brief
     *  System Clocks initialization is bypassed
     */
    SOC_SysClock_BYPASS_INIT
}SOC_SysClock;

可以看到又是一个结构体,这里包含了两个元素,第一个是系统时钟,这个main后面会用到,另一个是系统时钟初始化被绕过,意思就是不进行初始化。好了,知道这个参数是干啥的就行了,现在我们继续返回main往下走。

(4)

   /* Initialize the ESM: */
    ESM_init(0U); //dont clear errors as TI RTOS does it

这个是初始化ESM驱动程序,参数为0是不清除错误,继续F3进一步:

/** @brief Function intializes the ESM driver
*
*    @param[in] bClearErrors: boolean value to indicate if old ESM pending errors should be cleared or not
*                             value = 0: do not clear
*                             value = 1: clear all ESM group errors
*                             hint: If you using TI RTOS, then ESM errors are cleared before
*                                   entering main and this flag can be set to 0. For any other RTOS, check the
*                                   the RTOS implementation or set this flag to 1
*
*    @return    Success -   Handle to the ESM Driver
*               Error   -   NULL
*
*/
extern ESM_Handle ESM_init(uint8_t bClearErrors);

这里的ESM是什么意思呢?

ESM驱动程序提供API,以配置和处理来自ESM硬件模块的错误。

ESM驱动程序需要在整个系统中初始化一次。 这是使用#ESM_init(0)函数完成, 未经调用,ESM 的API均无法使用。

不需要深刻理解ESM初始化是干啥的,知道他是为了处理错误或者配置硬件的就行了,一般驱动的主要作用都是和顶层硬件打交道。

(5)

    /* Initialize and populate the demo MCB */
    memset ((void*)&gMmwMssMCB, 0, sizeof(MmwDemo_MCB));

这句话有大用,memset函数都知道是对申请的内存空间的内容初始化,所以这句话的目的就是对申请一个超大的内存空间,来存储MSS工程执行的所有结构体元素的参数信息,这里将内部的所有内容全部置零。而且这MSS和DSS工程里面都是这样的结构,所有参数全部在结构里走,外部函数只需要用结构体参数就行了,数据都是隐含在结构体里的,需要用的时候就拿出来,用完之后又存回去,这个思想需要了解。

选中MmwDemo_MCB ,F3进一步看,是一个很大的结构体:

typedef struct MmwDemo_MCB_t
{
    /*! @brief   Configuration which is used to execute the demo */
    MmwDemo_Cfg                 cfg;

    /*! * @brief   Handle to the SOC Module */
    SOC_Handle                  socHandle;

    /*! @brief   UART Logging Handle */
    UART_Handle                 loggingUartHandle;

    /*! @brief   UART Command Rx/Tx Handle */
    UART_Handle                 commandUartHandle;

    /*! @brief   This is the mmWave control handle which is used
     * to configure the BSS. */
    MMWave_Handle               ctrlHandle;

    /*!@brief   Handle to the peer Mailbox */
   // Mailbox_Handle              peerMailbox;
    Mbox_Handle              peerMailbox;
    /*! @brief   Semaphore handle for the mailbox communication */
    Semaphore_Handle            mboxSemHandle;


    /*! @brief   Semaphore handle for the application task */
    Semaphore_Handle                    appSemHandle;
	
    /*! @brief   Point Cloud */
    MmwDemo_output_message_pointCloud   *pointCloud;

    /*! @brief   Target Descriptors */
    MmwDemo_targetDescrHandle   *targetDescrHandle;

    /*! @brief   Tracker Handle */
    void     					        *gtrackHandle;

    /*! @brief   MSS system event handle */
    Event_Handle                eventHandle;

    /*! @brief   Handle to the SOC chirp interrupt listener Handle */
    SOC_SysIntListenerHandle    chirpIntHandle;

    /*! @brief   Handle to the SOC frame start interrupt listener Handle */
    SOC_SysIntListenerHandle    frameStartIntHandle;

    /*! @brief   Data Path object: currently only for receiving data from DSS. Potentially adding other block such as tracking here*/
    MmwDemo_MSS_DataPathObj     mssDataPathObj;

    /*! @brief   Has the mmWave module been opened? */
    bool                        isMMWaveOpen;

    /*! @brief   mmw Demo stats */
    MmwDemo_MSS_STATS           stats;

    /*! @brief Enable Sending Point cloud data */
    bool                        pcEnable;
} MmwDemo_MCB;

包含了系统配置、串口配置、数据参数等等,继续打开每一个结构体还有很多,这里我就不一一展开了,现在回到main继续往下走。

(6)

 memset ((void *)&socCfg, 0, sizeof(SOC_Cfg));
 

这句话与上一句一样,都是初始化ocCfg参数为0,不过这里参数不多。

(7)

  /* Populate the SOC configuration: */
    socCfg.clockCfg = SOC_SysClock_INIT;

看到没,来了,系统时钟设定。

(8)

gMmwMssMCB.socHandle   = SOC_init (&socCfg, &errCode);
 if (gMmwMssMCB.socHandle  == NULL)
    {
        System_printf ("Error: SOC Module Initialization failed [Error code %d]\n", errCode);
        return -1;
    }

这句话的意思是,初始化SOC模块,启动应用程序后立即完成,以确保正确配置MPU。

我们看这个函数的参数,是不是用到了之前的系统时钟socCfg和errCode,这里就把SOC系统给初试化了,然后还添加了校验。而且还要注意的是现在的参数全部都是包含在gMmwMssMCB这个大的结构体中。

(9)

    /* Initialize the DEMO configuration: */
    gMmwMssMCB.cfg.sysClockFrequency = MSS_SYS_VCLK;
    gMmwMssMCB.cfg.loggingBaudRate   = 921600;
    gMmwMssMCB.cfg.commandBaudRate   = 115200;
    gMmwMssMCB.pcEnable = 1;
    Cycleprofiler_init();

这里是初始化DEMO配置,包含了MSS的系统时钟、串口的波特率,这里有两个串口,一个是数据、一个是控制。pc_Enable是启用发送点云数据,这里是和上位机有关系的,启动之后上位机可以接受到点云数据。

Cycleprofiler_init()这个函数的作用是:设置事件计数器的事件类型,并在计数器溢出时启用/禁用中断生成,此功能禁用/停止计数器,设置新的事件类型,启用/禁用中断生成,然后重新启用计数器(如果之前已启用)。就当他是一个计数器吧。

(10)

 /* Debug Message: */
    System_printf ("**********************************************\n");
    System_printf ("Debug: Launching the Millimeter Wave Demo\n");
    System_printf ("**********************************************\n");

打印信息,略。
(11)

Task_Params_init(&taskParams);
taskParams.priority = 3;
task_create(MmwDemo_mssInitTask, &taskParams, NULL);

这的三个函数,第一个是任务参数初始化,初始化的结果存在之前最开头定义的taskParams参数中。
第二个函数是任务的优先级设置,目前是3。
第三个函数是创建一个任务,参数有三个。第一个是MmwDemo_mssInitTask,这个参数是后面程序执行的主任务,第二个参数是任务参数,第三个参数是NULL。

这里我们只需要知道main里面创建了一个主任务就行了,其余的地方按F3也进不去了,程序都封装死的。

(12)

 /* Start BIOS */
    BIOS_start();

启动BIOS,便是启动SYS_BIOS操作系统 ,F3进不去,这里只要知道这是把操作系统启动就行了。真正的代码在MmwDemo_mssInitTask这个任务里面。

好了,MSS的main部分就讲完了,下期继续将MmwDemo_mssInitTask任务部分,敬请期待,有什么不明白的地方可以留言。

  • 10
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

调皮连续波(皮哥)

鼓励调皮哥继续在雷达领域创作!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值