MTK串口驱动开发

MTK串口驱动开发

由于最近在工作中需要使用MTK的MT6261进行移动嵌入式设备的开发,所以将MTK串口驱动开发流程贴出来分享给大家。

1.使用串口工具配置UART管脚,此处配置的是UART2打开源码目录下的\custom\drv\Drv_Tool\DrvGen.exe

DrvGen双击打开
打开硬件定制文件点击Open ,打开\custom\codegen\MBLTEK61D_MOS_3232_11C_BB\codegen.dws的定制文件。点击Edit,配置UART2管脚。
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进行处理流程如下

INDEX结构体指针
此结构体指针指向Uart_handle中的结构体
根据配置方式

INDEX通过UART_Handler来调用底层函数
INDEXINDEXINDEXUART_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;
}

4.欢迎各位补充干货分享

猜你喜欢

转载自blog.csdn.net/LuoLuoSheShuiShe/article/details/83579277
今日推荐