build_embed_linux_system

Linux平台复杂api接口

epoll

epoll是一个用于处理多个文件描述符的I/O事件通知机制,它提供了一种机制,可以同时监听多个文件描述符,并自动将事件通知到应用程序。常用接口包含epoll_create, epoll_ctl, epoll_wait和close接口。

//目录相关的头文件
#include <sys/epoll.h>

//创建epoll事件句柄
// @__size: 创建的epoll事件描述符的数目
// @return: 0表示创建成功,负值返回对应错误码
int epoll_create (int __size);

struct epoll_event {
    uint32_t events;  // 监听的事件类型
    epoll_data_t data;  // 用户数据
};

typedef union epoll_data {
    void *ptr;  // 指向用户数据的指针
    int fd;  // 文件描述符
    uint32_t u32;  // 32位整数
    uint64_t u64;  // 64位整数
} epoll_data_t;

// 操作epoll事件的应用接口
// @__epfd: epoll事件描述符
// @__op: 添加,删除,修改事件
// @__fd: 事件描述符
// @__event: 事件描述符的具体信息
// @return: 0表示操作成功,负值返回对应错误码
int epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event);

//等待epoll事件触发的接口
// @__epfd: epoll事件描述符
// @__events: 事件描述符的具体信息
// @__maxevents: 事件描述符的最大数目
// @__timeout: 等待事件触发的超时时间
// @return: 0表示操作成功,负值返回对应错误码
int epoll_wait (int __epfd, struct epoll_event *__events, int __maxevents, int __timeout);

//关闭epoll事件描述符,释放资源
// @__fd: epoll事件描述符
// @return: 0表示关闭成功,负值返回对应错误码
int close (int __fd);

fifo

fifo是linux系统提供的一种特殊类型的文件,它允许多个进程之间进行通信,而不需要显式地创建和连接文件。fifo相关的接口包含mkfifo, open, read, write, close, unlink接口。

// 相关头文件
#include <sys/types.h>
#include <sys/stat.h>

//创建fifo管道
// @__path: 管道访问路径
// @__mode: 创建管道的权限, 可以是0644,0777
// @return: 0表示创建成功,负值返回对应错误码
int mkfifo (const char *__path, __mode_t __mode);

//打开fifo管道,获取后续使用的描述符
// @pathname: 管道访问路径
// @oflag: 创建管道的权限, 可以是O_RDONLY, O_WRONLY, O_RDWR
// @return: 0表示打开成功,负值返回对应错误码
int open(const char *pathname, int oflag,...);

//从fifo管道中读取数据
// @fd: 管道描述符
// @buf: 数据缓冲区
// @count: 数据缓冲区大小
// @return: 0表示读取成功,负值返回对应错误码
ssize_t read(int fd, void * buf, size_t count);

//向fifo管道写入数据
// @fd: 管道描述符
// @buf: 数据缓冲区
// @count: 数据缓冲区大小
// @return: 0表示写入成功,负值返回对应错误码
ssize_t write (int fd, const void *buf, size_t count);

//关闭fifo管道
// @fd: 管道描述符
// @return: 0表示关闭成功,负值返回对应错误码
int close(int fd);

//移除fifo管道
// @__name: 管道访问路径
// @return: 0表示移除成功,负值返回对应错误码
int unlink (const char *__name);

msg_queue

消息队列是一种进程间通信的机制,它允许进程在不同的进程之间传递消息。消息队列相关的接口包含msgget, msgsnd, msgrcv, msgctl接口。

//相关头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

//创建消息队列
// @key: 消息队列的key
// @msgflg: 消息队列的权限, 可以是IPC_CREAT, IPC_EXCL, IPC_NOWAIT
// @return: 0表示创建成功,负值返回对应错误码
int msgget (key_t key, int msgflg);

//发送消息
// @msgqid: 消息队列的描述符
// @msgp: 消息的具体信息
// @msgsz: 消息的大小
// @msgflg: 消息的权限, 可以是MSG_NOERROR, MSG_COPY, MSG_NOSIGNAL
// @return: 0表示发送成功,负值返回对应错误码
ssize_t msgsnd (int msgqid, const void *msgp, size_t msgsz, int msgflg);

