求教,关于HalUARTPollDMA函数的几个问题
发布网友
发布时间:2022-04-22 08:34
我来回答
共1个回答
热心网友
时间:2022-06-18 17:51
串口数据是由HAL层来负责的,让我们从主循环 (osal_start_system) 的Hal_ProcessPoll函数找下去 ,Hal_ProcessPoll ==> HalUARTPoll ==> HalUARTPollDMA。在这个 HalUARTPollDMA 函数里最后有这样一句话:dmaCfg.uartCB(HAL_UART_DMA-1, evt); 对dmaCfg.uartCB 这个函数进行了调用,dmaCfg结构体类型如下:
typedef struct
{
uint16 rxBuf[HAL_UART_DMA_RX_MAX];
rxIdx_t rxHead;
rxIdx_t rxTail;
uint8 rxTick;
uint8 rxShdw;
uint8 txBuf[2][HAL_UART_DMA_TX_MAX];
txIdx_t txIdx[2];
volatile uint8 txSel;
uint8 txMT;
uint8 txTick; // 1-character time in 32kHz ticks according to baud rate,
// to be used in calculating time lapse since DMA ISR
// to allow delay margin before start firing DMA, so that
// DMA does not overwrite UART DBUF of previous packet
volatile uint8 txShdw; // Sleep Timer LSB shadow.
volatile uint8 txShdwValid; // TX shadow value is valid
uint8 txDMAPending; // UART TX DMA is pending
halUARTCBack_t uartCB;
} uartDMACfg_t;
由上可知,uartCB是一个类型为halUARTCBack_t的函数指针(回调函数),那这个函数指针在那里赋值的呢?请看下面这条线路。void SerialApp_Init( uint8 task_id )里面有如下语句halUARTCfg_t uartConfig;在接下来的给uartConfig这个结构体变量赋值的语句中有如下语句:uartConfig.callBackFunc = SerialApp_CallBack;即将uartConfig里的串口回调函数设置为SerialApp_CallBack,然后再通过HalUARTOpen (SERIAL_APP_PORT, uartConfig);这个函数的调用(不再深入进去,有兴趣的同学可以进一步跟进)将uartConfig这个结构体变量的值转化为uartConfig这个结构体变量的值,注意两个结构体变量所属的类型不同,不能直接赋值,需要转化。
这样就保证了,SerialApp_CallBack函数每次循环中被调用一次,SerialApp_CallBack( ) ==> SerialApp_Send( ),在SerialApp_Send()函数里会调用HalUARTRead()函数,将 DMA 数据读至数据 buffer 并通过 AF_DataRequest ()函数发送出去,注意:发送出去的信息的 CLUSTERID(信息簇ID)号为 SERIALAPP_CLUSTERID1。
static void SerialApp_Send(void)
{
#if SERIAL_APP_LOOPBACK // 本条件编译为FALSE
if (SerialApp_TxLen < SERIAL_APP_TX_MAX)
{
SerialApp_TxLen += HalUARTRead(SERIAL_APP_PORT, SerialApp_TxBuf+SerialApp_TxLen+1,
SERIAL_APP_TX_MAX-SerialApp_TxLen);
}
if (SerialApp_TxLen)
{
(void)SerialApp_TxAddr;
if (HalUARTWrite(SERIAL_APP_PORT, SerialApp_TxBuf+1, SerialApp_TxLen))
{
SerialApp_TxLen = 0;
}
else
{
osal_set_event(SerialApp_TaskID, SERIALAPP_SEND_EVT);
}
}