Implement DMA for USART1 reception and update FreeRTOS configuration
- Modified shell_port.c to replace interrupt-based UART reception with DMA. - Introduced a DMA buffer for UART data and adjusted the shell buffer handling. - Added idle interrupt handling to process incoming data from the DMA buffer. - Updated freertos_f407.ioc to configure DMA for USART1 RX and TX. - Enabled necessary NVIC interrupts for DMA streams associated with USART1.
This commit is contained in:
parent
9f37c7d763
commit
21e9d75e40
|
|
@ -54,9 +54,11 @@ void UsageFault_Handler(void);
|
|||
void DebugMon_Handler(void);
|
||||
void USART1_IRQHandler(void);
|
||||
void TIM6_DAC_IRQHandler(void);
|
||||
void DMA2_Stream2_IRQHandler(void);
|
||||
void DMA2_Stream3_IRQHandler(void);
|
||||
void OTG_FS_IRQHandler(void);
|
||||
void DMA2_Stream6_IRQHandler(void);
|
||||
void DMA2_Stream7_IRQHandler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
|
|
|||
|
|
@ -43,12 +43,18 @@ void MX_DMA_Init(void)
|
|||
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||
|
||||
/* DMA interrupt init */
|
||||
/* DMA2_Stream2_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
|
||||
/* DMA2_Stream3_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 15, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
||||
/* DMA2_Stream6_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 15, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
|
||||
/* DMA2_Stream7_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@
|
|||
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
||||
extern DMA_HandleTypeDef hdma_sdio_rx;
|
||||
extern DMA_HandleTypeDef hdma_sdio_tx;
|
||||
extern DMA_HandleTypeDef hdma_usart1_rx;
|
||||
extern DMA_HandleTypeDef hdma_usart1_tx;
|
||||
extern UART_HandleTypeDef huart1;
|
||||
extern TIM_HandleTypeDef htim6;
|
||||
|
||||
|
|
@ -169,7 +171,13 @@ void DebugMon_Handler(void)
|
|||
void USART1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_IRQn 0 */
|
||||
|
||||
// 璉?<3F>亦征<E4BAA6>脖葉<E88496>剜<EFBFBD>敹?
|
||||
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
|
||||
{
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
|
||||
extern void shell_uart_rx_idle_callback(void);
|
||||
shell_uart_rx_idle_callback();
|
||||
}
|
||||
/* USER CODE END USART1_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart1);
|
||||
/* USER CODE BEGIN USART1_IRQn 1 */
|
||||
|
|
@ -191,6 +199,20 @@ void TIM6_DAC_IRQHandler(void)
|
|||
/* USER CODE END TIM6_DAC_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA2 stream2 global interrupt.
|
||||
*/
|
||||
void DMA2_Stream2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA2_Stream2_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_rx);
|
||||
/* USER CODE BEGIN DMA2_Stream2_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA2_Stream2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA2 stream3 global interrupt.
|
||||
*/
|
||||
|
|
@ -231,6 +253,20 @@ void DMA2_Stream6_IRQHandler(void)
|
|||
/* USER CODE END DMA2_Stream6_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA2 stream7 global interrupt.
|
||||
*/
|
||||
void DMA2_Stream7_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA2_Stream7_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA2_Stream7_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_tx);
|
||||
/* USER CODE BEGIN DMA2_Stream7_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA2_Stream7_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
/* USER CODE END 0 */
|
||||
|
||||
UART_HandleTypeDef huart1;
|
||||
DMA_HandleTypeDef hdma_usart1_rx;
|
||||
DMA_HandleTypeDef hdma_usart1_tx;
|
||||
|
||||
/* USART1 init function */
|
||||
|
||||
|
|
@ -80,6 +82,43 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
|||
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USART1 DMA Init */
|
||||
/* USART1_RX Init */
|
||||
hdma_usart1_rx.Instance = DMA2_Stream2;
|
||||
hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
|
||||
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
|
||||
|
||||
/* USART1_TX Init */
|
||||
hdma_usart1_tx.Instance = DMA2_Stream7;
|
||||
hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4;
|
||||
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
|
||||
|
||||
/* USART1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(USART1_IRQn);
|
||||
|
|
@ -106,6 +145,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
|||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
|
||||
|
||||
/* USART1 DMA DeInit */
|
||||
HAL_DMA_DeInit(uartHandle->hdmarx);
|
||||
HAL_DMA_DeInit(uartHandle->hdmatx);
|
||||
|
||||
/* USART1 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(USART1_IRQn);
|
||||
/* USER CODE BEGIN USART1_MspDeInit 1 */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,12 +17,14 @@ char shellBuffer[512];
|
|||
|
||||
static SemaphoreHandle_t shellMutex;
|
||||
|
||||
// 串口接收缓冲区(环形队列)
|
||||
// DMA接收缓冲区和shell环形缓冲区
|
||||
#define SHELL_UART_DMA_BUF_SIZE 256
|
||||
#define SHELL_UART_RX_BUF_SIZE 128
|
||||
static uint8_t shell_uart_dma_buf[SHELL_UART_DMA_BUF_SIZE];
|
||||
static uint8_t shell_uart_rx_buf[SHELL_UART_RX_BUF_SIZE];
|
||||
static volatile uint16_t shell_uart_rx_head = 0;
|
||||
static volatile uint16_t shell_uart_rx_tail = 0;
|
||||
static uint8_t shell_uart_rx_temp;
|
||||
static volatile uint16_t shell_uart_dma_last_pos = 0;
|
||||
|
||||
/**
|
||||
* @brief 用户shell写
|
||||
|
|
@ -106,8 +108,10 @@ void userShellInit(void)
|
|||
shell.unlock = userShellUnlock;
|
||||
shellInit(&shell, shellBuffer, 512);
|
||||
|
||||
// 启动串口中断接收
|
||||
HAL_UART_Receive_IT(&huart1, &shell_uart_rx_temp, 1);
|
||||
// 启动DMA接收
|
||||
HAL_UART_Receive_DMA(&huart1, shell_uart_dma_buf, SHELL_UART_DMA_BUF_SIZE);
|
||||
// 使能空闲中断
|
||||
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
|
||||
|
||||
xTaskCreate((TaskFunction_t)shellTask, // 任务入口函数
|
||||
(const char *)"shell_task", // 任务名字
|
||||
|
|
@ -117,19 +121,21 @@ void userShellInit(void)
|
|||
NULL); // 任务句柄
|
||||
}
|
||||
|
||||
// 串口接收完成回调(在 usart.c 里实现也可)
|
||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
// USART1 空闲中断处理(DMA新数据转入shell缓冲区)
|
||||
void shell_uart_rx_idle_callback(void)
|
||||
{
|
||||
if (huart->Instance == USART1)
|
||||
uint16_t dma_pos = SHELL_UART_DMA_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx);
|
||||
uint16_t data_len = (dma_pos >= shell_uart_dma_last_pos) ? (dma_pos - shell_uart_dma_last_pos) : (SHELL_UART_DMA_BUF_SIZE - shell_uart_dma_last_pos + dma_pos);
|
||||
for (uint16_t i = 0; i < data_len; i++)
|
||||
{
|
||||
uint8_t ch = shell_uart_dma_buf[(shell_uart_dma_last_pos + i) % SHELL_UART_DMA_BUF_SIZE];
|
||||
uint16_t next = (shell_uart_rx_head + 1) % SHELL_UART_RX_BUF_SIZE;
|
||||
if (next != shell_uart_rx_tail)
|
||||
{
|
||||
shell_uart_rx_buf[shell_uart_rx_head] = shell_uart_rx_temp;
|
||||
shell_uart_rx_buf[shell_uart_rx_head] = ch;
|
||||
shell_uart_rx_head = next;
|
||||
}
|
||||
// 继续接收下一个字节
|
||||
HAL_UART_Receive_IT(&huart1, &shell_uart_rx_temp, 1);
|
||||
}
|
||||
shell_uart_dma_last_pos = dma_pos;
|
||||
}
|
||||
// CEVENT_EXPORT(EVENT_INIT_STAGE2, userShellInit);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ CAD.pinconfig=
|
|||
CAD.provider=
|
||||
Dma.Request0=SDIO_RX
|
||||
Dma.Request1=SDIO_TX
|
||||
Dma.RequestsNb=2
|
||||
Dma.Request2=USART1_RX
|
||||
Dma.Request3=USART1_TX
|
||||
Dma.RequestsNb=4
|
||||
Dma.SDIO_RX.0.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.SDIO_RX.0.FIFOMode=DMA_FIFOMODE_ENABLE
|
||||
Dma.SDIO_RX.0.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL
|
||||
|
|
@ -31,6 +33,26 @@ Dma.SDIO_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_WORD
|
|||
Dma.SDIO_TX.1.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.SDIO_TX.1.Priority=DMA_PRIORITY_LOW
|
||||
Dma.SDIO_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst
|
||||
Dma.USART1_RX.2.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.USART1_RX.2.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.USART1_RX.2.Instance=DMA2_Stream2
|
||||
Dma.USART1_RX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.USART1_RX.2.MemInc=DMA_MINC_ENABLE
|
||||
Dma.USART1_RX.2.Mode=DMA_NORMAL
|
||||
Dma.USART1_RX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.USART1_RX.2.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.USART1_RX.2.Priority=DMA_PRIORITY_LOW
|
||||
Dma.USART1_RX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
Dma.USART1_TX.3.Direction=DMA_MEMORY_TO_PERIPH
|
||||
Dma.USART1_TX.3.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
Dma.USART1_TX.3.Instance=DMA2_Stream7
|
||||
Dma.USART1_TX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
|
||||
Dma.USART1_TX.3.MemInc=DMA_MINC_ENABLE
|
||||
Dma.USART1_TX.3.Mode=DMA_NORMAL
|
||||
Dma.USART1_TX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
|
||||
Dma.USART1_TX.3.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.USART1_TX.3.Priority=DMA_PRIORITY_LOW
|
||||
Dma.USART1_TX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
FATFS.BSP.number=1
|
||||
FATFS.IPParameters=_CODE_PAGE,_USE_LFN,_VOLUMES
|
||||
FATFS._CODE_PAGE=936
|
||||
|
|
@ -105,8 +127,10 @@ Mcu.UserName=STM32F407ZGTx
|
|||
MxCube.Version=6.9.2
|
||||
MxDb.Version=DB.6.0.92
|
||||
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream3_IRQn=true\:15\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream6_IRQn=true\:15\:0\:true\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DMA2_Stream7_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
NVIC.ForceEnableDMAVector=true
|
||||
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||
|
|
|
|||
Loading…
Reference in New Issue