单片机shell命令_MCU调试大法:使用串口实现简单shell功能
MCU調試大法:使用串口實現簡單shell功能
[復制鏈接]
MCU程序調試方法有很多,比如軟/硬件仿真、添加數據打印等。
像Keil?MDK就支持不少單片機的軟件仿真,在沒有拿到單片機的情況下,就可以先仿真調試部分功能,查看代碼邏輯是否正確。硬件仿真則需要借助仿真器,如調試Cortex內核MCU常用的J-Link/ST-Link等。通過watch窗口可以查看變量的值:
在代碼中添加數據的打印,則需要借助MCU的串口功能,將運行時的關鍵數據通過串口打印至PC,便于觀察。這是我調試時非常喜歡使用的一個功能,因為需要打印哪些數據完全自主可控,而且可以做到基本不影響程序正常運行。
這里順便把如何使用printf的方法講一下,比較簡單,會的同學可以直接略過:
/@@* 頭文件不能少 */
#include <stdio.h>
/@@* 平臺的選擇 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /@@* __GNUC__ */
PUTCHAR_PROTOTYPE
{
/@@* 這里只需要實現一個字符ch的發送即可,以下以ST為例 */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
return ch;
}
可交互的調試方法—shell
有了串口數據打印,尋找BUG方便了不少;但是隨著使用場景的增多:比如我需要在某個時刻打印某些數據、需要控制程序進入某個分支、調試算法時需要經常修改某些變量的值。此時光有打印就不行了,我需要一個可以實時和MCU進行交互的系統,那就是shell。
這里介紹一個體積極小的嵌入式shell,功能如下:
命令自動補全,使用tab鍵補全命令
命令長幫助,使用help [command]顯示命令長幫助
長幫助補全,輸入命令后雙擊tab鍵補全命令長幫助指令
快捷鍵,支持使用Ctrl + A~Z組合按鍵直接調用函數
shell變量,支持在shell中查看和修改變量值,支持變量作為命令參數
開始移植
1. 下載源碼并添加至工程中:
360截圖20191106140620843.jpg (5.14 KB, 下載次數: 0)
2019-11-6 14:06 上傳
360截圖20191106140437649.jpg (11.25 KB, 下載次數: 2)
2019-11-6 14:06 上傳
算上h文件,也就5個。
2. 初始化shell
定義shell全局實體:
SHELL_TypeDef shell;
在main中初始化,這里需要提供write函數,即字符發送函數:
/@@* 初始化shell */
shell.read = NULL; //采用中斷方式,所以不需要提供read方法
shell.write = user_shellWrite;
shellInit(&shell);
/@@* shell write定義 */
void user_shellWrite(const char ch)
{
/@@* 實現一個字符ch的發送功能,使用阻塞方式發送 */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
}
3. shell調用
在串口接收中斷中,調用shellHandler處理函數:
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
//將收到的字符實時送入shell處理
shellHandler(&shell, uart1_it_buf);
HAL_UART_Receive_IT(&huart1, (uint8_t *)&uart1_it_buf, 1);
}
4. 配置
將SHELL_DISPLAY_RETURN關閉,不然會打印shell函數返回值;SHELL_USING_CMD_EXPORT則根據個人喜好來,我這里將其關閉,所以以下將使用命令表來添加命令:
/@@**
* ?是否顯示命令調用函數返回值
* 使能此宏,則每次調用shell命令之后會以整形和十六進制的方式打印函數的返回值
*/
#define SHELL_DISPLAY_RETURN 0
/@@**
* @brief 是否使用命令導出方式
* 使能此宏后,可以使用`SHELL_EXPORT_CMD()`或者`SHELL_EXPORT_CMD_EX()`
* 定義shell命令,關閉此宏的情況下,需要使用命令表的方式
*/
#define SHELL_USING_CMD_EXPORT 0
5. 添加命令
因為定義了SHELL_USING_CMD_EXPORT為0,所以我們使用命令表來添加命令。在shell.c中,這里我們可以看到默認實現了兩個命令help和cls:
const SHELL_CommandTypeDef shellDefaultCommandList[] =
{
SHELL_CMD_ITEM_EX(help, shellHelp, command help, help [command] --show help info of command),
SHELL_CMD_ITEM(cls, shellClear, clear command line),
/@@* 在這里按照格式添加自己的命令,如顯示版本 */
SHELL_CMD_ITEM(version, shell_showVersion, show current version),
};
shell_showVersion的實現,可以在其他C文件中實現
/@@**
* @brief shell顯示當前軟件版本
*
*/
void shell_showVersion(void)
{
SHELL_TypeDef *shell = shellGetCurrent();
if (!shell)
{
return;
}
shellDisplay(shell, "\r\n V1.0.0\r\n");
shellDisplay(shell, "\r\n Build: "__DATE__" "__TIME__"\r\n");
return;
}
6. run
實際效果如下:
按TAB可以顯示所有命令,在輸入命令時按TAB還可以自動補全。
其他
這里只是完成了最基礎的移植工作,還有一些高級的功能就等著大家自行摸索啦。
有了shell調試起來肯定如虎添翼,呼呼哈哈!
還有一點,給客戶演示demo的時候,逼格也高了很多,哈哈哈!
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的单片机shell命令_MCU调试大法:使用串口实现简单shell功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Rose环境和用例图
- 下一篇: win8优化(win8优化大师设置开始界