由于最近在工作中需要使用MTK的MT6261进行移动嵌入式设备的开发,所以将MTK串口驱动开发流程贴出来分享给大家。
双击打开
点击Open ,打开\custom\codegen\MBLTEK61D_MOS_3232_11C_BB\codegen.dws的定制文件。点击Edit,配置UART2管脚。
完成后点击确定,并点击Save,再点击Gen Code生成硬件定制信息,生成的文件在codegen.dws的同级目录下。生成配置文件之后,使用 make c,u custom peripheral指令生成新的硬件配置关系。
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;
}
1.串口的指令通过结构体指针最终走到Uart_Handler进行处理流程如下
此结构体指针指向Uart_handle中的结构体
根据配置方式
通过UART_Handler来调用底层函数
UART_Driver结构体
至此,串口流程梳理完毕。
第一次调用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;
}