1.
/* Create UART1 handle */
UART_TransferCreateHandle(TEST_UART1_BASE, &g_uart1_handle,
uart_interrupt_callback, NULL);
三个参数:
结构体类型定义如下:
! @brief UART handle structure. */
struct _uart_handle
{
uint8_t *volatile txData; /*!< Address of remaining data to send. */
volatile size_t txDataSize; /*!< Size of the remaining data to send. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
uint8_t *volatile rxData; /*!< Address of remaining data to receive. */
volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
size_t rxDataSizeAll; /*!< Size of the data to receive. */
uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */
size_t rxRingBufferSize; /*!< Size of the ring buffer. */
volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
uart_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< UART callback function parameter.*/
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
2.
void UART_TransferCreateHandle(UART_Type *base,
uart_handle_t *handle,
uart_transfer_callback_t callback,
void *userData)
{
设置handle结构体
a. TX/RX state.
b. Set the callback and user data.
c.
static uart_handle_t *s_uartHandle[UART_HANDLE_ARRAY_SIZE];
s_uartHandle是一个指针数组,里面就是用来放Uart0 Uart1…各自Hander结构体的地址的。
/* Get instance from peripheral base address. */
instance = UART_GetInstance(base);
/* Save the handle in global variables to support the double weak mechanism. */
s_uartHandle[instance] = handle;
d.
s_uartIsr是一个函数指针,这里将UART_TransferHandleIRQ这个函数的地址赋值给这个函数指针。
这样UART0_DriverIRQHandler这样一个系统决定的中断处理函数中我就可以固定的写上
s_uartIsr(UART0, s_uartHandle[0]); 这样一句话;而实际上中断后会调用的函数确实我用户app.c 通过UART_TransferCreateHandle这个函数把地址传过来的。
上面只解决了UART0_DriverIRQHandler 调用的函数如何的传入问题,那如果这个函数需要一些参数怎么办呢?这里就是通过s_uartHandle这个c条目已经谈到的指针数组。
/* Typedef for interrupt handler. */
typedef void (*uart_isr_t)(UART_Type *base, uart_handle_t *handle);
/* UART ISR for transactional APIs. */
static uart_isr_t s_uartIsr;
void UART0_DriverIRQHandler(void)
{
s_uartIsr(UART0, s_uartHandle[0]);
}
s_uartIsr = UART_TransferHandleIRQ;
e.
/* Enable interrupt in NVIC. */
EnableIRQ(s_uartIRQ[instance]);
}
3.
总结:
app.c中调用fsl_uart.c这个通用驱动函数里的UART_TransferCreateHandle函数。
UART_TransferCreateHandle函数将传入的callback and user data 数据放到Handle结构体中,然后就把Handle结构体的地址给了s_uartHandle这个Handle结构体指针数组中,这个数组指针适用于所有的UART。这样通过s_uartHandle这个fsl_uart.c中定义的Handle结构体指针数组就可以的到各个UART的Handle结构体了
s_uartIsr = UART_TransferHandleIRQ;
UART_TransferHandleIRQ这个函数里会通过Handle结构体来调用callback函数。
4.
上面的驱动适用于每个UART有系统默认定义好的一个函数入口。
但是在KM34中,UART0123共用一个函数入口,也就是不存在fsl_uart.c默认定义的UART0_DriverIRQHandler UART1_DriverIRQHandler 。。。这些函数。
也就是虽然我也调用UART_TransferCreateHandle给s_uartHandle指针数组和s_uartIsr函数指针赋值了,但是却会得不到处理。这个时候怎么办呢???
那就自己在app.c里写吧。
因为是共用的,所以定义了g_uart1_interrupt_enabled,g_uart2_interrupt_enabled这些标志来决定执行哪个UART的处理函数。
#if TEST_UART1_UART2_SHARE_IRQn
void UART0_UART1_UART2_UART3_IRQHandler(void)
{
if (g_uart1_interrupt_enabled)
{
UART_TransferHandleIRQ(TEST_UART1_BASE, &g_uart1_handle);
}
if (g_uart2_interrupt_enabled)
{
UART_TransferHandleIRQ(TEST_UART2_BASE, &g_uart2_handle);
}
}
#endif