单片机上使用shell控制台

本文介绍如何将Shell控制台移植到单片机平台,包括修改宏定义、编译器设置及接口实现等关键步骤。适用于希望在嵌入式系统中增加命令行交互功能的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


单片机控制台第一次使用是在RTthread上的Finsh组件,当时感觉挺好,但也一直没移植到其他单片机芯片平台,主要是一直搞Linux的开发,最近看了下刚准备搞,发现有个开源的做的不赖。 LetterShell开源项目地址

效果

在这里插入图片描述

移植方法

目前3.06版本的IAR测试存在问题,定位到指定段(shellCommand),需要增加编译器关键字__root
修改如下:
shell.h文件
替换其中的宏定义

#ifndef SECTION
  #ifdef __CC_ARM                        /* ARM Compiler */
      #define SECTION(x)                 __attribute__((section(x)))
      #define USED                       __attribute__((used))
  #elif defined (__IAR_SYSTEMS_ICC__)    /* for IAR Compiler */
      #define SECTION(x)                 @ x
      #define USED                       __root
  #elif defined (__GNUC__)               /* GNU GCC Compiler */
      #define SECTION(x)                 __attribute__((section(x)))
      #define USED                       __attribute__((used))
  #else
      #error not supported tool chain
  #endif /* __CC_ARM */
#endif

文件中所有定位到shellCommand段的常量全部增加USED宏即(__root

USED const ShellCommand \
            shellCommand##_name SECTION("shellCommand")

shell.c文件有一个需要修改
在这里插入图片描述
以上修改好即可。

IAR指定段的起始地址设置,修改icf文件(非必须)

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
define symbol __ICFEDIT_const_data_start__ = 0x08008000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__     = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__       = 0x081FFFFF;
define symbol __ICFEDIT_region_RAM_start__     = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__       = 0x2001FFFF;
define symbol __ICFEDIT_region_ITCMRAM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ITCMRAM_end__   = 0x0000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x0000A000;
define symbol __ICFEDIT_size_heap__ = 0x0000C000;
/**** End of ICF editor section. ###ICF###*/


define memory mem with size = 4G;
define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
define region ITCMRAM_region  = mem:[from __ICFEDIT_region_ITCMRAM_start__ to __ICFEDIT_region_ITCMRAM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:__ICFEDIT_const_data_start__ { readonly section shellCommand };

place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

加入文件到工程

1、复制源码
在这里插入图片描述

2、加入到工程
在这里插入图片描述

3、加入头文件路径到工程
在这里插入图片描述

完善接口

4、在Shell_Port.c中根据需要完善读、写、初始化接口

以下模板使用的STM32串口操作库文件和环形队列库文件

/**
 * @brief shell写
 * 
 * @param data 数据
 */
static void Shell_Port_Write(char data)
{
  /*底层接口最好是阻塞式发送*/
  Uart_Port_Transmit_Data(Uart_Dev_Handle, (uint8_t *)&data, 1);
}

/**
 * @brief shell读
 * 
 * @param data 数据
 * @return char 状态
 */
static signed char Shell_Port_Read(char *data)
{
  uint32_t len = CQ_getLength(Uart_Dev_Handle->cb);
  if(len == 0)
  {
    return -1;
  }
  CQ_getData(Uart_Dev_Handle->cb, (uint8_t *)data, 1);
  return 0;
}

/**
 * @brief shell初始化
 * 
 * @param data 数据
 * @return char 状态
 */
void Shell_Port_Init(void)
{
  Uart_Dev_Handle = Uart_Port_Get_Handle(UART_NUM_1);
  if(Uart_Dev_Handle == NULL)
  {
    return;
  }
  shell.write = Shell_Port_Write;
  shell.read = Shell_Port_Read;
  shellInit(&shell, shellBuffer, 512);
}

如需使用串口操作库文件则需要移植它,并修改如下接口为阻塞式发送

/************************************************************
  * @brief   串口数据发送
  * @param   [in]uart_opt_handle 串口句柄.
  * @param   [in]data 数据.
  * @param   [in]size 数据大小.
  * @return  true 发送成功.
  * @author  aron566
  * @date    2020/3/15
  * @version v1.0
  * @note    @@
  ***********************************************************/
bool Uart_Port_Transmit_Data(Uart_Dev_Handle_t *uart_opt_handle, uint8_t *data, uint16_t size)
{
  if(uart_opt_handle == NULL)
  {
    return false;
  }
  if(HAL_UART_Transmit(uart_opt_handle->phuart, data, size, 0xFF) != HAL_OK)
  {
    return false;
  }
  return true;
} 

测试代码

int func(int argc, char *argv[])
{
    printf("%dparameter(s)\r\n", argc);
    for (char i = 1; i < argc; i++)
    {
        printf("%s\r\n", argv[i]);
    }
    return 0;
}

/** Public application code --------------------------------------------------*/
/*******************************************************************************
*
*       Public code
*
********************************************************************************
*/
/**
  ******************************************************************
  * @brief   引导任务启动
  * @param   [in]None
  * @return  None.
  * @author  aron566
  * @version v1.0
  * @date    2021/2/1
  ******************************************************************
  */
int main(void)
{
   /*初始化硬件,串口。。。*/
   /*TODO*/

	/*其他初始化*/
	User_Main_Init();
	
	for(;;)
	{
		/*启动shell*/
	  	Shell_Port_Start();
	}  
}

/**
  ******************************************************************
  * @brief   初始化任务
  * @param   [in]None
  * @return  None.
  * @author  aron566
  * @version v1.0
  * @date    2021/2/1
  ******************************************************************
  */
void User_Main_Init(void)
{
  /*初始化串口设备*/
  Uart_Port_Init();
  
  /*Flash操作初始化*/
  Flash_Port_Init();
  
  /*Shell初始化*/
  Shell_Port_Init();
}
/*导出功能函数*/
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), func, func, test);

本次移植代码工具地址

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

aron566

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

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

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

打赏作者

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

抵扣说明:

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

余额充值