摘要:

这篇博文衔接上一篇博文(main),在上一篇博文中创建了一个线程函数SRR_MSS_initTask,这时程序执行将会进入到SRR_MSS_initTask中,在这篇博文中将会对SRR_MSS_initTask函数分片段来描述它的作用,同样的并会对一些函数作用进行描述。这个函数的声明在 mms工程mss_main文件下的第112行,读者可以在main函数中在创建线程函数SRR_MSS_initTask的地方按住 Ctrl + 鼠标左键 跳转到SRR_MSS_initTask函数。SRR_MSS_initTask函数的主要作用是完成MSS初始化任务,以及初始化MSS子系统中的各个组件。

1.参数声明

进入到SRR_MSS_initTask函数中,映入我们眼帘的是一些参数的声明,接下来将会对这些参数的作用加以阐述,参数声明部分如下图所示,为了方便描述,将从上到下一一描述,并将他们命名为参数1,2,3…;

1)参数1

这个参数是用来填充错误代码的,程序一旦出现错误,将立即中断,并返回这个错误代码。

2)参数2

这是一个传感器配置参数,它是一个结构体,该结构指定了初始化和设置mmWave模块所需的配置。例如mmWave 模块正在执行的执行域等。

3)参数3

这是用来配置串口属性的结构体,参数用于UART_open()调用。 这些参数的默认值可以使用UART_Params_init()来设置。

4)参数4

线程参数,用于创建线程时用到的参数,这个结构体主要用于设置线程函数的属性,例如优先级等。

5)参数5

这是用于给系统注册中断监听器的配置参数,它是一个结构体,存储了初始化系统中断监听器所需的配置信息。

6)参数6

这是用于给系统创建信号量的配置参数,它是一个结构体,用于初始化系统信号量所需的配置信息。信号量是用来阻塞线程执行的,通俗来说就是一个开关作用,用来控制死循环的通断,线程函数中都是创建在一个死循环的基础上。

7)参数7

邮箱配置参数,邮箱配置参数与Mailbox_open()调用一起使用。 这些参数的默认值是使用Mailbox_Config_init()设置的。这个参数存储了邮箱配置的所需信息。邮箱的作用是用于BSS、MSS、DSS之间的交换信息。

最后便是向控制台打印编译信息,如果程序成功进入SRR_MSS_initTask中,则会显示编译信息,否则不然。

2.引脚复用

在程序参数声明之后,接下来就是引脚复用部分,在传感器芯片内部有很多外设,这些外设的引脚都是与I/O口复用的,也就是说,一个I/O口如果可以复用为内置外设的功能引脚,那么这个I/O作为内部外设使用的时候,就叫做复用。这一部分的代码片段如下所示,设置引脚复用首先需要设定选定引脚的输入输出方式,这个过程由Pinmux_Set_OverrideCtrl来完成的,之后就是对引脚增加功能,这是使用Pinmux_Set_FuncSel来完成的。在这个demo中,下列的代码主要作用是实现了与上位机完成交互使用的引脚,通俗的说就是设定了UART的引脚。

函数原型:

1)

描述

配置引脚输入输出控制

参数

[in] pin 等待配置的Pin管脚号

[in] outputCtrl 输出控件选择参数outputCtrl可以是以下值之一:

PINMUX_OUTPUT_EN

PINMUX_OUTPUT_DIS

PINMUX_OUTEN_RETAIN_HW_CTRL // 硬件控制下输出

[in] inputCtrl 输入控件选择参数inputCtrl可以是以下值之一:

PINMUX_INPUT_EN

PINMUX_INPUT_DIS

PINMUX_INPEN_RETAIN_HW_CTRL //硬件控制下输入

返回值

成功 - 0

错误 - <0

2)

描述

设置pin的功能。这个功能设置pin的功能个性。 指定的信号将被引脚引出。 因为没有对传递的参数进行严格检查,传递的值必须来自头文件pinmux.h中指定的宏。

参数

[in] pin 等待配置的Pin管脚号

[in] func 用户需要设定的功能,通常为SDK中已经定义的宏

3.驱动初始化