//接收消息
// @msgqid: 消息队列的描述符
// @msgp: 消息的具体信息
// @msgsz: 消息的大小
// @msgtyp: 消息的类型
// @msgflg: 消息的权限, 可以是MSG_NOERROR, MSG_COPY, MSG_NOSIGNAL
// @return: 0表示接收成功,负值返回对应错误码
ssize_t msgrcv (int msgqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

//操作消息队列的应用接口
// @msgqid: 消息队列的描述符
// @cmd: 消息队列的操作类型
// @buf: 消息队列的具体信息
// @return: 0表示操作成功,负值返回对应错误码
int msgctl (int msgqid, int cmd, struct msqid_ds *buf);

pipe

pipe 是一个用于创建管道的系统调用,它允许进程在父子进程或兄弟进程之间进行单向通信,而不需要显式地创建和连接文件。pipe相关的接口包含pipe, read, write, close接口。

// 相关头文件
#include <unistd.h>

//创建pipe通道,
// @fd: 管道描述符,其中fd[0]为数据读管道描述符,fd[1]为数据写管道描述符
// @return: 0表示创建成功,负值返回对应错误码
int pipe (int fd[2]);

//通过管道描述符从管道中读取数据  
// @fd: 管道描述符
// @buf: 数据缓冲区
// @count: 数据缓冲区大小
// @return: 0表示读取成功,负值返回对应错误码
ssize_t read(int fd, void * buf, size_t count);

//通过管道描述符向管道中写入数据
// @fd: 管道描述符
// @buf: 数据缓冲区
// @count: 数据缓冲区大小
// @return: 0表示写入成功,负值返回对应错误码
ssize_t write (int fd, const void *buf, size_t count);

//关闭管道
// @fd: 管道描述符
// @return: 0表示关闭成功,负值返回对应错误码
int close(int fd);

posix_mq

POSIX消息队列(POSIX Message Queues)是一种用于进程间通信的机制,它允许进程在父子进程或兄弟进程之间进行单向通信,而不需要显式地创建和连接文件。POSIX消息队列相关的接口包含mq_unlink, mq_open, mq_close, mq_getattr, mq_send, mq_receive接口。

//相关头文件
#include <mqueue.h>

//创建或打开一个消息队列
// @name: 消息队列的名称
// @oflag: 消息队列的权限, 可以是O_RDONLY, O_WRONLY, O_RDWR
// @mode(可选): 消息队列的权限, 可以是0644,0777
mqd_t mq_open(const char *name, int oflag, ... )

//关闭消息队列
// @mqdes: 消息队列的描述符
// @return: 0表示关闭成功,负值返回对应错误码
int mq_close(mqd_t mqdes);

struct mq_attr {
    long mq_flags;       // 消息队列标志
    long mq_maxmsg;      // 消息队列的最大消息数
    long mq_msgsize;     // 消息队列中每个消息的最大字节数
    long mq_curmsgs;     // 消息队列中当前的消息数
};

//获取消息队列的具体参数信息
// @mqdes: 消息队列的描述符
// @attr: 消息队列的具体信息
// @return: 0表示获取成功,负值返回对应错误码
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);

//设置消息队列的具体参数信息
// @mqdes: 消息队列的描述符
// @attr: 消息队列的具体信息
// @oattr(可选): 消息队列的具体信息
// @return: 0表示设置成功,负值返回对应错误码
int mq_setattr(mqd_t mqdes, const struct mq_attr *attr, struct mq_attr *oattr);

//投递数据给消息队列
// @mqdes: 消息队列的描述符
// @msgp: 消息的具体信息
// @msgsz: 消息的大小
// @msgprio: 消息的优先级
// @return: 0表示投递成功,负值返回对应错误码
int mq_send(mqd_t mqdes, const char *msgp, size_t msgsz, unsigned int msgprio);

//等待消息队列有消息接收
// @mqdes: 消息队列的描述符
// @msgp: 消息的具体信息
// @msgsz: 消息的大小
// @msgprio: 消息的优先级
// @return: 0表示接收成功,负值返回对应错误码
ssize_t mq_receive(mqd_t mqdes, char *msgp, size_t msgsz, unsigned int *msgprio);

//删除已经存在的消息队列
// @name: 消息队列的名称
// @return: 0表示删除成功,负值返回对应错误码
int mq_unlink(const char *name);

semaphore

