TI 毫米波雷达开发 —— 设置雷达上电自启动

本文详细介绍了TI毫米波雷达的免配置启动流程,包括上电后直接运行的策略,以及如何通过CLI接收和处理来自PC的配置命令,以实现无需额外配置文件的自启动过程。
摘要由CSDN通过智能技术生成

mmWave 常规启动流程

TI 官方的例程上电启动流程为:
上电 – 等待配置 – 串口配置 – 配置完成后运行
现介绍一种上电之后不需要使用配置文件配置的方法,直接在ARM核上写固定程序。

mmWave 免配置启动流程

上电 – 配置完成后直接运行

主要思路

对于TI所有的需要配置参数的Demo而言,背后的处理流程都是一样的。

  1. PC通过UART发送命令。
  2. ARM内核接收,通过串口中断服务函数接收配置命令和配置数据。实现这一步需要初始化串口和CLI函数。
// 串口初始化函数
    /* Setup the default UART Parameters */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode  = UART_DATA_BINARY;
    uartParams.readDataMode   = UART_DATA_BINARY;
    uartParams.clockFrequency = gMmwMssMCB.cfg.sysClockFrequency;
    uartParams.baudRate       = gMmwMssMCB.cfg.loggingBaudRate;
    uartParams.isPinMuxDone   = 1U;

    /* Open the Logging UART Instance: */
    gMmwMssMCB.loggingUartHandle = UART_open(1, &uartParams);
    if (gMmwMssMCB.loggingUartHandle == NULL)
    {
        System_printf("Error: MMWDemoMSS Unable to open the Logging UART Instance\n");
        return;
    }

   /*忽略中间代码*/
   
    MmwDemo_CLIInit(); //CLI 初始化函数用于注册当前Demo中所需的命令解析回调函数。
// 接下俩看看MmwDemo_CLIInit()的函数体
void MmwDemo_CLIInit(void)
{
    CLI_Cfg cliCfg;
    char    demoBanner[256];
    /* CLI 初始化命令 */
    sprintf(&demoBanner[0],
            "******************************************\n"
            "xWR68xx High Acc Demo. SDK: %02d.%02d.%02d.%02d\n"
            "******************************************\n",
            MMWAVE_SDK_VERSION_MAJOR,
            MMWAVE_SDK_VERSION_MINOR,
            MMWAVE_SDK_VERSION_BUGFIX,
            MMWAVE_SDK_VERSION_BUILD);

    /* 初始化CLI 配置 */
    memset((void *)&cliCfg, 0, sizeof(CLI_Cfg));
    cliCfg.cliPrompt                   = "mmwDemo:/>";
    cliCfg.cliBanner                   = demoBanner;
    cliCfg.cliUartHandle               = gMmwMssMCB.commandUartHandle;
    cliCfg.taskPriority                = 3;
    cliCfg.socHandle                   = gMmwMssMCB.socHandle;
    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           = "highAccCfg";
    cliCfg.tableEntry[4].helpString    = "<numRangeBinZoomIn> <skipLeft> <skipRight> <enablePhaseEst> <enableLinearFit> <enableFilter>";
    cliCfg.tableEntry[4].cmdHandlerFxn = MmwDemo_CLIHighAccuCfg;
    
    cliCfg.tableEntry[5].cmd           = "dataLogger";
    cliCfg.tableEntry[5].helpString    = "<mssLogger | dssLogger>";
    cliCfg.tableEntry[5].cmdHandlerFxn = MmwDemo_CLISetDataLogger;
    
    cliCfg.tableEntry[6].cmd           = "adcbufCfg";
    cliCfg.tableEntry[6].helpString    = "<adcOutputFmt> <SampleSwap> <ChanInterleave> <ChirpThreshold>";
    cliCfg.tableEntry[6].cmdHandlerFxn = MmwDemo_CLIADCBufCfg;
    
    cliCfg.tableEntry[7].cmd           = "RangeLimitCfg";
    cliCfg.tableEntry[7].helpString    = "<numRangeBinZoomIn> <enabled> <min_range> <max_range> "; //"<numRangeBinZoomIn> <enabled> <min_range> <max_range> ";
    cliCfg.tableEntry[7].cmdHandlerFxn = MmwDemo_CLIRangeLimitCfg;

    if (CLI_open(&cliCfg) < 0) // 记住CLI_open 函数会创建一个task , 用于接收并解析命令,后面会提到。
    {
        System_printf("Error: Unable to open the CLI\n");
        return;
    }
    System_printf("Debug: CLI is operational\n");
    return;
}  
  1. 接收到的数据提交到命令解析回调函数。