在调用驱动 API之前,必须先对这个驱动模块进行初始化,否则将无法调用驱动模块API。下面的代码片段分别对UART、GPIO、Mailbox驱动的初始化。在这里需要补充的是,由于pinmux驱动初始化是非必要的,所以在上述引脚复用中调用了pinmux驱动的API而没有事先初始化,这是因为pinmux驱动初始化是非必要的。

函数原型:

1)

描述

初始化UART模块。

2)

描述

初始化UART模块。

3)

描述

初始化邮箱模块。

参数

[in] LocalEndpoint 本地邮箱端点类型

返回值

在错误时返回错误代码

注意:

这里的邮箱初始化驱动类型是MSS类型,换句话说就是在主子系统中初始化邮箱。

4.启动串口(UART)实例

在驱动初始化之后,接下来就是启动或者说是打开串口实例,用于传感器与上位机进行交互,在下面代码片段中,启动串口实例首先需要对串口属性参数(uartParams)进行初始化为默认值,这个过程是由UART_Params_init API完成的,初始化为默认值后,用户可以根据需要更改串口属性值,例如在本例中更改cpu时钟频率为MSS_SYS_VCLK,波特率为115200,用户根据需要更改设置好串口属性值后,使用UART_open实例化串口,并返回控制句柄储存在全局变量中,紧接着就是通过if语句判断串口是否成功开启,如果返回的控制句柄为NULL则说明串口启动失败,并异常终止程序运行,且在控制台输出相应的错误信息,否则不然。

在下面的代码片段中,可以看到实例了两个串口,其中一个串口是用于上位机传递命令给传感器的,后一个串口是用于将收集的数据或经过处理好的数据传递给上位机可视化的。

函数原型:

1)

描述

函数将UART_Params类型的结构体初始化为默认值。

参数

[in] 用于初始化的指向UART_Params结构体的指针

2)

描述

函数初始化给定的UART外围设备。

参数

Index UART索引到UART_config表中的逻辑外设号

params 指向参数块的指针。 如果为NULL,则使用默认参数值。 该结构中的所有字段都是RO(只读)。

5.建立MSS与DSS的通信信道

启动串口实例之后,接下来就建立MSS与DSS相互通信的信道,这个信道也称为邮箱。在建立邮箱前,首先需要创建一个二进制的信号量,这个信号量用来阻塞邮箱信息。二进制信号的创建首先需要对信号量参数进行初始化,这通过Semaphore_Params_init来完成,初始化完成后,设置信号量的模式为二进制模式,并通过Semaphore_create创建信号量实例,返回控制这个信号量的句柄存储在全局变量中。信号量创建完成后,开始对邮箱配置参数初始化为默认参数,这个过程由Mailbox_Config_init来完成的,邮箱配置参数初始化完成后,用户可以根据需求来更改默认的配置参数,例如在下面的代码片段中,将邮箱信道类型设置为在DSS和MSS之间允许多个邮箱通道(每个方向),信道的ID号设置为0,邮箱的写入模式为阻塞模式(邮箱的读模式为回调模式,即每次邮箱中存入信息时,调用回调函数来读取邮箱中的信息),并将邮箱回调函数设置为MmwDemo_mboxCallback,这是一个自定义的邮箱读函数。

按住Ctrl + 鼠标左键跳转到这个回调函数,可以看到这个函数体如下;函数很简单,只有一行代码,这行代码的作用是释放一个信号量,这个回调函数在对等端在邮箱中存入一个消息时,也就是DSS将处理好的信息写入邮箱里时,邮箱中存入了信息,这时就需要MSS及时读取邮箱里的信息,读取完成后并删除信息,在DSS向邮箱中存入信息后就会执行一次这个回调函数,每回调一次,释放一次信号量,也就是执行一次任务线程,这里的这个线程函数就是在下一个代码片段中讲到的任务线程。

在配置邮箱信息完成后,将调用Mailbox_open API来启动邮箱,返回邮箱控制句柄存储在全局变量中,并通过if语句来判断邮箱通道是否成功开启,如果成功则返回的句柄不为空,否之则说明不成功,这时将会错误中断函数,并且在控制台显示错误类型信息。

函数原型:

1)

描述

