基于MDK平台 cortex-M3 shell 的实现

本文介绍了如何在MDK平台上实现Cortex-M3处理器的Shell功能,以简化代码测试。作者分享了从U-BOOT和RTT-Shell中汲取灵感并简化后的Shell代码,包括命令登记、Console接口和Shell处理。通过示例代码,展示了如何使用和注册命令,并提供了命令处理函数。此外,还包含了删除字符、读取行和解析行等实用函数的实现。

    每次写完代码最头疼的就是测试,大多数时间都得花在这里。要么用串口调试助手、要么用上位机。至于串口调度助手效率,大家都懂的。但又不想每次都写一个上位机、闲暇之余模仿u-boot和rtt-shell 写了一个shell,大多数代码都来自U-BOOT的、做了小小的阉割。

使用方法

/*在需要登记命令的文件内包含shell.h、console.h两个头文件  */

例:

REG_CMD                                            --命令登记宏

(

    printconf,                   --命令名

   3,                                --命令的最大参数个数

  do_printconf,             --命令处理函数(函数的类型遵循      int  (*cmd_callback)(struct cmd_tbl_t *, int argc, char **argv))

    "显示系统配置",     --简单的使用说明

    "打印系统配置信息."                      --详细使用说明

);

另外由于所有的命令列表都编译到了cmdlist代码段,所以需要在编译器中设置防止cmdlist被优化。



暂时没心思写详细说明,直接给出代码。

代码主要由四个文件组成(Console.c、Console.h、shell.c、shell.h)

Console提供打印移植接口

/*console.h*/

#ifndef _CONSOLE_H_

#define _CONSOLE_H_

#include "app_type.h"

 

void console_init(void);

void console_putc(const char c);

void console_puts(const char * s);

bool console_get(char  *c);

char console_getc(void);

                                                              /*---对输入格式化字符串进行检测---*/

void console_printf (const char *fmt, ...) __attribute__((format(printf,1,2)));

#endif  

/*console.c*/

#include "includes.h"

#include <stdio.h>

#include <stdarg.h>

#include <stdbool.h>

#include <string.h>

 

 

/**==========================================================

 *@brief 控制台初始化

 *@param none

 ==========================================================*/

void console_init(void){}

/**==========================================================

 *@brief 输出一个字符到串口控制台

 *@param c

 ==========================================================*/

void console_putc(const char c){}

 

/**==========================================================

 *@brief 输出一个字符串到串口控制台

 *@param s

 ==========================================================*/

void console_puts(const char * s){}

 

/**==========================================================

 *@brief 从串口控制台获取一个输入字符

 *@retval true:成功获取

 ==========================================================*/

bool console_get(char  *c){}

 

/**==========================================================

 *@brief 从串口控制台获取一个输入字符

 *@retval c

 *@attetion 阻塞方式调用

 ==========================================================*/

char console_getc(void){}


static char printbuffer[128];

/**==========================================================

 *@brief 打印一个格式化字符串到串口控制台

 *@retval 

 ==========================================================*/

void console_printf (const char *fmt, ...)

{

        va_list args;                                                  

va_start (args, fmt);                                             

vsprintf (printbuffer, fmt, args);                    //将输入参考格式化后放到缓冲区

va_end (args);

console_puts (printbuffer);

}

 

/*shell 提供命令处理*/

/*shell.h*/

/**********************************************************************

* @file shell.h

* @brief 命令行处理

*  

* @version 1.0

* @date 2015-06-09

* @author roger

*

* Copyright(C) 2015 

* All rights reserved.

* Copyright(C) 2015  QQ 932896234

* @reference u-boot

*

***********************************************************************/

 

#ifndef __SHELL_H_

#define __SHELL_H_

 

#ifndef NULL

#define NULL 0

#endif

 

#define CFG_MAXARGS 16                       /*最大参数个数-----------------*/

#define CFG_MAXCMDS 30                       /*最多允许定义的命令个数-------*/

 

/*----------------------------------------------------------------------------------------------------------

 * Monitor Command Table

 --------------------------------------------------------------------------------------------------------*/

typedef struct  cmd_tbl_t

{

char *name;                       /* 命令名                                                         */

     char    maxargs;                         &nb

### 实现STM32F103VCT6开发板与PC机的串口通信 #### 软件环境配置 为了实现STM32F103VCT6开发板与PC机的串口通信,需要先搭建好开发环境。以下是具体的软件工具及其用途: - **Keil MDK**:用于编写和编译嵌入式C代码[^2]。 - **ST-Link驱动**:通过ST-Link调试器将程序烧录到STM32芯片中[^2]。 在Keil MDK中创建项目时,需确保选择了正确的设备型号(即STM32F103VCT6)。此外,还需安装对应的Device Pack以支持特定硬件特性[^2]。 --- #### 硬件连接设置 要实现串口通信,通常利用USART接口完成数据交换。对于STM32F103系列而言,其具备多个USART模块可供选择[^1]。假设选用USART1作为主要通讯通道,则应按照以下方式连接开发板与计算机: - 开发板上的TXD引脚接至USB转TTL模块的RXD端; - RXD引脚对应于USB转TTL模块的TXD端; - GND两端共地处理。 注意实际连线前确认电平匹配情况以免损坏器件。 --- #### 配置USART参数 接下来,在初始化阶段设定波特率、字长、停止位等基本属性来满足双方同步需求。下面给出一段典型配置示例供参考: ```c #include "stm32f1xx.h" void USART_Init(void){ GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); // PA9(TX),PA10(RX) GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); USART_StructInit(&USART_InitStruct); USART_InitStruct.USART_BaudRate = 115200; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No ; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None ; USART_Init(USART1,&USART_InitStruct); USART_Cmd(USART1,ENABLE); } ``` 此段代码完成了对USART1的基础定义工作,并启用了发送接收功能。 --- #### 编写Shell命令解析逻辑 为了让SecureCRT能解读来自用户的指令并据此操控目标系统的继电器状态或其他物理行为,可以在主循环里加入简单的字符串比较机制判断输入内容是否符合预期模式。例如检测收到的是字符&#39;o&#39;(代表开)还是&#39;c&#39;(表示关),然后分别调用相应API改变指定管脚高低电平达到目的效果: ```c uint8_t RxBuffer[2]; int main(){ USART_Init(); while(1){ if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)){ RxBuffer[0]=USART_ReceiveData(USART1); switch(RxBuffer[0]){ case &#39;o&#39;: GPIO_SetBits(GPIOB,GPIO_Pin_5);//假定PB5控制LED灯泡点亮 break; case &#39;c&#39;: GPIO_ResetBits(GPIOB,GPIO_Pin_5); break; default : break; } } } } ``` 以上片段展示了如何监听串口中断事件获取最新到达的数据包,并依据预设规则执行动作[^1]。 --- #### 使用SecureCRT测试交互过程 最后一步便是借助第三方终端模拟应用程序——SecureCRT来进行远程管理和监控整个装置的表现状况。启动之后新建会话指向本地COM端口号,调整适配前面提到过的速率数值一致即可开始键入自定义好的关键词触发响应反馈。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值