• 将上层应用代码与底层硬件操作代码解耦,应用层代码不需要更改,实现代码的复用。
  • 将相关信息封装在结构体中
  • 面向接口编程。把代码分为稳定的和不稳定的。应用层调用稳定的接口。剧烈变化的封装为类,去实现接口。这样就算底层变化也不影响业务。

以串口封装为例

方式一:

封装为UART_Send()等函数

方式二:

面向对象,抽象为结构体

/***************************************封装层***************************************************************/
#include<uart_device.h>
struct UART_Device={
	char *name,
	int(*Init)(struct UART_Device *pDev, int band,int datas,char parity,int stop);
	int(*Send)(struct UART_Device *pDev,uint8_t *datas,int len,int timeout_ms);
	
	// 初始:int (*Recv)(int uart_port_num,uint8_t *data,int timeout_ms);
	int (*Recv)(struct UART_Device *pDev,uint8_t *data,int timeout_ms);
	
	void *priv_data;
};
#include<uart_device.c>
#define UART_SEND_BUF_SIZE (100)
 
struct UART_Data{
	UART_HandleTypeDef *handle,
	SemaphoreHandle_t xTxSem;
	uint8_t rxdata;
};
 
struct UART_Device g_stm32_uart;
 
 
void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
{
	struct UART_Data *data;
	if(husart==&uart1)
	{
		data=g_stm32_uart1.priv_data;
		/*释放信号量*/
		xSemaphoreGiveFromISR(data->xTxSem,NULL);
	
	}
}
 
void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
{
	struct UART_Data *data;
	if(husart==&uart1)
	{
		data=g_stm32_uart1.priv_data;
		/*写队列*/
		xQueueSendFromISR(data->xTxSem,&data->rxdata,NULL);
		/*再次启动串口数据接收*/
		HAL_USART_Receive_IT(data->handle,&data->rxdata,1);
	}
}
 
 
static int stm32_uart_init(struct UART_Device *pDev, int band,int datas,char parity,int stop)
{
	struct UART_Data *data=pDev->priv_data;
 
	data->xTxSem=xSemaphoreCreateBinary();
	data->xRxQueue=xQueueCreate(UART_SEND_BUF_SIZE,1);
	/*启动第一次串口数据接收*/
	HAL_USART_Receive_IT(data->handle,&data->rxdata,1);
	return 0;
}
 
static int stm32_uart_send(struct UART_Device *pDev,uint8_t *datas,int len,int timeout_ms)
{
	struct UART_Data *data=pDev->priv_data;
	/*仅仅是触发中断而已*/
	HAL_UART_Transmit_IT(UART_HandleTypeDef *(pDev->priv_data),datas,len);
	/*等待发送完毕,等待信号量*/
	if(pdTRUE==SemphoreTake(data->xTxSem,timeout_ms))
	{
		return 0;
	}
	else
	{
		return -1;
	}
}
static int stm32_uart_recv(struct UART_Device *pDev,uint8_t *data,int timeout_ms)
{
	struct UART_Data *recv_data=pDev->priv_data;
	 /*等待队列得到数据,问题:谁写队列?中断:写队列*/
	if(pdPASS==xQueueRecevie(recv_data->xRxQueue,recv_data,timeout_ms));
}
 
static struct UART_Data g_stm32_uart1_data={
	&huart1,
}
staic struct UART_Device g_stm32_uart={
	.name="stm32_uart1",
	.init=stm32_uart.init,
	.send=stm32_uart_send;
	&g_stm32_uart1_data;
};
 
 
 
struct UART_Device *g_uart_devs[]={&g_stm32_uart1,&g_stm32_uart2,&g_stm32_uart3};
 
struct UART_Devie *GetUARTEevice(char *name)
{
	for(int i=0;i<sizeof(g_uart_devs)/sizeof(g_uart_devs[0]);i++)
	{
		if(0==strcmp(name,g_uart_devs[i]->name))
		{
			return g_uart——devs[i];
		}
		else
		{
			return NULL;
		}
	}
}
/********************************************************************************************************/
 
struct UART_Device *p=g_stm32_uart;
 
p->Init();
p->Send(p,"100ask\r\n",8,100);
 
 
struct UART_Devie *GetUARTEevice(char *name)