TI AWR1642 评估板 77G行人检测雷达代码分析(2-2)-sys_bios系统任务结构分析(MSS工程)
大家好,这篇文章是补充上一篇没有讲完的部分,下面我们直接开始吧。
(10)
/*****************************************************************************
* mmWave: Initialization of the high level module
*****************************************************************************/
/* Initialize the mmWave control init configuration */
memset ((void*)&initCfg, 0 , sizeof(MMWave_InitCfg));
/* Populate the init configuration for mmwave library: */
initCfg.domain = MMWave_Domain_MSS;
initCfg.socHandle = gMmwMssMCB.socHandle;
initCfg.eventFxn = MmwDemo_mssMmwaveEventCallbackFxn;
initCfg.linkCRCCfg.useCRCDriver = 1U;
initCfg.linkCRCCfg.crcChannel = CRC_Channel_CH1;
initCfg.cfgMode = MMWave_ConfigurationMode_FULL;
initCfg.executionMode = MMWave_ExecutionMode_COOPERATIVE;
initCfg.cooperativeModeCfg.cfgFxn = MmwDemo_mssMmwaveConfigCallbackFxn;
initCfg.cooperativeModeCfg.openFxn = MmwDemo_mssMmwaveOpenCallbackFxn;
initCfg.cooperativeModeCfg.closeFxn = MmwDemo_mssMmwaveCloseCallbackFxn;
initCfg.cooperativeModeCfg.startFxn = MmwDemo_mssMmwaveStartCallbackFxn;
initCfg.cooperativeModeCfg.stopFxn = MmwDemo_mssMmwaveStopCallbackFxn;
/* Initialize and setup the mmWave Control module */
gMmwMssMCB.ctrlHandle = MMWave_init (&initCfg, &errCode);
if (gMmwMssMCB.ctrlHandle == NULL)
{
/* Error: Unable to initialize the mmWave control module */
System_printf("Error: MMWDemoMSS mmWave Control Initialization failed [Error code %d]\n", errCode);
return;
}
System_printf("Debug: MMWDemoMSS mmWave Control Initialization was successful\n");
/* Synchronization: This will synchronize the execution of the control module
* between the domains. This is a prerequiste and always needs to be invoked. */
这个部分是初始化高级模块。
首先memset函数就是对申请的一个大的内存做初始化,作用是将某一块内存中的内容(变量)全部设置为指定的值,这里是用来存放初始化mmWave控件的初始配置参数。
在这里是将initCfg这个参数的值全部设置为0。下面接着对initCfg参数的其他元素进行赋值,这里需要注意的是,除了赋值单一的参数之外,还赋值了回调函数。
这个回调函数这里不太好理解,比如:
initCfg.eventFxn = MmwDemo_mssMmwaveEventCallbackFxn;
这个的返回值总是0,而其他回调函数的返回值是void,即空,但是这个回调函数是用来做什么的,我百思不得其解,不过大体上可以推测是用来配置雷达的。
继续往下看,我们可以看到这个参数initCfg用来设置mmWave控制模块了:
gMmwMssMCB.ctrlHandle = MMWave_init (&initCfg, &errCode);
if (gMmwMssMCB.ctrlHandle == NULL)
{
/* Error: Unable to initialize the mmWave control module */
System_printf("Error: MMWDemoMSS mmWave Control Initialization failed [Error code %d]\n", errCode);
return;
}
(11)下面是进入一个while()循环,主要有几个部分,包含获取同步化状态
,当获取之后,就退出当前循环,如果没有获得同步状态,就一直等待。
while (1)
{
int32_t syncStatus;
/* Get the synchronization status: */
syncStatus = MMWave_sync (gMmwMssMCB.ctrlHandle , &errCode);
if (syncStatus < 0)
{
/* Error: Unable to synchronize the mmWave control module */
System_printf ("Error: MMWDemoMSS mmWave Control Synchronization failed [Error code %d]\n", errCode);
return;
}
if (syncStatus == 1)
{
/* Synchronization acheived: */
break;
}
/* Sleep and poll again: */
Task_sleep(1);
}
(12)下面是建立了三个任务,先不要研究三个任务具体是做什么的,大概了解一下,后面会慢慢展开。
/*****************************************************************************
* Launch the mmWave control execution task
* - This should have a higher priority than any other task which uses the
* mmWave control API
*****************************************************************************/
Task_Params_init(&taskParams);
taskParams.priority = 6;
taskParams.stackSize = 4*1024;
Task_create(MmwDemo_mmWaveCtrlTask, &taskParams, NULL);
/*****************************************************************************
* Create a data path management task to handle data Path events
*****************************************************************************/
Task_Params_init(&taskParams);
taskParams.priority = 4;
taskParams.stackSize = 4*1024;
Task_create(MmwDemo_mssCtrlPathTask, &taskParams, NULL);
/*****************************************************************************
* Create an application task to handle high layer processing
*****************************************************************************/
/* Create a binary semaphore for application task to pend */
Semaphore_Params_init(&semParams);
semParams.mode = Semaphore_Mode_BINARY;
gMmwMssMCB.appSemHandle = Semaphore_create(0, &semParams, NULL);
Task_Params_init(&taskParams);
taskParams.priority = 2;
taskParams.stackSize = 4*1024;
Task_create(MmwDemo_appTask, &taskParams, NULL);
第一个是MmwDemo_mmWaveCtrlTask任务,该任务为mmWave控制任务提供执行内容,属于启动mmWave控件执行任务,优先级6,主控制。
第二个是MmwDemo_mssCtrlPathTask任务,该任务用于处理数据路径事件控制任务,属处理于路径数据,优先级4,主数据控制。
第三个是MmwDemo_appTask,该任务用于处理从以下位置收到的mmw演示消息邮箱虚拟通道,属于高层处理,优先级2,主处理。
三个任务各司其职。
(13)最后了,加油
/*****************************************************************************
* At this point, MSS and DSS are both up and synced. Configuration is ready to be sent.
* Start CLI to get configuration from user
*****************************************************************************/
MmwDemo_CLIInit();
/*****************************************************************************
* Benchmarking Count init
*****************************************************************************/
/* Configure benchmark counter */
Pmu_configureCounter(0, 0x11, FALSE);
Pmu_startCounter(0);
return;
这里有一个函数特别重要:
MmwDemo_CLIInit();
他是对雷达进行配置的关键,按F3跟进:
void MmwDemo_CLIInit (void)
{
CLI_Cfg cliCfg;
char demoBanner[256];
/* Create Demo Banner to be printed out by CLI */
sprintf(&demoBanner[0], "******************************************\n" \
"MMW TM Demo %s\n" \
"******************************************\n", MMW_VERSION);
/* Initialize the CLI configuration: */
memset ((void *)&cliCfg, 0, sizeof(CLI_Cfg));
/* Populate the CLI configuration: */
cliCfg.cliPrompt = "mmwDemo:/>";
cliCfg.cliBanner = demoBanner;
cliCfg.cliUartHandle = gMmwMssMCB.commandUartHandle;
cliCfg.taskPriority = 3;
cliCfg.mmWaveHandle = gMmwMssMCB.ctrlHandle;
cliCfg.enableMMWaveExtension = 1U;
cliCfg.usePolledMode = true;
cliCfg.tableEntry[0].cmd = "sensorStart";
cliCfg.tableEntry[0].helpString = "No arguments";
cliCfg.tableEntry[0].cmdHandlerFxn = MmwDemo_CLISensorStart;
cliCfg.tableEntry[1].cmd = "sensorStop";
cliCfg.tableEntry[1].helpString = "No arguments";
cliCfg.tableEntry[1].cmdHandlerFxn = MmwDemo_CLISensorStop;
cliCfg.tableEntry[2].cmd = "frameStart";
cliCfg.tableEntry[2].helpString = "No arguments";
cliCfg.tableEntry[2].cmdHandlerFxn = MmwDemo_CLIFrameStart;
cliCfg.tableEntry[3].cmd = "guiMonitor";
cliCfg.tableEntry[3].helpString = "<detectedObjects> <logMagRange> <rangeAzimuthHeatMap> <rangeDopplerHeatMap>";
cliCfg.tableEntry[3].cmdHandlerFxn = MmwDemo_CLIGuiMonSel;
cliCfg.tableEntry[4].cmd = "cfarCfg";
cliCfg.tableEntry[4].helpString = "<detMode> <discardLeft> <discardRight> <refWinSize1> <refWinSize2> <guardWinSize1> <guardWinSize2> <thre>";
cliCfg.tableEntry[4].cmdHandlerFxn = MmwDemo_CLICfarCfg;
cliCfg.tableEntry[5].cmd = "doaCfg";
cliCfg.tableEntry[5].helpString = "<doaMode> <doaGamma> <sideLobe_dB> <searchRange> <searchRes> <varThre>";
cliCfg.tableEntry[5].cmdHandlerFxn = MmwDemo_CLIDoACfg;
cliCfg.tableEntry[6].cmd = "trackingCfg";
cliCfg.tableEntry[6].helpString = "<enable> <paramSet> <numPoints> <numTracks> <maxDoppler> <framePeriod>";
cliCfg.tableEntry[6].cmdHandlerFxn = MmwDemo_CLITrackingCfg;
cliCfg.tableEntry[7].cmd = "dataLogger";
cliCfg.tableEntry[7].helpString = "<mssLogger | dssLogger>";
cliCfg.tableEntry[7].cmdHandlerFxn = MmwDemo_CLISetDataLogger;
cliCfg.tableEntry[8].cmd = "adcbufCfg";
cliCfg.tableEntry[8].helpString = "<adcOutputFmt> <SampleSwap> <ChanInterleave> <ChirpThreshold>";
cliCfg.tableEntry[8].cmdHandlerFxn = MmwDemo_CLIADCBufCfg;
cliCfg.tableEntry[9].cmd = "SceneryParam";// PC OFFICE Left Wall (-1.5), Right Wall (1.5), Bottom Exit Zone (1m), Upper Exit Zone (4.5m)
cliCfg.tableEntry[9].helpString = "<Left Wall> <Right Wall> <Bottom Exit Zone> <Upper Exit Zone>";
cliCfg.tableEntry[9].cmdHandlerFxn = MmwDemo_CLISceneryParamCfg;
cliCfg.tableEntry[10].cmd = "GatingParam";// PC: 4 gating volume, Limits are set to 3m in length, 2m in width, 0 no limit in doppler
cliCfg.tableEntry[10].helpString = "<gating volume> <length> <width> <doppler>";
cliCfg.tableEntry[10].cmdHandlerFxn = MmwDemo_CLIGatingParamCfg;
cliCfg.tableEntry[11].cmd = "StateParam";// PC: 10 frames to activate, 5 to forget, 10 active to free, 1000 static to free, 5 exit to free
cliCfg.tableEntry[11].helpString = "<det2act> <det2free> <act2free> <stat2free> <exit2free>";//det2act, det2free, act2free, stat2free, exit2free
cliCfg.tableEntry[11].cmdHandlerFxn = MmwDemo_CLIStateParamCfg;
cliCfg.tableEntry[12].cmd = "AllocationParam";// PC: 250 SNR, 0.1 minimal velocity, 5 points, 1m in distance, 2m/s in velocity
cliCfg.tableEntry[12].helpString = "<SNRs> <minimal velocity> <points> <in distance> <in velocity>";
cliCfg.tableEntry[12].cmdHandlerFxn = MmwDemo_CLIAllocationParamCfg;
cliCfg.tableEntry[13].cmd = "VariationParam";// PC: 1m height, 1m in width, 1 m/s for doppler
cliCfg.tableEntry[13].helpString = "<height> <width> <doppler>";
cliCfg.tableEntry[13].cmdHandlerFxn = MmwDemo_CLIVariationParamCfg;
/*! Enable Point Cloud */
cliCfg.tableEntry[14].cmd = "PointCloudEn"; //1 is on, 0 is off
cliCfg.tableEntry[14].helpString = "1 is on, 0 is off";
cliCfg.tableEntry[14].cmdHandlerFxn = MmwDemo_CLIPointCloudEn;
/* Open the CLI: */
if (CLI_open (&cliCfg) < 0)
{
System_printf ("Error: Unable to open the CLI\n");
return;
}
System_printf ("Debug: CLI is operational\n");
return;
}
这个地方需要细看,所有的语句都是对cliCfg赋值,然后后面直接调用:
CLI_open (&cliCfg)
对雷达进行配置,我们要知道对cliCfg赋值的是些什么东西,下面一起来看看:
举个例子,帮助大家理解,比如下面是ADCBUFFG:
cliCfg.tableEntry[8].cmd = "adcbufCfg";
cliCfg.tableEntry[8].helpString = "<adcOutputFmt> <SampleSwap> <ChanInterleave> <ChirpThreshold>";
cliCfg.tableEntry[8].cmdHandlerFxn = MmwDemo_CLIADCBufCfg;
为了帮助大家建立联系,我这里要用到上位机的参数配置文件,如下:
看到这里的参数,是不是有所开窍,没错这里便是将上位机下发的参数配置文件送给雷达,继续往下看调用这个MmwDemo_CLIADCBufCfg 函数做了些什么:
static int32_t MmwDemo_CLIADCBufCfg (int32_t argc, char* argv[])
{
MmwDemo_ADCBufCfg adcBufCfg;
MmwDemo_message message;
/* Sanity Check: Minimum argument check */
if (argc != 5)
{
CLI_write ("Error: Invalid usage of the CLI command\n");
return -1;
}
/* Initialize the ADC Output configuration: */
memset ((void *)&adcBufCfg, 0, sizeof(MmwDemo_ADCBufCfg));
/* Populate configuration: */
adcBufCfg.adcFmt = (uint8_t) atoi (argv[1]);
adcBufCfg.iqSwapSel = (uint8_t) atoi (argv[2]);
adcBufCfg.chInterleave = (uint8_t) atoi (argv[3]);
adcBufCfg.chirpThreshold = (uint8_t) atoi (argv[4]);
/* Save Configuration to use later */
memcpy((void *)&gMmwMssMCB.cfg.adcBufCfg, (void *)&adcBufCfg, sizeof(MmwDemo_ADCBufCfg));
/* Send configuration to DSS */
memset((void *)&message, 0, sizeof(MmwDemo_message));
message.type = MMWDEMO_MSS2DSS_ADCBUFCFG;
memcpy((void *)&message.body.adcBufCfg, (void *)&adcBufCfg, sizeof(MmwDemo_ADCBufCfg));
if (MmwDemo_mboxWrite(&message) == 0)
return 0;
else
return -1;
}
这段代码中关系在于那四个数组赋值,便是代表这四个参数。
剩下的其他参数大家可以按照同样的方法查看。
最后两句代码是配置基准计数器,然后启动计数器,知道他是干啥的就行了,不用知道他是具体怎么做的。
Pmu_configureCounter(0, 0x11, FALSE);
Pmu_startCounter(0);
好了,今天就讲到这里了。现在已经把几个任务的结构讲完了,下面会单独分析每一个任务的具体作用。