前言
本次使用的是lwrb开源的源码; 测试环境使用的是stm32f407zgt6 这里不介绍lwrb的内容,如有需要请自行去查阅. 这里会使用到rt_container_of的宏定义(相关介绍请参考rt_thread或linux源码相关的宏定义,其表达的内容是一致的) 这里使用的是threadx做为os 本次驱动存在一个数据拷贝的问题(待优化,最简单的方式就是重写HAL库自定义的中断处理函数) 本次只涉及到中断的方式,dma的话对应的回调函数都是一致的。
串口驱动编写
头文件
# ifndef BSP_UART_H
# define BSP_UART_H
# define UART1_RX_BUF_SIZE 1 * 1024
# define UART1_FRAME_MAX_SIZE 256
# include <lwrb/lwrb.h> struct stm32_uart_device { UART_HandleTypeDef handle; struct lwrb rx_lwrb; uint8_t * cache_buf; uint16_t cache_len; void ( * tx_complete_cb) ( void * ) ;
} ;
int bsp_uart_init ( void ) ;
int uart_receive ( const USART_TypeDef * uart, void * pdata, int len) ;
int uart_send_block ( const USART_TypeDef * uart, const void * pdata, int len) ;
int uart_send_async ( const USART_TypeDef * uart, const void * pdata, int len, void ( * tx_complete_cb) ( void * ) ) ; # endif
源文件 (这里只实现串口1)
# include "bsp.h"
# define khyx_container_of ( ptr, type, member) \ ( type * ) ( ( char * ) ( ptr) - offsetof ( type, member) )
enum { UART1_IDX = 0 , UART_MAX_NUMBER
} UART_IDX; static uint8_t uart1_rx_buf[ UART1_RX_BUF_SIZE] ;
static struct stm32_uart_device * uart_map[ UART_MAX_NUMBER] ; int bsp_uart_init ( void ) { { static struct stm32_uart_device uart1 = { 0 } ; uart1. handle. Instance = USART1; uart1. handle. Init. BaudRate = 115200 ; uart1. handle. Init. WordLength = UART_WORDLENGTH_8B; uart1. handle. Init. StopBits = UART_STOPBITS_1; uart1. handle. Init. Parity = UART_PARITY_NONE; uart1. handle. Init. Mode = UART_MODE_TX_RX; uart1. handle. Init. HwFlowCtl = UART_HWCONTROL_NONE; HAL_UART_Init ( & uart1. handle) ; lwrb_init ( & uart1. rx_lwrb, uart1_rx_buf, UART1_RX_BUF_SIZE) ; static uint8_t uart1_cache_buf[ UART1_FRAME_MAX_SIZE] ; uart1. cache_buf = uart1_cache_buf; uart1. cache_len = sizeof ( uart1_cache_buf) ; HAL_UARTEx_ReceiveToIdle_IT ( & uart1. handle, uart1. cache_buf, uart1. cache_len) ; uart_map[ UART1_IDX] = & uart1; } return 0 ;
} struct stm32_uart_device * usart_to_dev ( const USART_TypeDef * uart) { if ( uart == USART1) { return uart_map[ UART1_IDX] ; } return NULL ;
}
int uart_receive ( const USART_TypeDef * uart, void * pdata, int len) { struct stm32_uart_device * dev = usart_to_dev ( uart) ; return dev ? lwrb_read ( & dev-> rx_lwrb, pdata, len) : 0 ;
}
int uart_send_block ( const USART_TypeDef * uart, const void * pdata, const int len) { struct stm32_uart_device * dev = usart_to_dev ( uart) ; return dev ? HAL_UART_Transmit ( & dev-> handle, pdata, len, 100 ) : HAL_OK;
} int uart_send_async ( const USART_TypeDef * uart, const void * pdata, const int len, void ( * tx_complete_cb) ( void * ) ) { struct stm32_uart_device * dev = usart_to_dev ( uart) ; if ( dev == NULL ) return HAL_ERROR; dev-> tx_complete_cb = tx_complete_cb; return HAL_UART_Transmit_IT ( & dev-> handle, pdata, len) ;
}
void USART1_IRQHandler ( void ) { HAL_UART_IRQHandler ( & uart_map[ UART1_IDX] -> handle) ;
} void HAL_UART_RxCpltCallback ( UART_HandleTypeDef * huart) { struct stm32_uart_device * uart = khyx_container_of ( huart, struct stm32_uart_device , handle) ; lwrb_write ( & uart-> rx_lwrb, uart-> cache_buf, uart-> cache_len) ; HAL_UARTEx_ReceiveToIdle_IT ( & uart-> handle, uart-> cache_buf, uart-> cache_len) ;
}
void HAL_UART_TxCpltCallback ( UART_HandleTypeDef * huart) { struct stm32_uart_device * uart = khyx_container_of ( huart, struct stm32_uart_device , handle) ; if ( uart-> tx_complete_cb) uart-> tx_complete_cb ( uart) ;
} void HAL_UARTEx_RxEventCallback ( UART_HandleTypeDef * huart, uint16_t Size) { struct stm32_uart_device * uart = khyx_container_of ( huart, struct stm32_uart_device , handle) ; lwrb_write ( & uart-> rx_lwrb, uart-> cache_buf, Size) ; HAL_UARTEx_ReceiveToIdle_IT ( & uart-> handle, uart-> cache_buf, uart-> cache_len) ;
}
void HAL_UART_ErrorCallback ( const UART_HandleTypeDef * huart) { struct stm32_uart_device * uart = khyx_container_of ( huart, struct stm32_uart_device , handle) ; HAL_UARTEx_ReceiveToIdle_IT ( & uart-> handle, uart-> cache_buf, uart-> cache_len) ;
}
引脚初始化
void HAL_UART_MspInit ( UART_HandleTypeDef * huart) { GPIO_InitTypeDef GPIO_InitStruct = { 0 } ; if ( huart-> Instance == USART1) { __HAL_RCC_USART1_CLK_ENABLE ( ) ; __HAL_RCC_GPIOA_CLK_ENABLE ( ) ; GPIO_InitStruct. Pin = GPIO_PIN_9 | GPIO_PIN_10; GPIO_InitStruct. Mode = GPIO_MODE_AF_PP; GPIO_InitStruct. Pull = GPIO_NOPULL; GPIO_InitStruct. Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct. Alternate = GPIO_AF7_USART1; HAL_GPIO_Init ( GPIOA, & GPIO_InitStruct) ; HAL_NVIC_SetPriority ( USART1_IRQn, 0 , 0 ) ; HAL_NVIC_EnableIRQ ( USART1_IRQn) ; }
} void HAL_UART_MspDeInit ( UART_HandleTypeDef * huart) { if ( huart-> Instance == USART1) { __HAL_RCC_USART1_CLK_DISABLE ( ) ; HAL_GPIO_DeInit ( GPIOA, GPIO_PIN_9 | GPIO_PIN_10) ; HAL_NVIC_DisableIRQ ( USART1_IRQn) ; }
} # endif
驱动的使用(发送什么回什么)
初始化
khyx_int bsp_init ( void ) { SystemClock_Config ( ) ; bsp_uart_init ( ) ; return KHYX_SUCCESS;
}
测试任务
# include "app_task.h"
# define SERIAL_MONITOR_THREAD_STACK_SIZE 1024
# define SERIAL_MONITOR_THREAD_PRIORITY 2
# define SERIAL_MONITOR_THREAD_SLICE 1 static TX_THREAD serial_monitor_thread; static void serial_monitor_thread_entry ( ULONG entry_input) { static uint8_t rx_buf[ 128 ] ; while ( 1 ) { const int len = uart_receive ( USART1, rx_buf, 128 ) ; if ( len) { uart_send_block ( USART1, rx_buf, len) ; } tx_thread_sleep ( 10 ) ; }
}
khyx_int tx_serial_monitor_thread_init ( void ) { tx_thread_create ( & serial_monitor_thread, "serial_monitor_thread" , serial_monitor_thread_entry, 0 , tx_malloc ( SERIAL_MONITOR_THREAD_STACK_SIZE) , SERIAL_MONITOR_THREAD_STACK_SIZE, SERIAL_MONITOR_THREAD_PRIORITY, SERIAL_MONITOR_THREAD_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_ACTIVATE) ; return KHYX_SUCCESS;
} KHYX_APP_INIT_EXPORT ( tx_serial_monitor_thread_init) ;
结果
注意,如果出现丢包,说明是数据出现覆盖的情况,需要调整一些lwrb的数据指针的大小