前言
恩智浦“FRDM-MCXN947”評(píng)測(cè)活動(dòng)由安富利和與非網(wǎng)協(xié)同舉辦。本篇內(nèi)容由與非網(wǎng)用戶發(fā)布,已獲轉(zhuǎn)載許可。原文可在與非網(wǎng)(eefocus)工程師社區(qū)查看。
背景
此次任務(wù)通過(guò)串口命令行控制RGB LED,相比較與上一次任務(wù)通過(guò)單個(gè)字符控制增加了FreeRTOS-CLI組件,支持更復(fù)雜的、帶參數(shù)的命令。
1. 搭建VSCode開(kāi)發(fā)環(huán)境
2. 添加FreeRTOS組件,創(chuàng)建任務(wù)
3. 添加FreeRTOS-CLI組件,打通適配層
4. 添加FreeRTOS-CLI自定義命令,控制RGB LED
搭建VS Code開(kāi)發(fā)環(huán)境
無(wú)論是使用MCUXpresso IDE還是VS Code開(kāi)發(fā)環(huán)境,都必須要:
1. 安裝MCUXpresso IDE,因?yàn)镮DE里有NXP支持的GCC工具鏈
2. 下載mcux_sdk_frdm_mcxn947 SDK
3. VS Code安裝插件MCUXPresso for VS Code
4. VS Code配置插件MCUXpresso for VS Code
前幾個(gè)步驟都好說(shuō),這里簡(jiǎn)短演示下VS Code配置插件MCUXpresso for VS Code。
01 配置MCUXpresso for VS Code
1. 在VS Code側(cè)邊欄單擊MCUXpresso圖標(biāo)展開(kāi)右側(cè)視圖
2. 單擊(2)處展開(kāi)右側(cè)視圖。這里建議單擊Import Example from Repository,因?yàn)樗壬厦娴?strong>Import Repository有更多的配置選型,可以直接從這里創(chuàng)建示例工程
3. 單擊(3)處選擇本地的SDK路徑,例如這里選擇已經(jīng)下載并解壓縮的mcux_sdk_frdm_mcxn947
4. 單擊(4)處選擇MCUXpresso IDE的GCC工具鏈
5. 單擊(5)處選擇開(kāi)發(fā)板,一個(gè)SDK可以支持同類(lèi)型的幾個(gè)開(kāi)發(fā)板,根據(jù)需要選擇對(duì)應(yīng)的開(kāi)發(fā)板
6. 單擊(6)處選擇示例工程模版,也可以輸入關(guān)鍵詞搜索
7. 編輯(7)處輸入框輸入新建的工程名字
8. 單擊(8)處選擇工程保存路徑
9. 最后點(diǎn)擊Create即可以創(chuàng)建工程
02 工程結(jié)構(gòu)
.vscode/包含一些配置選項(xiàng)、調(diào)試啟動(dòng)文件
repo/是一個(gè)鏈接文件,執(zhí)行SDK所在文件夾
app/包含應(yīng)用代碼
armgcc包含CMakeLists.txt目錄程序以及一些bat、shell編譯腳本,如果新增了源文件和頭文件,需要修改此處的CMakeLists.txt文件
board/包含管腳、時(shí)鐘、外設(shè)初始化代碼,是MCUXpresso Config Tools自動(dòng)生成的文件夾
iar/是IAR IDE工程文件和鏈接腳本
mdk/是MDK IDE工程文件和鏈接腳本
后綴名為*.mex是MCUXpresso Config Tools的輸入文件
readme.md是示例工程的說(shuō)明文檔
03 編譯、下載、調(diào)試
采用CMake+GCC編譯此工程,圖簡(jiǎn)便的話直接點(diǎn)擊MCUXpresso for VS Code中的圖標(biāo),如下圖所示。
04 添加FreeRTOS組件
嘗試過(guò)MCUXpresso IDE添加FreeRTOS組件,雖然把源碼拷貝過(guò)來(lái)添加到工程里,但是port層的源文件和頭文件缺失了,需要從例程拷貝復(fù)制,太麻煩了。
而VS Code中添加組件的方式特別簡(jiǎn)單,如下添加FreeRTOS組件,簡(jiǎn)直不要太爽了。
1. 鼠標(biāo)右鍵單擊工程名
2. 在彈出的菜單中選擇(2)配置工程
3. 然后選擇(3)管理組件
4. 在(4)處編輯框輸入kernel過(guò)濾組件
5. 在(5)處選擇合適的FreeRTOS類(lèi)型
6. 在(6)處點(diǎn)擊確認(rèn)即可
添加FreeRTOS所做的更改體現(xiàn)在armgcc/config.cmake文件,如下圖所示文件中增加了幾處和freertos相關(guān)的配置選項(xiàng)。當(dāng)然FreeRTOS源碼不會(huì)拷貝過(guò)來(lái),它依然存在于SDK路徑中,但是需要拷貝一份FreeRTOSConfig.h過(guò)來(lái),自行修改其中的參數(shù)。
05 新建FreeRTOS任務(wù)
新建一個(gè)最簡(jiǎn)單的FreeRTOS任務(wù),每隔兩秒鐘打印一次信息。
(滑動(dòng)查看)
int main(void) { // 管腳復(fù)用和配置 BOARD_InitBootClocks(); BOARD_InitBootPeripherals(); BOARD_InitBootPins(); BOARD_InitSWD_DEBUGPins(); // 調(diào)試串口打印日志 BOARD_InitDebugConsole(); PRINTF(" "); PRINTF(" Build: %s %s ", __DATE__, __TIME__); if (xTaskCreate(zygote_task, "zygote_task", ZYGOTE_TASK_STACK_SIZE, NULL, ZYGOTE_TASK_PRIORITY, NULL) != pdPASS) { PRINTF("Task creation failed!. "); while (1) ; } vTaskStartScheduler(); for (;;) ; } static void zygote_task(void *pvParameters) { uint32_t zygote_loop_cnt = 0; for (;;) { zygote_loop_cnt++; PRINTF("zygote loop cnt: %u ", zygote_loop_cnt); vTaskDelay(pdMS_TO_TICKS(2000)); } }
FreeRTOS-CLI組件
01 組件介紹
FreeRTOS-CLI是FreeRTOS官方的組件,支持注冊(cè)多參數(shù)命令,命令接口可以是串口、網(wǎng)絡(luò)套接字等。
當(dāng)前使用的版本是FreeRTOS+CLI V1.0.4,適配層使用串口,注冊(cè)兩個(gè)多參數(shù)的命令,控制開(kāi)發(fā)板上的RGB LED亮滅。
02 添加FreeRTOS-CLI組件
在源碼頂層目錄新建3rdparty目錄并拷貝FreeRTOS_Plus_CLI組件到此,目錄結(jié)構(gòu)如下:
FreeRTOS_Plus_CLI/ port/ serial.c serial.h src/ FreeRTOS_CLI.c FreeRTOS_CLI.h
我們只需要關(guān)心port/目錄即可,適配UART層在這里。
03 適配層
重點(diǎn)在以下幾個(gè)函數(shù)的適配:
xSerialPortInitMinimal()
xSerialPortInit()
vSerialPutString()
xSerialGetChar()
xSerialPutChar()
因?yàn)楣苣_初始化已經(jīng)由MCUXpresso Config Tools圖形化配置完成,通過(guò)Debug UART進(jìn)行輸入輸出,所以前兩個(gè)串口初始化函數(shù)可以留空,重點(diǎn)在于xSerialGetChar()和xSerialPutChar()的實(shí)現(xiàn),這里簡(jiǎn)單實(shí)現(xiàn)一下,通過(guò)Debug UART進(jìn)行輸入輸出即可。
(滑動(dòng)查看)
signed portBASE_TYPE xSerialGetChar(xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime) { #ifndef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING *pcRxedChar = GETCHAR(); return pdPASS; #else char data = 0; while (xBlockTime-- > 0) { if (kStatus_Success == DbgConsole_TryGetchar(&data)) { *pcRxedChar = data; return pdPASS; } else { vTaskDelay(pdMS_TO_TICKS(1)); } } return pdFAIL; #endif } signed portBASE_TYPE xSerialPutChar(xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime) { signed portBASE_TYPE ch = 0; ch = PUTCHAR(cOutChar); return ch; }
04 RGB LED控制命令
為了點(diǎn)亮、熄滅RGB LED,需要實(shí)現(xiàn)如下這樣的命令:
ledset r on點(diǎn)亮紅色LED,同理ledset g/b on點(diǎn)亮綠色、藍(lán)色LED
ledset r off熄滅紅色LED,同理ledset g/b off熄滅綠色、藍(lán)色LED
ledget r獲取紅色LED狀態(tài),如LEDR:OFF表示熄滅,LEDR:ON表示點(diǎn)亮
05 點(diǎn)亮、熄滅 LED命令的實(shí)現(xiàn)
(滑動(dòng)查看)
// TODO: ledset r/g/b on/off // 作用:設(shè)置燈的狀態(tài) // 命令: ledset // 參數(shù)1:編號(hào),這里以 r/g/b 縮寫(xiě)分別表示 "RED/GREE/BLUE" 三個(gè)燈 // 參數(shù)2:開(kāi)關(guān),這里以字符串 on/off 分別表示 "開(kāi)燈/關(guān)燈" /** * @brief * * @param pcWriteBuffer * @param xWriteBufferLen * @param pcCommandString * @return BaseType_t */ static BaseType_t prvLedSetCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) { configASSERT(pcWriteBuffer); /* param1: r/g/b */ const char *paramLedId = NULL; BaseType_t paramLedIdLength = 0; led_id_e mLedId = LED_ID_INVALID; /* param2: on/off */ const char *paramLedStatus = NULL; BaseType_t paramLedStatusLength = 0; led_status_e mLedStatus; // 首先清除輸出緩沖區(qū)舊的內(nèi)容 memset(pcWriteBuffer, 0, xWriteBufferLen); // TODO: 根據(jù)兩個(gè)參數(shù)打印返回的字符串 paramLedId = FreeRTOS_CLIGetParameter(pcCommandString, 1, ¶mLedIdLength); paramLedStatus = FreeRTOS_CLIGetParameter(pcCommandString, 2, ¶mLedStatusLength); if (strncmp("r", paramLedId, 1) == 0) { mLedId = LED_ID_RED; } else if (strncmp("g", paramLedId, 1) == 0) { mLedId = LED_ID_GREEN; } else if (strncmp("b", paramLedId, 1) == 0) { mLedId = LED_ID_BLUE; } else { mLedId = LED_ID_INVALID; } if (strncmp("on", paramLedStatus, 2) == 0) { mLedStatus = LED_ON; } else if (strncmp("off", paramLedStatus, 3) == 0) { mLedStatus = LED_OFF; } led_set_status(mLedId, mLedStatus); /* There is no more data to return after this single string, so return pdFALSE. */ return pdFALSE; }
06 獲取LED狀態(tài)命令的實(shí)現(xiàn)
(滑動(dòng)查看)
// TODO: ledget r/g/b // 作用:獲取燈的狀態(tài) // 命令: ledget // 參數(shù)1:編號(hào) /** * @brief * * @param pcWriteBuffer * @param xWriteBufferLen * @param pcCommandString * @return BaseType_t */ static BaseType_t prvLedGetCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) { configASSERT(pcWriteBuffer); /* param1: r/g/b */ const char *paramLedId = NULL; BaseType_t paramLedIdLength = 0; led_id_e mLedId = LED_ID_INVALID; led_status_e mLedStatus; // 首先清除輸出緩沖區(qū)舊的內(nèi)容 memset(pcWriteBuffer, 0, xWriteBufferLen); paramLedId = FreeRTOS_CLIGetParameter(pcCommandString, 1, ¶mLedIdLength); if (strncmp("r", paramLedId, 1) == 0) { mLedId = LED_ID_RED; } else if (strncmp("g", paramLedId, 1) == 0) { mLedId = LED_ID_GREEN; } else if (strncmp("b", paramLedId, 1) == 0) { mLedId = LED_ID_BLUE; } else { mLedId = LED_ID_INVALID; } /* 獲取燈的狀態(tài) */ mLedStatus = led_get_status(mLedId); /* 輸出燈的狀態(tài),輸出到 pcWriteBuffer 緩沖區(qū)中 */ sprintf(pcWriteBuffer, "%s: %s ", led_helper_id_to_string(mLedId), led_helper_status_to_string(mLedStatus)); /* There is no more data to return after this single string, so return pdFALSE. */ return pdFALSE; }
07 注冊(cè)命令
先定義結(jié)構(gòu)體,把命令字符串和解析函數(shù)關(guān)聯(lián)在一起。
(滑動(dòng)查看)
/* Structure that defines the "ledset" command line command. This generates a table that gives information on each task in the system. */ static const CLI_Command_Definition_t xLedSet = { "ledset", /* The command string to type. */ " ledset: set r/g/b led status example: ledset r on or ledset g off ", prvLedSetCommand, /* The function to run. */ 2 /* 2 parameters are expected. */ }; /* Structure that defines the "ledget" command line command. This generates a table that gives information on each task in the system. */ static const CLI_Command_Definition_t xLedGet = { "ledget", /* The command string to type. */ " ledget : get r/g/b led status example: ledget r or ledget g ", prvLedGetCommand, /* The function to run. */ 1 /* 1 parameters are expected. */ };
再在合適的時(shí)機(jī)注冊(cè)命令,如下所示:
(滑動(dòng)查看)
void vRegisterBspCliCommands(void) { /* Register all the command line commands defined immediately above. */ FreeRTOS_CLIRegisterCommand( &xLedSet ); FreeRTOS_CLIRegisterCommand( &xLedGet ); }
static void zygote_task(void *pvParameters) { uint32_t zygote_loop_cnt = 0; /* FreeRTOS-CLI 任務(wù)創(chuàng)建 */ vUARTCommandConsoleStart(); extern void vRegisterSampleCLICommands(void); vRegisterSampleCLICommands(); vRegisterBspCliCommands(); for (;;) { zygote_loop_cnt++; PRINTF("zygote loop cnt: %u ", zygote_loop_cnt); vTaskDelay(pdMS_TO_TICKS(2000)); } }
08 驗(yàn)證
發(fā)送命令ledset r on電量紅色LED
發(fā)送命令ledset r off熄滅紅色LED
發(fā)送命令ledget r獲取紅色LED點(diǎn)亮狀態(tài)
替換r/g/b可以正確執(zhí)行命令
-
恩智浦
+關(guān)注
關(guān)注
14文章
5929瀏覽量
111517 -
RGB
+關(guān)注
關(guān)注
4文章
803瀏覽量
59388 -
命令
+關(guān)注
關(guān)注
5文章
719瀏覽量
22627 -
開(kāi)發(fā)環(huán)境
+關(guān)注
關(guān)注
1文章
237瀏覽量
16961
原文標(biāo)題:用戶測(cè)評(píng)(四):使用NXP MCX-N板卡新增命令控制
文章出處:【微信號(hào):AvnetAsia,微信公眾號(hào):安富利】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
恩智浦 MCX N系列之電源管理(MCX N94/54與MCX N23)

恩智浦MCX N23的官方評(píng)估板FRDM-MCXN236詳解

貼片代碼MARKING絲印手冊(cè),新增NXP的
MCX314As型四軸運(yùn)動(dòng)控制器原理及應(yīng)用

恩智浦全新MCX N微控制器推出!助力實(shí)現(xiàn)高性能、低功耗的邊緣安全智能
恩智浦推出全新面向工業(yè)與物聯(lián)網(wǎng)應(yīng)用的MCX微控制器產(chǎn)品組合

貿(mào)澤電子開(kāi)售適用于智能電機(jī)控制和機(jī)器學(xué)習(xí)應(yīng)用的 NXP Semiconductors MCX微控制器
基于MCX N和MCX A系列微控制器,NXP宣布推出無(wú)線多協(xié)議MCX W系列

富昌電子推薦兩款恩智浦的MCX A和MCX N系列微控制器
恩智浦發(fā)布全新MCX W系列微控制器
MCX N系列微控制器適用于安全、智能的電機(jī)控制和機(jī)器學(xué)習(xí)應(yīng)用
NXP MCX N23和MCX N94/54的不同之處

用戶測(cè)評(píng)之體驗(yàn)NXP MCX-N板卡的NPU功能

使用NXP MCX-N板卡搭建環(huán)境及點(diǎn)燈

評(píng)論