开发板为迅为Itop4412
open()
1.库函数头文件
在所有Linux系统中,对文件的操作都只需包含下面四个头文件即可:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
2.打开文件函数open
int open(const char *path,int oflags);
int open(const char *path,int oflags,mode_t mode);
open函数有2到3个参数,其返回值为对应文件的句柄:
1.第一个参数path为绝对路径
2.第二个参数oflags为读写方式等操作
下面三个选项是必须选择其中之一的。
O_RDONLY 文件只读
O_WRONLY 文件只写
O_RDWR 文件可读可写
下面是可以任意选择的。
O_APPEND 每次写操作都写入文件的末尾
O_CREAT 如果指定文件不存在,则创建这个文件
O_EXCL 如果要创建的文件已存在,则返回-1,并且修改errno 的值
O_TRUNC 如果文件存在,并且以只写/读写方式打开,则清空文件全部内容
O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK 如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O设置为非阻塞模式
O_NDELAY 和O_NONBLOCK 功能类似,调用O_NDELAY 和使用的O_NONBLOCK 功能是一样的。
3.参数mode为设置创建文件的权限。其参数设置可参照linux下的权限值,例如chmod 777 filename
ioctl()
控制I/O设备 ,提供了一种获得设备信息和向设备发送控制参数的手段。用于向设备发控制和配置命令 ,有些命令需要控制参数,这些数据是不能用read / write 读写的,称为Out-of-band数据。也就是说,read / write 读写的数据是in-band数据,是I/O操作的主体,而ioctl 命令传送的是控制信息,其中的数据是辅助的数据。
int ioctl(int handle, int cmd,[int *argdx, int argcx]);
第三个参数总是一个指针,但指针的类型依赖于request 参数。我们可以把和网络相关的请求划分为类:
套接口操作
文件操作
接口操作
ARP 高速缓存操作
路由表操作
流系统
下表列出了网络相关ioctl请求的request 参数以及arg 地址必须指向的数据类型:
类别 | Request | 说明 | 数据类型 |
---|---|---|---|
套 | SIOCATMARK | 是否位于带外标记 | int |
接 | SIOCSPGRP | 设置套接口的进程ID 或进程组ID | int |
口 | SIOCGPGRP | 获取套接口的进程ID 或进程组ID | int |
文 | FIONBIO | 设置/ 清除非阻塞I/O 标志 | int |
件 | FIOASYNC | 设置/ 清除信号驱动异步I/O 标志 | int |
FIONREAD | 获取接收缓存区中的字节数 | int | |
FIOSETOWN | 设置文件的进程ID 或进程组ID | int | |
FIOGETOWN | 获取文件的进程ID 或进程组ID | int | |
接 | SIOCGIFCONF | 获取所有接口的清单 | struct ifconf |
口 | SIOCSIFADDR | 设置接口地址 | struct ifreq |
SIOCGIFADDR | 获取接口地址 | struct ifreq | |
SIOCSIFFLAGS | 设置接口标志 | struct ifreq | |
SIOCGIFFLAGS | 获取接口标志 | struct ifreq | |
SIOCSIFDSTADDR | 设置点到点地址 | struct ifreq | |
SIOCGIFDSTADDR | 获取点到点地址 | struct ifreq | |
SIOCGIFBRDADDR | 获取广播地址 | struct ifreq | |
SIOCSIFBRDADDR | 设置广播地址 | struct ifreq | |
SIOCGIFNETMASK | 获取子网掩码 | struct ifreq | |
SIOCSIFNETMASK | 设置子网掩码 | struct ifreq | |
SIOCGIFMETRIC | 获取接口的测度 | struct ifreq | |
SIOCSIFMETRIC | 设置接口的测度 | struct ifreq | |
SIOCGIFMTU | 获取接口MTU | struct ifreq | |
SIOCxxx | (还有很多取决于系统的实现) | ||
ARP | SIOCSARP | 创建/ 修改ARP 表项 | struct arpreq |
SIOCGARP | 获取ARP 表项 | struct arpreq | |
SIOCDARP | 删除ARP 表项 | struct arpreq | |
路 | SIOCADDRT | 增加路径 | struct rtentry |
由 | SIOCDELRT | 删除路径 | struct rtentry |
SIOCRTMSG | 获取路由表 | struct rtentry | |
流 | I_xxx |
write 函数介绍
ssize_t write(int fd,const void *buf,size_t count)
参数 fd,使用 open 函数打开文件之后返回的句柄。
参数buf,需要写入的数据。
参数 count,将参数buf 中最多 count 个字节写入文件中。
返回值为 ssize 类型,出错会返回-1,其它数值表示实际写入的字节数
ssize_t read(int fd,void *buf,size_t len)
参数 fd,使用 open 函数打开文件之后返回的句柄。
参数*buf,读出的数据保存的位置。
参数 len,每次最多读 len 个字节。
返回值为 ssize 类型,出错会返回-1,其它数值表示实际写入的字节数,返回值大于 0 小
于 len 的数值都是正常的。
串口相关
#include <termios.h>
#include <unistd.h>
int tcgetattr(int fd, struct termios *termios_p)
读取当前串口的参数值
参数 1:fd 是 open 返回的文件句柄。
参数 2:*termios_p 是前面介绍的结构体。
使用这个函数前可以先定义一个 termios 结构体,用于存储旧的参数
cfsetispeed(struct termios *termios_p, speed_t speed);
置波特率的函数
参数 1:*termios_p 是前面介绍的结构体。
参数 2:speed 波特率,常用的 B2400,B4800,B9600,B115200,B460800 等等。
执行成功返回 0,失败返回-1
int cfsetospeed(struct termios *termios_p, speed_t speed);
置波特率的函数
参数 1:*termios_p 是前面介绍的结构体。
参数 2:speed 波特率,常用的 B2400,B4800,B9600,B115200,B460800 等等。
执行成功返回 0,失败返回-1
speed_t cfgetispeed(const struct termios *termios_p)
用于读取当前串口输入的波特率。
参数 1:*termios_p 是前面介绍的结构体。
返回值为 speed_t。
函数 speed_t cfgetospeed(const struct termios *termios_p)。这个函数用于读取当前
输出的波特率。
参数 1:*termios_p 是前面介绍的结构体
speed_t cfgetospeed(const struct termios *termios_p)
用于读取当前输出的波特率。
参数 1:*termios_p 是前面介绍的结构体。
返回值为 speed_t 类型,当前波特率。
int tcflush(int fd, int queue_selector);
函数 tcflush 用于清空串口中没有完成的输入或者输出数据。在接收或者发送数据的时候,
串口寄存器会缓存数据,这个函数用于清除这些数据。
参数 1:fd 是 open 返回的文件句柄。
参数 2:控制 tcflush 的操作。
有三个常用数值,TCIFLUSH 清除正收到的数据,且不会读取出来;TCOFLUSH 清除正
写入的数据,且不会发送至终端;TCIOFLUSH 清除所有正在发生的 I/O 数据。
执行成功返回 0,失败返回-1
int tcsetattr(int fd, int optional_actions,const struct termios *termios_p);
参数 1:fd 是 open 返回的文件句柄。
参数 2:optional_actions 是参数生效的时间。
有三个常用的值:TCSANOW:不等数据传输完毕就立即改变属性;TCSADRAIN:等待
所有数据传输结束才改变属性;TCSAFLUSH:清空输入输出缓冲区才改变属性。
参数 3:*termios_p 在旧的参数基础上修改的后的参数。
执行成功返回 0,失败返回-1
一般在初始化最后会使用这个函数
unsigned int sleep(unsigned int seconds);
例如:sleep(1),即延时一秒。
返回无符号的整形数值,如果延时成功则返回 0,如果延时过程中被打断,则返回剩余的
秒数。例如 sleep(5),返回值为 3,那么实际延时就是 5-3=2 秒。
int usleep(useconds_t usec);
Useconds 需要小于 1000000
例如:usleep(10),表示延时 10 微秒。
延时成功则返回 0,失败则返回-1
void mdelay(unsigned long msecs);
例如:mdelay(10),表示延时 10 毫秒。
void udelay(unsigned long usecs);
例如:udelay(5),表示延时 5 微秒。
void ndelay(unsigned long nsecs);
例如:ndelay(3),表示延时 3 纳秒。
int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv, const struct timezone *tz);
高精度时间
参数 tv:用于保存获取的时间。
参数 tz:可以缺省,传入 NULL。
无名管道 pipe
从 UNIX 系统开始,无名管道的通信方式就存在,有点类似硬件中的串口,从最初的设计者定型之后,这种模型就一直延续到今天,说明无名管道当初设计的就极具科学性。
不过无名管道有一定的局限性。
第一:它是属于半双工的通信方式;
第二:只有具有“亲缘关系”的的进程才能使用这种通信方式,也就是父进程和子进程之间
int pipe(int pipefd[2])
参数 pipefd[0]:用于读管道。
参数 pipefd[1]:用于写管道。
返回值:执行成功返回 0,失败返回-1。
有名管道 fifo
无名管道只能用于有亲缘进程之间的通信,有名管道可以实现无亲缘关系的通信。
有名管道 fifo 给文件系统提供一个路径,这个路径和管道关联,只要知道这个管道路径,
就可以进行文件访问,fifo 是指先进先出,也就是先写入的数据,先读出来。
int mkfifo(const char *pathname, mode_t mode);
参数*pathname:路径名,管道名称。
参数 mode:管道的权限。
返回值:成功返回 0,错误返回-1。
消息队列 msg
分析一下 msgrcv 和 msgsnd 函数。
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数 msqid:消息队列的标识码。
参数*msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用
户可定义的通用结构。
参数 msgsz:消息的长短。
参数 msgflg:标志位。
返回值:成功返回 0,错误返回-1。
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
参数 msqid:消息队列的标识码。
参数*msgp:指向消息缓冲区的指针。
参数 msgsz:消息的长短
参数 msgflg:标志位。
返回值:成功返回数据长度,错误返回-1。
信号 signal
unsigned int alarm(unsigned int seconds);
参数 seconds:闹钟的时间,单位为秒。
返回值:成功返回 0 或者返回剩余时间;错误返回-1。
sighandler_t signal(int signum, sighandler_t handler);
参数 signum:等待的信号。
参数 handler:信号到来之后,触发的处理方式。
返回值:成功返回 0,错误返回-1。
信号量 Semaphore
int semget(key_t key, int nsems, int semflg);
参数 key:一个用来允许不相关的进程访问相同信号量的整数值。
参数 nsems:需要的信号量数目。这个值通常总是 1。
参数 semflg:标记集合,与 open 函数的标记十分类似。
返回值:成功返回标识符,用于其它信号函数,错误返回-1。
共享内存 shmdata
int shmget(key_t key, size_t size, int shmflg);
参数 key:建立新的共享内存对象
参数 size:新建立的内存大小
参数 shmflg:标识符
返回值:成功 shmget 返回一个共享内存标识符或创建一个共享内存对象,错误返回-1。
其它函数,如下所示。
void *shmat(int shmid, const void *shmaddr, int shmflg)
参数 shmid:共享内存标识符
参数 shmaddr:指定共享内存出现在进程内存地址的什么位置,直接指定为 NULL 让内核
自己决定一个合适的地址位置
参数 shmflg :SHM_RDONLY,为只读模式,其他为读写模式
返回值:成功返回共享的内存地址,否则返回-1。
int shmdt(const void *shmaddr)
参数 shmaddr:连接的共享内存的起始地址。
返回值:成功返回 0,错误返回-1。
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
参数 shmid:共享内存标识符
参数 cmd IPC_RMID:删除这片共享内存
参数 buf:共享内存管理结构体
返回值:成功返回 0,错误返回-1