函数将Mailbox_Config结构初始化为默认值。

参数

cfg   指向Mailbox_Config结构的指针,用于初始化

返回值

在失败时返回错误代码。

2)

描述

函数初始化邮箱驱动程序的实例。

参数

remoteEndpoint 此邮箱实例将与之通信的远程端点

cfg                 指向邮箱配置参数的指针。

errCode          指向函数返回的错误码值/状态的指针

返回值

成功时的Mbox_Handle。 如果发生错误,则为NULL。

6.创建线程函数来控制邮箱信息

在MSS与DSS之间通信的邮箱搭建好之后,就需要在MSS中读取来自DSS的邮箱信息,为了能够实时的处理邮箱信息,创建了一个线程函数MmwDemo_mboxReadTask来读取来之DSS的信息,同样的在创建邮箱信息时,需要先对线程参数初始化,这是在Task_Params_init中完成的,并设置线程函数的堆大小为16*1024,随后使用Task_create API创建了MmwDemo_mboxReadTask线程函数。该任务线程用于处理从邮箱虚拟通道接收的毫米波演示消息。

跳转进入到这个线程中,如下图可见,线程运行在一个while死循环中,在进入循环时,可以看到第一行Semaphore_pend(gSrrMSSMCB.mboxSemHandle, BIOS_WAIT_FOREVER)代码,是将任务线程悬挂起来,暂时不执行,一直等待到Semaphore_post (gSrrMSSMCB.mboxSemHandle)释放信号量时线程才开始执行,也就是说,每释放一次信号量,这个任务线程执行一次。在MSS中,当DSS向邮箱中写入消息时,将会执行一次邮箱回调函数,这个函数将释放一次信号量,即下面的任务线程将执行一次,读取DSS存入的消息,读取完消息后将这个消息删除,然后MSS读取完信息后并向邮箱中写入已经读取完成的信息,这时同样的在远程端将会触发DSS预先设定好的与MSS通信的邮箱回调函数。

关于上面这个读取邮箱信息的任务线程函数,不是本文的重点,我将会在另一篇博文(读取邮箱消息函数)中主要讲解这个任务线程。这篇博文重点讲程序代码的走向,以及每条代码的用处。

到这里为止,线程函数SRR_MSS_initTask走到了创建读取邮箱任务线程MmwDemo_mboxReadTask这里,在这里创建完线程后,并不会直接执行这个行程,只要原因上面已经提到了,被信号量阻塞了,需要等待信号量的释放才能执行。因此这时程序依旧往下走。

7.注册监听器

注册监听器,也可以说是定义中断。监听器的作用是用来给正在运行的系统一个中断信号,使系统优先处理中断事件,而后再接着运行。例如:你正在打游戏,但这时你的手机响了,你不得不暂停游戏,先去接电话,接完电话后,你于是又开始打游戏了,这里的把游戏比喻为正在运行的系统,而中断事件就是接电话,中断信号就是手机响了。

注册监听器的代码片段如下所示,从下面的代码片段中可以看到,系统注册了两个监听器,分别用于监听chirp事件和帧事件,也就是说,每一个chirp或一个帧(Frame)表示一个中断信号,当产生这些中断信号时,将会执行对应的中断事件。在注册监听器前,需要对监听器配置参数进行初始化,这个过程是由 memset来完成的,紧接着就是根据监听器的需求填充配置参数(在chirp监听器中,可以看到,监听器的属性systemInterrupt被设置为SOC_XWR16XX_MSS_CHIRP_AVAIL_IRQ ,而这个属性的作用就是注册的监听事件,也可以理解为上述中说到的中断信号,后面的宏值SOC_XWR16XX_MSS_CHIRP_AVAIL_IRQ表示每一个chirp完成时中断。第二个属性listenerFxn表示当系统完成本次中断时需要执行的回调函数,这里的回调函数为SRR_MSS_chirpIntCallback,第三个属性值arg为可选参数,用于在ISR上调用侦听器函数,通常默认填充为0。将上面的chirp监听器连起来就是当完成一个chirp事件时系统中断一次并执行一次回调函数SRR_MSS_chirpIntCallback里的程序。同理在Frame监听器中的过程也是一样的,即当系统发送完成一个帧周期时,系统中断一次并执行相应的回调函数SRR_MSS_frameStartIntCallback。到这里回调函数里的内容可是用户自定义的,由于传感器尚未运行程序还没走到这里,所以在这里暂时不讲解这里边的内容,在往后的文章中将会讲解。)在参数配置完成后,接下来就是执行监听器的注册,这个是由SOC_registerSysIntListener 函数完成的,并返回监听器的控制句柄存储在全局变量中,这个句柄主要的作用就是告诉系统,这个监听chirp的监听器已经被注册在系统中,如果句柄等于NULL,则表明注册失败,控制台将会显示错误信息,并直接错误退出程序。

