函数接口封装,说到底是用指向函数的函数指针,通过调用指针的方式起到调用函数的目的。实现函数的隔离调用,以方便多个程序员协调开发应用。举例:
常用的UART串口,首先将串口封装为对象:
typedef struct {
uint8_t port; /* uart port */
uart_config_t config; /* uart config */
void *priv; /* priv data */
} uart_dev_t;
uart_dev_t即为一个UART串口的对象,port为端口号,config为配置信息,config配置如下:
typedef struct {
uint32_t baud_rate;
hal_uart_data_width_t data_width;
hal_uart_parity_t parity;
hal_uart_stop_bits_t stop_bits;
hal_uart_flow_control_t flow_control;
hal_uart_mode_t mode;
} uart_config_t;
config下对应了串口配置的详细信息,包含基本串口参数,这里不一 一描述。
这里举例对data_width的进一步封装为枚举类型:
typedef enum {
DATA_WIDTH_5BIT,
DATA_WIDTH_6BIT,
DATA_WIDTH_7BIT,
DATA_WIDTH_8BIT,
DATA_WIDTH_9BIT
} hal_uart_data_width_t;
其它参数如为常用的设置亦可照葫芦画瓢,枚举的目的在于看名知功能或定义,不会是枯燥的数字难以理解。
至此,UART串口本身的封装完成。
那么,怎么应用呢?如下:
static uart_dev_t at_uart;
首先定义一个串口,例如用在AT指令读写上,名字:at_uart
at_uart_configure(&at_uart);
直接将指向该结构体的指针代入函数,函数如下:
static void at_uart_configure(uart_dev_t *u)
{
u->port = AT_UART_PORT;
u->config.baud_rate = AT_UART_BAUDRATE;
u->config.data_width = AT_UART_DATA_WIDTH;
u->config.parity = AT_UART_PARITY;
u->config.stop_bits = AT_UART_STOP_BITS;
u->config.flow_control = AT_UART_FLOW_CONTROL;
u->config.mode = AT_UART_MODE;
}
这些参数,在宏定义下定义:
/* uart config */
#define AT_UART_PORT 1
#define AT_UART_LINUX_DEV "/dev/ttyUSB0"
#define AT_UART_BAUDRATE 115200
#define AT_UART_DATA_WIDTH DATA_WIDTH_8BIT
#define AT_UART_PARITY NO_PARITY
#define AT_UART_STOP_BITS STOP_BITS_1
#define AT_UART_FLOW_CONTROL FLOW_CONTROL_DISABLED
#define AT_UART_MODE MODE_TX_RX
#define AT_UART_TIMEOUT_MS 1000
调用 at_uart_configure初始化完成后,此处HAL_AT_Uart_Init即封装为需要移植代码者实现的底层对接函数。
static int at_init_uart()
{
at_uart_configure(&at_uart);
if (HAL_AT_Uart_Init(&at_uart) != 0) {
return -1;
}
at._pstuart = &at_uart;
return 0;
}
at._pstuart将指针指向此结构体,以方便其它UART实现函数调用。
用户定义UART参数时,即可直接调用结构体指针参数,例如,Linux环境下的移植代码部分如下:
int32_t HAL_AT_Uart_Init(uart_dev_t *uart)
{
int fd;
struct termios t_opt;
speed_t baud;
if (uart->port != AT_UART_PORT) {
return 0;
}
if ((at_uart_fd = open(AT_UART_LINUX_DEV,
O_RDWR | O_NOCTTY | O_NDELAY)) == -1) {
printf("open at uart failed\r\n");
return -1;
}
switch (uart->config.baud_rate) {
case 115200:
baud = B115200;
break;
case 921600:
baud = B921600;
break;
default:
baud = B115200;
break;
}
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是一个个人学习交流的平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽,造成漏登,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。