- 将上层应用代码与底层硬件操作代码解耦,应用层代码不需要更改,实现代码的复用。
- 将相关信息封装在结构体中
- 面向接口编程。把代码分为稳定的和不稳定的。应用层调用稳定的接口。剧烈变化的封装为类,去实现接口。这样就算底层变化也不影响业务。
以串口封装为例
方式一:
封装为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)