// CLI_open 会进行相关内容的初始化并且创建新的CLI task
int32_t CLI_open (CLI_Cfg* ptrCLICfg)
{
    Task_Params     taskParams;
    uint32_t        index;

    /*  空指针检查 */
    if (ptrCLICfg == NULL)
        return -1;

    /* 初始化 CLI 管理控制块 */
    memset ((void*)&gCLI, 0, sizeof(CLI_MCB));

    /* 数据复制,用于安全控制*/
    memcpy ((void *)&gCLI.cfg, (void *)ptrCLICfg, sizeof(CLI_Cfg));

    /* 循环查看支持的命令 */
    for (index = 0; index < CLI_MAX_CMD; index++)
    {
        /* Do we have a valid entry? */
        if (gCLI.cfg.tableEntry[index].cmd == NULL)
        {
            /* NO: This is the last entry */
            break;
        }
        else
        {
            /* YES: Increment the number of CLI commands */
            gCLI.numCLICommands = gCLI.numCLICommands + 1;
        }
    }

    /* Is the mmWave Extension enabled? */
    if (gCLI.cfg.enableMMWaveExtension == 1U)
    {
        /* YES: Initialize the CLI Extension: */
        if (CLI_MMWaveExtensionInit (ptrCLICfg) < 0)
            return -1;
    }

    /* Do we have a CLI Prompt specified?  */
    if (gCLI.cfg.cliPrompt == NULL)
        gCLI.cfg.cliPrompt = "CLI:/>";

    gCLI.cfg.tableEntry[gCLI.numCLICommands].cmd           = "help";
    gCLI.cfg.tableEntry[gCLI.numCLICommands].helpString    = NULL;
    gCLI.cfg.tableEntry[gCLI.numCLICommands].cmdHandlerFxn = CLI_help;

    /* Increment the number of CLI commands: */
    gCLI.numCLICommands++;

    /* Initialize the task parameters and launch the CLI Task: */
    Task_Params_init(&taskParams);
    taskParams.priority  = gCLI.cfg.taskPriority;
    taskParams.stackSize = 4*1024;
// 创建CLI任务
    gCLI.cliTaskHandle = Task_create(CLI_task, &taskParams, NULL);
    return 0;
}
static void CLI_task(UArg arg0, UArg arg1)
{
    uint8_t                 cmdString[256];
    char*                   tokenizedArgs[CLI_MAX_ARGS];
    char*                   ptrCLICommand;
    char                    delimitter[] = " \r\n";
    uint32_t                argIndex;
    CLI_CmdTableEntry*      ptrCLICommandEntry;
    int32_t                 cliStatus;
    uint32_t                index;

    /* Do we have a banner to be displayed? */
    if (gCLI.cfg.cliBanner != NULL)
    {
        /* YES: Display the banner */
        CLI_write (gCLI.cfg.cliBanner);
    }

    /* Loop around forever: */
    while (1)
    {
        /* Demo Prompt: */
        CLI_write (gCLI.cfg.cliPrompt);

        /* Reset the command string: */
        memset ((void *)&cmdString[0], 0, sizeof(cmdString));

        /* Read the command message from the UART: */
        UART_read (gCLI.cfg.cliUartHandle, &cmdString[0], (sizeof(cmdString) - 1));

        /* Reset all the tokenized arguments: */
        memset ((void *)&tokenizedArgs, 0, sizeof(tokenizedArgs));
        argIndex      = 0;
        ptrCLICommand = (char*)&cmdString[0];

        /* comment lines found - ignore the whole line*/
        if (cmdString[0]=='%') {
            CLI_write ("Skipped\n");
            continue;
        }

        /* Set the CLI status: */
        cliStatus = -1;

        /* The command has been entered we now tokenize the command message */
        while (1)
        {
            /* Tokenize the arguments: */
            tokenizedArgs[argIndex] = strtok(ptrCLICommand, delimitter);
            if (tokenizedArgs[argIndex] == NULL)
                break;

            /* Increment the argument index: */
            argIndex++;
            if (argIndex >= CLI_MAX_ARGS)
                break;

            /* Reset the command string */
            ptrCLICommand = NULL;
        }

        /* Were we able to tokenize the CLI command? */
        if (argIndex == 0)
            continue;

        /* Cycle through all the registered CLI commands: */
        for (index = 0; index < gCLI.numCLICommands; index++)
        {
            ptrCLICommandEntry = &gCLI.cfg.tableEntry[index];

            /* Do we have a match? */
            if (strcmp(ptrCLICommandEntry->cmd, tokenizedArgs[0]) == 0)
            {
                /* YES: Pass this to the CLI registered function */
                cliStatus = ptrCLICommandEntry->cmdHandlerFxn (argIndex, tokenizedArgs);
                if (cliStatus == 0)
                {
                    CLI_write ("Done\n");
                }
                else
                {
                    CLI_write ("Error %d\n", cliStatus);
                }
                break;
            }
        }

        /* Did we get a matching CLI command? */
        if (index == gCLI.numCLICommands)
        {
            /* NO matching command found. Is the mmWave extension enabled? */
            if (gCLI.cfg.enableMMWaveExtension == 1U)
            {
                /* Yes: Pass this to the mmWave extension handler */
                cliStatus = CLI_MMWaveExtensionHandler (argIndex, tokenizedArgs);
            }

            /* Was the CLI command found? */
            if (cliStatus == -1)
            {
                /* No: The command was still not found */
                CLI_write ("'%s' is not recognized as a CLI command\n", tokenizedArgs[0]);
            }
        }
    }
}

  1. 命令解析函数对各配置命令进行处理。