信号量是一种用于进程间同步和互斥的机制,它允许进程在不同的进程之间进行同步和互斥,而不需要显式地创建和连接文件。信号量相关的接口包含sem_open, sem_close, sem_post, sem_wait, sem_trywait, sem_getvalue, sem_destroy,semget,semctl接口。

//相关头文件
#include <semaphore.h>
#include <sys/sem.h>
#include <sys/ipc.h>

//初始化信号量
// @sem: 信号量的描述符
// @pshared: 信号量的权限, 可以是0, 1
int sem_init(sem_t *sem, int pshared, unsigned int value);

//创建或打开一个信号量
// @name: 信号量的名称
// @oflag: 信号量的权限, 可以是O_CREAT, O_EXCL, O_NONBLOCK
// @mode(可选): 信号量的权限, 可以是0644,0777
// @value: 信号量的初始值
// @return: 0表示创建成功,负值返回对应错误码
sem_t *sem_open(const char *name, int oflag,... )

//关闭信号量
// @sem: 信号量的描述符
// @return: 0表示关闭成功,负值返回对应错误码
int sem_close(sem_t *sem);

//信号量加1
// @sem: 信号量的描述符
// @return: 0表示加1成功,负值返回对应错误码
int sem_post(sem_t *sem);

//信号量减1
// @sem: 信号量的描述符
// @return: 0表示减1成功,负值返回对应错误码
int sem_wait(sem_t *sem);

//尝试信号量减1
// @sem: 信号量的描述符
// @return: 0表示减1成功,负值返回对应错误码
int sem_trywait(sem_t *sem);

//获取信号量的值
// @sem: 信号量的描述符
// @sval: 信号量的值
// @return: 0表示获取成功,负值返回对应错误码
int sem_getvalue(sem_t *sem, int *sval);

//销毁信号量
// @sem: 信号量的描述符
// @return: 0表示销毁成功,负值返回对应错误码
int sem_destroy(sem_t *sem);

// 创建或获取信号量集的系统调用
// @key: 信号量集的键值   
// @nsems: 信号量集的数量
// @semflg: 信号量集的权限, 可以是IPC_CREAT, IPC_EXCL, IPC_NOWAIT
int semget(key_t key, int nsems, int semflg);

// 控制信号量集的系统调用
// @semid: 信号量集的描述符
// @semnum: 信号量集的序号
// @cmd: 信号量集的操作类型
// @arg: 信号量集的操作参数
// @return: 0表示控制成功,负值返回对应错误码
int semctl(int semid, int semnum, int cmd, ...);

shm

共享内存是一种进程间通信的机制,它允许进程在不同的进程之间共享内存,而不需要显式地创建和连接文件。共享内存相关的接口包含shm_open, shm_unlink, shm_get_size, shm_map, shm_unmap接口。

//相关头文件
#include <sys/mman.h>
#include <sys/stat.h>

//创建共享内存
// @name: 共享内存的名称
// @oflag: 共享内存的权限, 可以是O_RDONLY, O_WRONLY, O_RDWR
// @mode(可选): 共享内存的权限, 可以是0644,0777
// @return: 0表示创建成功,负值返回对应错误码
int shm_open(const char *name, int oflag,... )

//删除已经存在的共享内存
// @name: 共享内存的名称
// @return: 0表示删除成功,负值返回对应错误码
int shm_unlink(const char *name);

//获取共享内存的大小
// @shmid: 共享内存的描述符
// @return: 0表示获取成功,负值返回对应错误码
size_t shm_get_size(int shmid);

//映射共享内存到进程的地址空间
// @shmid: 共享内存的描述符
// @addr: 共享内存的地址
// @len: 共享内存的大小
// @prot: 共享内存的权限, 可以是PROT_READ, PROT_WRITE, PROT_EXEC
// @flags: 共享内存的权限, 可以是MAP_SHARED, MAP_PRIVATE
// @return: 0表示映射成功,负值返回对应错误码
void *shm_map(int shmid, void *addr, size_t len, int prot, int flags);

//取消共享内存的映射
// @addr: 共享内存的地址
// @len: 共享内存的大小
// @return: 0表示取消映射成功,负值返回对应错误码
int shm_unmap(void *addr, size_t len);

udp

udp是一种无连接的传输层协议,它允许进程在不同的进程之间进行单向通信,而不需要显式地创建和连接文件。udp相关的接口包含socket, sendto, recvfrom, close接口。

