背景
尝试移植lettershell,但是仿照其他教程,移植好文件后,通过正常串口不带中断收发,数据异常,只有到波特率降低到9600才能正常显示,并且Shell软件无法交互。因此怀疑是中断处理时间太长,尝试降低串口中断执行的时间,减少阻塞程度。因此采用串口 空闲中断 + DMA 方式。
lettershell版本 v3.1.2
硬件 stm32f103
CubeMX配置
配置串口中断
配置DMA
串口配置完成后,我们重新实现串口空闲中断回调函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)//Size参数是本次接受到的数据长度
{
if(huart->Instance == USART2)
{
for(uint8_t i = 0;i < Size;i++){
shellHandler(&shell, (char)r_data[i]);
}
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, r_data, sizeof(r_data));//重新启动接收
}
}
函数初始化
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, r_data, sizeof(r_data));/* 设置串口接收DMA空闲中断*/
userShellInit();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(3000);
}
/* USER CODE END 3 */
}
LetterShell配置部分
shell_port.c 实现
由于是中断触发,因此只要注册write的回调即可
/**
* @file shell_port.c
* @author Letter (NevermindZZT@gmail.com)
* @brief
* @version 0.1
* @date 2019-02-22
*
* @copyright (c) 2019 Letter
*
*/
#include "shell.h"
#include "usart.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
Shell shell;
char shellBuffer[512];
/**
* @brief 用户shell写
*
* @param data 数据
* @param len 数据长度
*
* @return short 实际写入的数据长度
*/
short userShellWrite(char *data, unsigned short len)
{
HAL_UART_Transmit(&huart2,(uint8_t *)(data),len,1000);
return len;
}
/**
* @brief 用户shell读
*
* @param data 数据
* @param len 数据长度
*
* @return short 实际读取到
*/
//short userShellRead(char *data, unsigned short len)
//{
// return serialReceive(&huart2, (uint8_t *)data, len, 0);
//}
/**
* @brief 用户shell初始化
*
*/
void userShellInit(void)
{
shell.write = userShellWrite;
shellInit(&shell, shellBuffer, 512);
}
//CEVENT_EXPORT(EVENT_INIT_STAGE2, userShellInit);
之后将该宏注释掉即可设置lettershell为中断处理模式
lettershell步骤细节参考【嵌入式】开源shell命令行的移植和使用(2)——letter-shell_letter shell-CSDN博客