// 以MmwDemo_CLIHighAccuCfg为例
static int32_t MmwDemo_CLIHighAccuCfg(int32_t argc, char *argv[])
{
    radarModuleHighAccuConfig highAccuConfig;
    MmwDemo_message           message;

    /* Sanity Check: Minimum argument check */
    if (argc != 7)
    {
        CLI_write("Error: Invalid usage of the CLI command\n");
        return -1;
    }

    /* Initialize the ADC Output configuration: */
    memset((void *)&highAccuConfig, 0, sizeof(radarModuleHighAccuConfig));


    // System_printf("highAccuConfig config\n");

    // cliCfg.tableEntry[4].helpString     = "<numRangeBinZoomIn> <skipLeft> <skipRight> <enablePhaseEst> <enableLinearFit> <enableFilter>";
    /* Populate configuration: */
    highAccuConfig.numRangeBinZoomIn = (uint16_t)atoi(argv[1]);
    highAccuConfig.skipLeft          = (uint16_t)atoi(argv[2]);
    highAccuConfig.skipRight         = (uint16_t)atoi(argv[3]);
    highAccuConfig.enablePhaseEst    = (uint16_t)atoi(argv[4]);
    highAccuConfig.enableLinearFit   = (uint16_t)atoi(argv[5]);
    highAccuConfig.enableFilter      = (uint16_t)atoi(argv[6]);

    /* Save Configuration to use later */
    memcpy((void *)&gMmwMssMCB.cfg.highAccuRangeCfg, (void *)&highAccuConfig, sizeof(radarModuleHighAccuConfig));

    /* Send configuration to DSS */
    memset((void *)&message, 0, sizeof(MmwDemo_message));

    message.type = MMWDEMO_MSS2DSS_HIGHACCURANGE_CFG;
    memcpy((void *)&message.body.highAccuRangeCfg, (void *)&highAccuConfig, sizeof(radarModuleHighAccuConfig));

    if (MmwDemo_mboxWrite(&message) == 0)
        return 0;
    else
        return -1;
}

所以如果期望实现免配置自启动,只需要给第3步提供合适的入口参数。

实现方式

cli.c中定义配置命令

#define USE_HARD_CODED_CONFIG

#ifdef USE_HARD_CODED_CONFIG

int32_t hardCodedConfigIndex;


char *hardCodedConfigCommands[] = {
    "sensorStop",
    "flushCfg",
    "dfeDataOutputMode 1",
    "channelCfg 15 7 0",
    "adcCfg 2 1",
    "adcbufCfg -1 0 1 1 1",
    "lowPower 0 0",
    "profileCfg 0 60 7 3 24 0 0 166 1 256 12500 0 0 158",
    "chirpCfg 0 0 0 0 0 0 0 1",
    "chirpCfg 1 1 0 0 0 0 0 4",
    "chirpCfg 2 2 0 0 0 0 0 2",
    "frameCfg 0 2 32 0 100 1 0",
    "guiMonitor -1 1 1 1 0 0 1",
    "cfarCfg -1 0 2 8 4 3 0 15.0 0",
    "cfarCfg -1 1 0 4 2 3 1 15.0 0",
    "multiObjBeamForming -1 1 0.5",
    "calibDcRangeSig -1 0 -5 8 256",
    "clutterRemoval -1 0",

    "compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0",
    "measureRangeBiasAndRxChanPhase 0 1. 0.2",

    "aoaFovCfg -1 -90 90 -90 90",
    "cfarFovCfg -1 0 0.25 9.0",
    "cfarFovCfg -1 1 -20.16 20.16",
    "extendedMaxVelocity -1 0",

    "CQRxSatMonitor 0 3 4 63 0",
    "CQSigImgMonitor 0 127 4",
    "analogMonitor 0 0",
    "lvdsStreamCfg -1 0 0 0",
    "bpmCfg -1 0 0 0",
    "calibData 0 0 0",
    "sensorStart",
    "!!!END_OF_HARD_CODED_COMMANDS"
};