//相关头文件
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// 创建网络套接字
// @domain: 网络套接字类型, 可以是AF_INET, AF_INET6, AF_UNIX等 
// @type: 网络套接字类型, 可以是SOCK_STREAM, SOCK_DGRAM等
// @protocol: 网络套接字类型, 可以是IPPROTO_TCP, IPPROTO_UDP等
// @return: 0表示创建成功,负值返回对应错误码
int socket(int domain, int type, int protocol)  

struct sockaddr_in {
    short            sin_family;   // 地址族(AF_INET)
    unsigned short   sin_port;     // 端口号
    struct in_addr   sin_addr;     // Internet地址
    char             sin_zero[8];  // 填充,使结构体大小与 struct sockaddr 相同
};

// 绑定网络套接字(服务端专用接口)
// @sockfd: 网络套接字描述符
// @my_addr: 网络套接字地址
// @addrlen: 网络套接字地址长度
// @return: 0表示绑定成功,负值返回对应错误码
int bind(int sockfd, const struct sockaddr* my_addr, socklen_t addrlen);  

// 发送数据
// @sockfd: 网络套接字描述符
// @buf: 数据缓冲区
// @len: 数据缓冲区长度
// @flags: 发送数据的标志
// @dest_addr: 目标地址
// @addrlen: 目标地址长度
// @return: 0表示发送成功,负值返回对应错误码
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
              const struct sockaddr *dest_addr, socklen_t addrlen);
 
// 接收数据
// @sockfd: 网络套接字描述符
// @buf: 数据缓冲区
// @len: 数据缓冲区长度
// @flags: 接收数据的标志
// @src_addr: 源地址
// @addrlen: 源地址长度
// @return: 0表示接收成功,负值返回对应错误码
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,  
                struct sockaddr *src_addr, socklen_t *addrlen); 

// 关闭网络套接字
// @fd: 网络套接字描述符
// @return: 0表示关闭成功,负值返回对应错误码
int close(int fd); 

tcp

tcp是一种面向连接的传输层协议,它允许进程在不同的进程之间进行双向通信,而不需要显式地创建和连接文件。tcp相关的接口包含socket, connect, write, read, close接口。

// 相关头文件
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// 创建网络套接字
// @domain: 网络套接字类型, 可以是AF_INET, AF_INET6, AF_UNIX等
// @type: 网络套接字类型, 可以是SOCK_STREAM, SOCK_DGRAM等
// @protocol: 网络套接字类型, 可以是IPPROTO_TCP, IPPROTO_UDP等
// @return: 0表示创建成功,负值返回对应错误码
int socket(int domain, int type, int protocol)

struct sockaddr_in {
    short            sin_family;   // 地址族(AF_INET)
    unsigned short   sin_port;     // 端口号
    struct in_addr   sin_addr;     // Internet地址
    char             sin_zero[8];  // 填充,使结构体大小与 struct sockaddr 相同
};
// 绑定网络套接字(服务端专用接口)
// @sockfd: 网络套接字描述符
// @my_addr: 网络套接字地址
// @addrlen: 网络套接字地址长度
// @return: 0表示绑定成功,负值返回对应错误码
int bind(int sockfd, const struct sockaddr* my_addr, socklen_t addrlen);

// 接收客户端连接的接口(服务端专用接口)
// @sockfd: 网络套接字描述符
// @addr: 客户端地址
// @addrlen: 客户端地址长度
// @return: 0表示接收成功,负值返回对应错误码
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

// 连接到服务器(客户端专用接口)
// @sockfd: 网络套接字描述符
// @serv_addr: 服务器地址
// @addrlen: 服务器地址长度
// @return: 0表示连接成功,负值返回对应错误码
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

// 发送数据
// @sockfd: 网络套接字描述符
// @buf: 数据缓冲区
// @len: 数据缓冲区长度
// @flags: 发送数据的标志
// @return: 0表示发送成功,负值返回对应错误码
ssize_t write(int fd, const void *buf, size_t count);

// 接收数据
// @sockfd: 网络套接字描述符
// @buf: 数据缓冲区
// @len: 数据缓冲区长度
// @flags: 接收数据的标志
// @return: 0表示接收成功,负值返回对应错误码
ssize_t read(int fd, void *buf, size_t count);

