MTK串列埠驅動開發
MTK串列埠驅動開發
由於最近在工作中需要使用MTK的MT6261進行移動嵌入式裝置的開發,所以將MTK串列埠驅動開發流程貼出來分享給大家。
1.使用串列埠工具配置UART管腳,此處配置的是UART2開啟原始碼目錄下的\custom\drv\Drv_Tool\DrvGen.exe
雙擊開啟
點選Open ,開啟\custom\codegen\MBLTEK61D_MOS_3232_11C_BB\codegen.dws的定製檔案。點選Edit,配置UART2管腳。
完成後點選確定,並點選Save,再點選Gen Code生成硬體定製資訊,生成的檔案在codegen.dws的同級目錄下。生成配置檔案之後,使用 make c,u custom peripheral指令生成新的硬體配置關係。
2.串列埠程式碼
static DCL_HANDLE g_handle = 0;
//0 成功 -1 失敗
kal_int32 m_uart_open(kal_uint32 port)
{
DCL_HANDLE handle = 0;
handle = DclSerPort_Open(port,(module_type)MOD_UART1_HISR+port);
if(handle)
{
g_handle = handle;
return 0;
}
else
{
g_handle = 0;
return -1;
}
}
void m_uart_close(kal_uint32 port)
{
DclSerPort_Close(g_handle);
g_handle = 0;
}
void m_uart_config(kal_uint32 port,UARTDCBStruct * UART_Config)
{
UART_CTRL_DCB_T data;
if(0 == g_handle) { return; } /* config the UART */ data.u4OwenrId = (module_type)MOD_UART1_HISR+port; data.rUARTConfig.u4Baud = UART_Config->baud; data.rUARTConfig.u1DataBits = UART_Config->dataBits; data.rUARTConfig.u1StopBits = UART_Config->stopBits; data.rUARTConfig.u1Parity = UART_Config->parity; data.rUARTConfig.u1FlowControl = UART_Config->flowControl; data.rUARTConfig.ucXonChar = UART_Config->xonChar; data.rUARTConfig.ucXoffChar = UART_Config->xoffChar; data.rUARTConfig.fgDSRCheck = UART_Config->DSRCheck; /* open the UART port, then setup the config information. */ DclSerialPort_Control(g_handle, SIO_CMD_SET_DCB_CONFIG, (DCL_CTRL_DATA_T*)&data);
}
kal_int32 m_uart_sendbytes(kal_uint32 port,kal_uint8* pSendBuff,kal_uint16 len)
{
kal_uint32 writelen = 0;
UART_CTRL_CLR_BUFFER_T data_clr_buf = {0};
UART_CTRL_PURGE_T data_purge_buf = {0};
UART_CTRL_POWERON_T data_power_on = {0};
if(0 == g_handle)
{
return -1;
}
data_power_on.bFlag_Poweron = KAL_TRUE;
DclSerialPort_Control(g_handle, UART_CMD_POWER_ON,(DCL_CTRL_DATA_T*)&data_power_on);
data_purge_buf.u4OwenrId = (module_type)MOD_UART1_HISR+port;
data_purge_buf.dir = DCL_RX_BUF;
DclSerialPort_Control(g_handle, SIO_CMD_PURGE,(DCL_CTRL_DATA_T*)&data_purge_buf);
data_purge_buf.dir = DCL_TX_BUF;
DclSerialPort_Control(g_handle, SIO_CMD_CLR_RX_BUF,(DCL_CTRL_DATA_T*)&data_purge_buf);
data_clr_buf.u4OwenrId = (module_type)MOD_UART1_HISR+port;
DclSerialPort_Control(g_handle, SIO_CMD_CLR_RX_BUF,(DCL_CTRL_DATA_T*)&data_clr_buf);
DclSerialPort_Control(g_handle, SIO_CMD_CLR_RX_BUF,(DCL_CTRL_DATA_T*)&data_clr_buf);
return (s32)DclSerPort_WriteData(g_handle,pSendBuff,len,&writelen,(module_type)MOD_UART1_HISR+port);
}
kal_int32 m_uart_readbytes(kal_uint32 port,kal_uint8* pRecvBuff,kal_uint16 len,kal_uint32* readlen,kal_uint32 timeout)
{
kal_uint32 read_count_len = 0;
kal_uint32 read_sum_len = 0;
DCL_STATUS status;
kal_uint32 timestart = 0;
kal_uint32 timecurrent = 0;
kal_uint32 tickcurrent = 0;
UART_CTRL_POWERON_T data_power_on = {0};
if(0 == g_handle)
{
return -1;
}
data_power_on.bFlag_Poweron = KAL_TRUE;
DclSerialPort_Control(g_handle, UART_CMD_POWER_ON,(DCL_CTRL_DATA_T*)&data_power_on);
kal_get_time(&tickcurrent);
timestart = kal_ticks_to_milli_secs(tickcurrent);
while(1)
{
read_count_len = 0;
status = DclSerPort_ReadData(g_handle,pRecvBuff + read_sum_len,len - read_sum_len,&read_count_len,(module_type)MOD_UART1_HISR+port);
if(STATUS_OK != status)
{
//出現錯誤 直接返回退出
break;
}
if(readlen)
{
read_sum_len += read_count_len;
}
if(read_sum_len >= len)
{
*readlen = read_sum_len;
break;
}
kal_get_time(&tickcurrent);
timecurrent = kal_ticks_to_milli_secs(tickcurrent);
if((timecurrent - timestart)>= timeout)
{
*readlen = read_sum_len;
break;
}
}
return status;
}
3.串列埠程式碼分析
1.串列埠的指令通過結構體指標最終走到Uart_Handler進行處理流程如下
此結構體指標指向Uart_handle中的結構體
根據配置方式
通過UART_Handler來呼叫底層函式
UART_Driver結構體
至此,串列埠流程梳理完畢。
3.remark
第一次呼叫DCL_xx函式的時候程式會異常宕機,最後查到原因是我的MTK原始碼中的
DCL_STATUS DclSerPort_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_BUFF_LEN *returned_len, DCL_OPTIONS options)
{
UART_CTRL_GET_BYTES_T data;
DCL_STATUS status;
data.u4OwenrId =(module_type)options;
data.u2Length = buf_len;
data.puBuffaddr = buff;
data.pustatus = NULL; //此語句缺失導致系統重啟
status = DclSerialPort_Control(handle,SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*)&data);
*returned_len = data.u2RetSize;
return status;
}