利用串口移植nr_micro_shell在其他mcu上已经实现多次了。本次也是先在stm32h533上实现移植shell。方便后续通过shell测试。
首先在STM32CUBEMX上配置串口,基本都是默认设置。主要是打开串口中断功能,实现串口接收不漏数据。
添加nr_micro_shell代码到工程内,然后在nr_micro_shell_config.h内配置shell功能和串口发送接收数据接口。
添加串口发送接收数据驱动。这里实现的是中断接收进入FIFO缓存数据。
typedef struct fifo_buffer_t
{
volatile uint32_t read_i;
volatile uint32_t write_i;
uint8_t buff[512];
}fifo_buffer_t;
typedef struct shell_uart_buffer_t
{
fifo_buffer_t tx;
fifo_buffer_t rx;
volatile uint32_t tx_cpl : 1;
}shell_uart_buffer_t;
extern shell_uart_buffer_t g_shell_uart;
static uint8_t uart_recv_buff[4];
static uint8_t uart_send_buff[128];
shell_uart_buffer_t g_shell_uart=
{
.tx.read_i = 0,
.tx.write_i = 0,
.rx.read_i = 0,
.rx.write_i = 0,
.tx_cpl = 0,
};
//
static void uart_get_data_send(void)
{
uint32_t i;
//
for(i=0;i<128;i++)
{
if(g_shell_uart.tx.read_i != g_shell_uart.tx.write_i)
{
uart_send_buff[i] = g_shell_uart.tx.buff[g_shell_uart.tx.read_i++];
g_shell_uart.tx.read_i &= 0x1ff; //256Byte
}else break;
}
if(i)
{
g_shell_uart.tx_cpl = 1;
HAL_UART_Transmit_IT(&huart2,uart_send_buff,i);
}
}
static void uart_send_char(uint8_t ch)
{
while(((g_shell_uart.tx.write_i+1)&0x1ff) == g_shell_uart.tx.read_i)
{
//fifo buffer full
if((g_shell_uart.tx_cpl == 0))
{
uart_get_data_send();
}
}
g_shell_uart.tx.buff[g_shell_uart.tx.write_i++] = ch;
g_shell_uart.tx.write_i &= 0x1ff;//256Byte
if((g_shell_uart.tx_cpl == 0))
{
uart_get_data_send();
}
}
//////////////////////////////////////////////////////////////////////////////
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2) //shell
{
//
if(((g_shell_uart.rx.write_i+1)&0x1ff) != g_shell_uart.rx.read_i)
{
g_shell_uart.rx.buff[g_shell_uart.rx.write_i++] = uart_recv_buff[0] & 0xff;
g_shell_uart.rx.write_i &= 0x1ff;//256Byte
}
HAL_UART_Receive_IT(huart,uart_recv_buff,1);//
}
}
//
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2) //shell
{
g_shell_uart.tx_cpl = 0;
uart_get_data_send();
}
}
//
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2) //shell
{
HAL_UART_Receive_IT(huart,uart_recv_buff,1);//
}
}
然后就是shell初始化和读取串口接收的FIFO数据进入shell解析。
void shell_usart_init(void)
{
#ifdef UART_SHELL
#if UART_SHELL == 1
userShellInit(); //LETTER_SHELL
#elif UART_SHELL == 2
shell_init(); //NR_MICRO_SHELL
#endif
#endif
HAL_UART_Receive_IT(&huart2,uart_recv_buff,1);//
}
void shell_usart_loop(void)
{
//
if(g_shell_uart.rx.read_i != g_shell_uart.rx.write_i)
{
#ifdef UART_SHELL
#if UART_SHELL == 1
shellHandler(&shell, g_shell_uart.rx.buff[g_shell_uart.rx.read_i++]); //letter shell
#elif UART_SHELL == 2
shell(g_shell_uart.rx.buff[g_shell_uart.rx.read_i++]);
#endif
#endif
g_shell_uart.rx.read_i &= 0x1ff; //256Byte
}
if(g_shell_uart.tx_cpl == 0)
{
uart_get_data_send();
}
}
添加nr_micro_shell头文件路径,以及优化等级。
最后在主循环main中添加初始化和循环处理数据。
编译下载代码:
运行之后就可以看到串口输出了。
|