// 关闭网络套接字
// @fd: 网络套接字描述符
// @return: 0表示关闭成功,负值返回对应错误码
int close(int fd);

tty_api

tty相关的接口包含open, close, read, write, ioctl, tcgetattr, tcsetattr, tcflush, cfsetispeed, tcdrain等接口。

//相关头文件
#include <termios.h>
#include <fcntl.h>
#include <stdio.h>

//打开tty设备
// @path: tty设备路径
// @oflag: 打开模式, 可以是O_RDONLY, O_WRONLY, O_RDWR
// @return: 0表示打开成功,负值返回对应错误码
int open(const char *path, int oflag);

//关闭tty设备
// @fd: tty设备描述符
// @return: 0表示关闭成功,负值返回对应错误码
int close(int fd);

//从tty设备读取数据
// @fd: tty设备描述符
// @buf: 数据缓冲区
// @count: 数据缓冲区大小
// @return: 0表示读取成功,负值返回对应错误码
ssize_t read(int fd, void *buf, size_t count);

//向tty设备写入数据
// @fd: tty设备描述符
// @buf: 数据缓冲区
// @count: 数据缓冲区大小
// @return: 0表示写入成功,负值返回对应错误码
ssize_t write (int fd, const void *buf, size_t count);

//控制tty设备的接口
// @fd: tty设备描述符
// @cmd: 控制命令
// @arg: 控制参数
// @return: 0表示控制成功,负值返回对应错误码
int ioctl (int fd, int cmd, ...);

struct termios {
    tcflag_t c_iflag;      // 输入模式标志
    tcflag_t c_oflag;      // 输出模式标志
    tcflag_t c_cflag;      // 控制模式标志
    tcflag_t c_lflag;      // 本地模式标志
    cc_t c_cc[NCCS];       // 控制字符
};

//Linux串口接收二进制字符0x11,0x13, 0x0d等特殊字符串丢弃和转换(如下设置避免处理)
term.c_cflag |= CLOCAL | CREAD;
term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
term.c_oflag &= ~OPOST;
term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

//获取tty设备的配置
// @fd: tty设备描述符
// @termios_p: tty设备配置
// @return: 0表示获取成功,负值返回对应错误码
int tcgetattr (int fd, struct termios *termios_p);

//设置tty设备的配置
// @fd: tty设备描述符
// @optional_actions: 可选操作
// @termios_p: tty设备配置
// @return: 0表示设置成功,负值返回对应错误码
int tcsetattr (int fd, int optional_actions, const struct termios *termios_p);

//刷新tty设备的输入输出缓冲区
// @fd: tty设备描述符
// @queue_selector: 缓冲区选择
// @return: 0表示刷新成功,负值返回对应错误码
int tcflush (int fd, int queue_selector);

//设置tty设备的波特率
// @fd: tty设备描述符
// @speed: 波特率
// @return: 0表示设置成功,负值返回对应错误码
int cfsetospeed (struct termios *__p, speed_t __speed);

//等待tty设备的输出缓冲区清空
// @fd: tty设备描述符
// @return: 0表示等待成功,负值返回对应错误码
int tcdrain (int fd);

select_api

select接口主要用于处理多个文件描述符的I/O事件,可用于input输入,网络通信,串口通信等。

//相关头文件
#include <sys/select.h>

// 等待文件描述符的I/O事件
// @nfds: 文件描述符的最大值
// @readfds: 可读文件描述符集合
// @writefds: 可写文件描述符集合
// @exceptfds: 异常文件描述符集合
// @timeout: 超时时间
// @return: 0表示等待成功,负值返回对应错误码
int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

// 初始化文件描述符集合
// @fdset: 文件描述符集合
// @return: 0表示初始化成功,负值返回对应错误码
void FD_ZERO (fd_set *fdset);

// 将文件描述符添加到文件描述符集合
// @fd: 文件描述符
// @fdset: 文件描述符集合
// @return: 0表示添加成功,负值返回对应错误码
void FD_SET (int fd, fd_set *fdset);

// 将文件描述符从文件描述符集合中移除
// @fd: 文件描述符
// @fdset: 文件描述符集合
// @return: 0表示移除成功,负值返回对应错误码
void FD_CLR (int fd, fd_set *fdset);

next_chapter

返回目录

直接开始下一节说明: 系统结语