函数原型:

1)

描述

该函数用于为系统中断注册一个监听器。 可以将多个监听器附加到一个系统中断,一旦中断被触发,SOC模块将确保注册的监听器被调用。

参数

handle                    SOC模块的句柄(这个句柄是SOC_init返回的)

ptrListenerCfg        指向监听器配置的指针

errCode                   错误时生成的错误代码

8.mmWave初始化

监听器注册完成后,接下来就是对整个毫米波模块进行初始化。毫米波传感器是由BSS,MSS,DSS组成的一个封闭系统,它们是如何联系在一起协同工作的,需要对毫米波传感器进行初始化来告诉它们是以何种方式运行的,这个过程是由MMWave_init来完成的。在进行mmWave模块初始化前,需要对初始化配置参数进行初始化为0,这是由memset来完成的,接着就是根据用户所需的工作模式来配置初始参数,接下来将会基于初始化配置参数的结构体来解析SRR demo的工作模式。下面是mmWave 初始化的代码片段。

这是mmWave模块配置参数initCfg的结构体原型

结构体的各属性

domain      mmWave模块正在执行的执行域,可以是在MSS,也可以是DSS,即mmWave_init是在MSS核中运行还是在DSS核中运行。

socHandle       SOC驱动的控制句柄(在执行mmWave_init前,必须执行SOC_init获得控制句柄)

eventFxn         应用程序提供的异步事件处理程序。 这是在接收来自BSS的异步事件时调用的

linkCRCCfg      与BSS交换的mmWave链接消息有一个校验和。 配置指定了CRC硬件*或软件要用于校验和计算和验证。

cfgMode         配置模式:Full或Minimal模式

executionMode  mmWave模块的执行模式。 在XWR16xx/XWR18xx/XWR68xx上,mmWave模块可以在以下两种模式中执行:

隔离模式-----只在DSS

隔离模式---只在MSS

协作模式---控制路径在DSS数据路径在MSS

协作模式---控制路径在MSS数据路径在DSS

cooperativeModeCfg  协同模式下:mmWave模块在DSS和MSS上同时执行。 该模块负责在域之间传递配置和异步事件。

在将mmWave模块的配置参数设置好之后,通过调用API MMWave_init对传感器进行初始化,并返回控制句柄存储在全局变量gSrrMSSMCB.ctrlHandle中,如果为空则初始化不成功,错误中断程序,并在控制台显示错误信息代码。

注意:

在mmWave初始化配置的参数中配置了几个回调函数,这些回调函数在发生相应的操作时才执行回调,例如initCfg.cooperativeModeCfg.cfgFxn   = &SRR_MSS_cfgFxn;表示到调用mmWave API  MMWave_config时执行回调SRR_MSS_cfgFxn,但是由于mmWave被配置为最小执行模式,所以MMWave_Config API不会被调用,所以这个回调函数也不会被调用。

函数原型:

1)

描述

该函数用于初始化mmWave控制模块。 需要在调用任何其他mmWave控件API之前调用此函数,例如: MMWave_sync API的调用。

参数

ptrCtrlInitCfg  指向控制初始化配置的指针

errCode        由API针对错误填充的编码错误代码

9.mmWave模块同步

在mmWave初始化之后,接下来就是要对mmWave控件进行同步,这是由 MMWave_sync 来完成的,代码片段如下;可以看到mmWave同步函数被写在一个while死循环中,这样做的好处是确认传感器中的mmWave模块间已经完成同步,当完成同步后将会退出这个循环。

