多年前自己写的Zstack 串口分析的博文
一、串口的初始化
//系统初始化
byte osal_init_system( void )
{
……
osalInitTasks();//系统任务初始化
……
}
//任务初始化
void osalInitTasks( void )
{
……
#if defined( MT_TASK )//如果定义了MT_TASK就初始化MT任务,所以要使用uart必须编译MT_TASK
MT_TaskInit( taskID++ );
#endif
……
}
//MT_TASK初始化
void MT_TaskInit( byte task_id )
{
MT_TaskID = task_id;//分配任务ID
……
SPIMgr_Init();//SPI(UART)管理初始化
} /* MT_TaskInit() */
//SPI(UART)管理初始化
void SPIMgr_Init ()
{
halUARTCfg_t uartConfig;
/* Initialize APP ID */
App_TaskID = 0;//应用层TaskID初始化为0,在后面应用层如果想使用uart需要注册该TaskID
/* UART Configuration */
uartConfig.configured = TRUE;
uartConfig.baudRate = SPI_MGR_DEFAULT_BAUDRATE;
uartConfig.flowControl = SPI_MGR_DEFAULT_OVERFLOW;
uartConfig.flowControlThreshold = SPI_MGR_DEFAULT_THRESHOLD;
uartConfig.rx.maxBufSize = SPI_MGR_DEFAULT_MAX_RX_BUFF;
uartConfig.tx.maxBufSize = SPI_MGR_DEFAULT_MAX_TX_BUFF;
uartConfig.idleTimeout = SPI_MGR_DEFAULT_IDLE_TIMEOUT;
uartConfig.intEnable = TRUE;
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
uartConfig.callBackFunc = SPIMgr_ProcessZToolData; //回调函数
#elif defined (ZAPP_P1) || defined (ZAPP_P2)
uartConfig.callBackFunc = SPIMgr_ProcessZAppData; //回调函数
#else
uartConfig.callBackFunc = NULL;
#endif
/* Start UART */
#if defined (SPI_MGR_DEFAULT_PORT)
HalUARTOpen (SPI_MGR_DEFAULT_PORT, &uartConfig); //打开默认串口
#else
……
}
到这里串口的初始化基本就完成了,还有个打开串口,先不下去了,下面的水是越来越浑,过几天总结底层的…
二、串口的事件处理
//系统主循环
void osal_start_system( void )
{
……
Hal_ProcessPoll(); // 串口与定时器轮询函数
……
}
// 串口与定时器轮询函数
void Hal_ProcessPoll ()
{
HalTimerTick();
#if (defined HAL_UART) && (HAL_UART == TRUE)
HalUARTPoll();
#endif
}
//串口轮询函数
void HalUARTPoll( void )
{
……//这里会根据是DMA还是普通串口有两种不同的轮询方式,这里说普通串口
#if HAL_UART_ISR
#if HAL_UART_DMA
if ( cfg->flag & UART_CFG_DMA )
{
pollDMA( cfg );
}
else
#endif
{
pollISR( cfg );
}
#elif HAL_UART_DMA
pollDMA( cfg );
#endif
……
}
//普通串口轮询函数
static void pollISR( uartCfg_t *cfg )
{
……
轮询完事再次回到void HalUARTPoll函数中,看是否触发事件,如果触发了HAL_UART_RX_FULL、HAL_UART_RX_ABOUT_FULL、HAL_UART_RX_TIMEOUT三个中任意一个就调用回调函数处理。
if ( evt && cfg->rxCB )
{
cfg->rxCB( ((cfg->flag & UART_CFG_U1F)!=0), evt );
}
//串口回调函数
三、与应用层联姻
底层和应用层联姻呢?在TI的协议栈很多都是通过注册Register。按键、串口…
通过注册可以传递任务ID,即TaskID。从而利用偷梁换柱、浑水摸鱼的技术将底层的任务传到应用层
//注册函数
void SPIMgr_RegisterTaskID( byte taskID )
{
App_TaskID = taskID;//任务ID被偷梁换柱了
}
//如果应用层调用了这个函数,则此时App_TaskID就变成了应用层的任务ID了……
现在我们在回去简单看一下串口的回调函数
2010-11-30
tuzhuke
欢迎光临 51uwb.cn (http://51uwb.cn/) | Powered by Discuz! X3.3 |