#endif

CLI_task 函数增加处理代码

static void CLI_task(UArg arg0, UArg arg1)
{
    uint8_t            cmdString[256];
    char              *tokenizedArgs[CLI_MAX_ARGS];
    char              *ptrCLICommand;
    char               delimitter[] = " \r\n";
    uint32_t           argIndex;
    CLI_CmdTableEntry *ptrCLICommandEntry;
    int32_t            cliStatus;
    uint32_t           index;

    /* Do we have a banner to be displayed? */
    if (gCLI.cfg.cliBanner != NULL)
    {
        /* YES: Display the banner */
        CLI_write(gCLI.cfg.cliBanner);
    }
#ifdef USE_HARD_CODED_CONFIG

    hardCodedConfigIndex = 0;

    CLI_write("Wait some time for system to initialize...\n");

    Task_sleep(100);

    CLI_write("Performing hard-coded config\n");

#endif
    /* Loop around forever: */
    while (1)
    {
        /* Demo Prompt: */
        CLI_write(gCLI.cfg.cliPrompt);

        /* Reset the command string: */
        memset((void *)&cmdString[0], 0, sizeof(cmdString));

#ifdef USE_HARD_CODED_CONFIG
        //新增上电自启动处理代码
        if (hardCodedConfigCommands[hardCodedConfigIndex][0] != '!')
        {   // CLI_write (hardCodedConfigCommands[hardCodedConfigIndex]);
            CLI_write("Command\n");
            memcpy((void *)&cmdString[0], (void *)hardCodedConfigCommands[hardCodedConfigIndex],
                   strlen(hardCodedConfigCommands[hardCodedConfigIndex]));
            hardCodedConfigIndex++;
        }
        else
        {
            UART_read(gCLI.cfg.cliUartHandle, &cmdString[0], (sizeof(cmdString) - 1));
        }
#else    //保留原来的串口处理方式
        /* Read the command message from the UART: */
        UART_read(gCLI.cfg.cliUartHandle, &cmdString[0], (sizeof(cmdString) - 1));
#endif
        /* Reset all the tokenized arguments: */
        memset((void *)&tokenizedArgs, 0, sizeof(tokenizedArgs));
        argIndex      = 0;
        ptrCLICommand = (char *)&cmdString[0];

        /* comment lines found - ignore the whole line*/
        if (cmdString[0] == '%')
        {
            CLI_write("Skipped\n");
            continue;
        }

        /* Set the CLI status: */
        cliStatus = -1;

        /* The command has been entered we now tokenize the command message */
        while (1)
        {
            /* Tokenize the arguments: */
            tokenizedArgs[argIndex] = strtok(ptrCLICommand, delimitter);
            if (tokenizedArgs[argIndex] == NULL)
                break;

            /* Increment the argument index: */
            argIndex++;
            if (argIndex >= CLI_MAX_ARGS)
                break;

            /* Reset the command string */
            ptrCLICommand = NULL;
        }

        /* Were we able to tokenize the CLI command? */
        if (argIndex == 0)
            continue;

        /* Cycle through all the registered CLI commands: */
        for (index = 0; index < gCLI.numCLICommands; index++)
        {
            ptrCLICommandEntry = &gCLI.cfg.tableEntry[index];

            /* Do we have a match? */
            if (strcmp(ptrCLICommandEntry->cmd, tokenizedArgs[0]) == 0)
            {
                /* YES: Pass this to the CLI registered function */
                cliStatus = ptrCLICommandEntry->cmdHandlerFxn(argIndex, tokenizedArgs);
                if (cliStatus == 0)
                {
                    CLI_write("Done\n");
                }
                else
                {
                    CLI_write("Error %d\n", cliStatus);
                }
                break;
            }
        }

        /* Did we get a matching CLI command? */
        if (index == gCLI.numCLICommands)
        {
            /* NO matching command found. Is the mmWave extension enabled? */
            if (gCLI.cfg.enableMMWaveExtension == 1U)
            {
                /* Yes: Pass this to the mmWave extension handler */
                cliStatus = CLI_MMWaveExtensionHandler(argIndex, tokenizedArgs);
            }

            /* Was the CLI command found? */
            if (cliStatus == -1)
            {
                /* No: The command was still not found */
                CLI_write("'%s' is not recognized as a CLI command\n", tokenizedArgs[0]);
            }
        }
    }
}
  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

雷达爆破手

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值