函数原型:

1)

描述

该功能用于同步控制模块在执行域之间的执行。 建议应用程序调用该函数,直到实现“同步”。 如果不这样做,将导致mmWave模块的错误行为。

参数

mmWaveHandle      mmWave控制模块的句柄

errCode                     由API针对错误填充的编码错误代码

10.子帧chirp总数的获取

mmWave模块同步完成后,在本案例中根据需求提前对子帧中的chirp数量进行设定,并记录在全局变量中方便后续函数进行调用。值得注意的是,本案例将一个帧分成两个子帧,关于chirp以及更多的高级帧配置内容,已经在另一篇理论准备的博文中说明,这里不再赘述。在下面的代码片段中由于使用了条件编译语句,所以实际只运行了

gSrrMSSMCB.numChirpsPerSubframe[0] = SUBFRAME_SRR_NUM_CHIRPS_TOTAL;

gSrrMSSMCB.numChirpsPerSubframe[1] = SUBFRAME_USRR_NUM_CHIRPS_TOTAL;

这两句语句,其它的部分可以不用看。

注意

如果我们需要对mmWave雷达demo开发时,这部分内容并不是固定的,可以更加具体问题具体分析,但是在此前的代码模块基本上都是一个模板,所以学习毫米波雷达开发,还是比较容易入门的。

11.mmWave控制线程

在完成子帧chirp总数的获取之后,便创建任务线程SRR_MSS_mmWaveCtrlTask用于执行mmWave控件,mmWave模块需要一个由应用程序提供的执行上下文。 这是因为BSS使用mmWave Link基础设施接收异步事件和响应消息。 这些需要在应用程序提供的执行上下文中进行处理。 它的作用给mmWave控制模块提供一个执行背景平台吧,也可以说是一个执行上下文,这是必不可少的一部分。在创建线程前首先需要对线程参数进行参数,这是由Task_Params_init完成的,然后便是根据需求对它的个别属性进行修改,例如优先级(这应该比其他使用mmWave控制API的任务有更高的优先级 ),然后就是使用Task_create创建SRR_MSS_mmWaveCtrlTask任务线程。

任务线程SRR_MSS_mmWaveCtrlTask原型;

在这个任务线程中,将MMWave_execute API放置在一个while死循环中,通过查看MMWave_execute函数原型,可以看到SemaphoreP_pend信号量的阻塞函数,所以说在创建这个执行控制线程函数后,并不会一直在这个线程中一直循环,程序仍然会顺着SRR_MSS_initTask一直往下运行。

函数原型

1)

描述

该函数用于执行mmWave控制模块,只能在执行线程的上下文中调用。该函数阻塞和处理mmWave链接消息。

参数

mmWaveHandle mmWave控制模块的句柄

errCode                由API针对错误填充的编码错误代码

返回值

成功 --- 0

错误 --- <0

注意:

没有提供和执行上下文,即没有调用MMWave_execute API,可能会导致mmWave API卡住,应用程序失去与系统中其他域的同步。

12.执行BSS波形配置

在创建mmWave控制线程之后,需要对发射波形进行配置,传感器的启动和停止等,这是由SRR_MSS_CLIInit 函数来完成的,到这里为止SRR_MSS_initTask任务线程已经基本结束,在下一篇文章中将详细讲解线性调频Chirp的编程过程。

总结:

参考示例:

mmwave_automotive_toolbox\mmwave_automotive_toolbox_3_5_0\labs\lab0002_short_range_radar

mmwave_sdk_03_05_00_04\docs\mmwave_sdk_module_documentation.html

