SDK2.0之从UART驱动代码看Handle的用法

1.

/* Create UART1 handle */
UART_TransferCreateHandle(TEST_UART1_BASE, &g_uart1_handle,
uart_interrupt_callback, NULL);

三个参数:

  • art 基地址 TEST_UART1_BASE
  • Uart handle结构体变量地址
  • allback函数的地址

结构体类型定义如下:

! @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

你可能感兴趣的:(C)