MSS代码解读-SRR_MSS_initTask(二)相关推荐

  1. Jsoup代码解读之二-DOM相关对象

    转载自  Jsoup代码解读之二-DOM相关对象 之前在文章中说到,Jsoup使用了一套自己的DOM对象体系,和Java XML API互不兼容.这样做的好处是从XML的API里解脱出来,使得代码精炼 ...

  2. Lossless Codec---APE代码解读系列(二)

    APE file 一些概念 APE代码解读系列(一) APE代码解读系列(三) 1. 先要了解APE compression level APE主要有5level, 分别是: CompressionL ...

  3. AWR1642 SRR 案例MSS代码解读-main(一)

    摘要:在这篇博文中,将会对demo的主函数分片段来描述它的作用,并且会对一些函数作用进行描述. 1.变量参数的声明: 主程序是案例代码的入口,进入主程序,我们会先看到定义三个变量参数,为了方便表述,下 ...

  4. MSS代码解读-SRR_MSS_CLIInit(三)

    摘要:在这篇文章中,我们主要讲解SRR_MSS_CLIInit函数,这个函数包含了SDK软件包中的CLI实用程序,这个CLI程序包是TI外部定义的命令行接口任务,这个命令行接口任务提供了一个简化的&q ...

  5. MSS代码解读-MmwDemo_mboxReadTask线程(八)

    摘要:本篇文章主要是围绕着MmwDemo_mboxReadTask任务线程函数讲解邮箱读取消息的过程,该任务用于处理从邮箱虚拟通道接收的毫米波 demo 消息.接下来将对该任务线程进行分片段进行讲解, ...

  6. ANO匿名飞控STM32代码解读(二)数据传输——Ano_DT.c

    我使用代码对应的上位机版本为v6,具体通信协议格式在打开V6版本上位机–帮助信息–通信协议里可以看到. 这部分数据传输的核心简单的解帧.这部分的讲解以及匿名的通信协议的简介可以看另一篇文章**< ...

  7. 串口+GPS定位软件 C#上位机代码解读(二)

    1.调用经纬度信息显示 //调用javascritpt函数标注地图WebBrowser mapWB = (WebBrowser)baiDuMap.Content;mapWB.InvokeScript( ...

  8. jsoup获得css,Jsoup代码解读之五-实现一个CSS Selector

    Jsoup代码解读之七-实现一个CSS Selector 当当当!终于来到了Jsoup的特色:CSS Selector部分.selector也是我写的爬虫框架webmagic开发的一个重点.附上一张s ...

  9. mask rcnn 超详细代码解读(一)

    mask r-cnn 代码解读(一) 文章目录 1 代码架构 2 model.py 的结构 3 train过程代码解析 3.1 Resnet Graph 3.2 Region Proposal Net ...

最新文章

  1. 34.2. terminal
  2. leetcode 417. Pacific Atlantic Water Flow | 417. 太平洋大西洋水流问题(DFS,经典“感染”思路)
  3. 基础练习 查找整数 c语言
  4. vuejs目录结构启动项目安装nodejs命令,api配置信息思维导图版
  5. ios下划线变量:为什么变量前要加下划线才有用?
  6. C# 开发 OPC Server 系列之二
  7. 北大开源ECCV2018深度去雨算法:RESCAN
  8. cxk不会二进制 (贪心)
  9. 银行的压力测试如何进行?
  10. jquery调色板_使用jQuery的调色板生成器
  11. python出行轨迹记录软件_看看过去跑过哪些地方,用Python和高德API绘制跑步轨迹...
  12. 人脸识别技术在智慧城城市建设中的深度应用
  13. 解析个人数据云存储:云服务商的责任
  14. 微型计算机原理与接口技术考研,微型计算机原理与接口技术
  15. Flutter 保护你的APP数据安全
  16. 图片直接引入base64格式的
  17. 最全最常用的RTMP、RTSP、HTTP协议流常用直播流地址
  18. 5.excel绘制统计图
  19. 聚焦技术,锐意创新,GaussDB给世界一个更优选择
  20. 用户故事与敏捷方法-第一章问题答案

热门文章

  1. 【Huggingface系列学习】Finetuning一个预训练模型
  2. 腾讯QQ for linux安装方法,腾讯Linux for QQ到底怎么安装 ?
  3. MIDI文件结构分析及生成方法
  4. 基于Vue的网页版录音并播放
  5. RCS -- Revision Control System
  6. python与数学的故事_我与数学的故事作文
  7. 梯度提升树GBDT的理论学习与细节补充
  8. Visual Basic工具栏不小心关闭的解决方法
  9. 3D模型【球型吊坠】
  10. 华北电力大学计算机排名,华电考研计算机专业排名