记录一下自己嵌入式Linux C应用所用到的函数
ifreq结构定义在/usr/include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一个接口的名字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。ifreq包含在ifconf结构中。而ifconf结构通常是用来保存所有接口的信息的。
AF_INET IPv4 Internet protocols
SOCK_DGRAM 固定长度的、无连接的、不可靠的报文传递,用于UDP协议。
char *strcpy(char *dest, const char *src) 把 src 所指向的字符串复制到 dest。
需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。
ioctl函数的SIOCGIFFLAGS和SIOCSIFFLAG
S是指socket,IO是指input/output,CG是指get,CS是指set,IFFLAGS是指interface flags,因此SIOCGIFFLAGS是获取接口标志的ioctl操作,SIOCSIFFLAGS是设置接口标志的ioctl操作。
SIOCGIFFLAGS会获取指定网络接口的标志。可以使用该标志来确定接口是否运行,是否支持广播、多播等功能,以及接口是否处于混杂模式。可以使用以下方式进行调用:
ioctl(socket_fd, SIOCGIFFLAGS, &ifr);
其中,socket_fd是已打开的套接字文件描述符,ifr是ifreq结构体类型的变量,该结构体包含了要操作的网络接口的名称。如果该操作成功,ifr结构体中的if_flags成员将包含接口的标志。SIOCSIFFLAGS会设置指定网络接口的标志。可以使用该标志来启用或禁用接口的某些功能,比如混杂模式。可以使用以下方式进行调用:
ioctl(socket_fd, SIOCSIFFLAGS, &ifr);
其中,socket_fd是已打开的套接字文件描述符,ifr是ifreq结构体类型的变量,该结构体包含了要操作的网络接口的名称和要设置的标志。如果该操作成功,接口的标志将被设置为if_flags成员中指定的值。
函数原型2:int inet_aton(const char *cp, struct in_addr *inp);
参数 cp:传入的ip地址;inp 指向转换后存储到struct in_addr结构体的s_addr;
int ip_addr;
struct in_addr inet_ip_addr;
ip_addr = inet_aton("192.168.2.125", &inet_ip_addr);
printf("%d\n",inet_ip_addr.s_addr);
int sprintf(char *str, const char *format, …) 发送格式化输出到 str 所指向的字符串。
参数
str – 这是指向一个字符数组的指针,该数组存储了 C 字符串。
format – 这是字符串,包含了要被写入到字符串 str 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。
例如:
#include
#include
int main()
{
char str[80];
sprintf(str, "Pi 的值 = %f", M_PI);
puts(str);
return(0);
}
输出
Pi 的值 = 3.141593
WEXITSTATUS是一个检验子进程退出的正常还是非正常和返回值的宏
WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。
WEXITSTATUS(status) 当WIFEXITED返回非零值时,可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;
如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说,WIFEXITED返回0,这个值就毫无意义。
一般情况下:
send(),recv()用于TCP,sendto()及recvfrom()用于UDP。但是send(),recv()也可以用于UDP,sendto()及recvfrom()也可以用于TCP sendto可以在参数中指定发送的目标地址 , send需要socket已建立连接, sendto 可用于无连接的 socket 对于send的有连接socket,两者一样,sendto最后两个参数没用。
函数原型:
int sendto ( socket s , const void * msg, int len, unsigned int flags,
const struct sockaddr * to , int tolen ) ;
头文件:#include
sendto() 用来将数据由指定的socket传给对方主机。参数s为已建好连线的socket,如果利用UDP协议则不需经过连线操作。参数msg指向欲连线的数据内容,参数flags 一般设0,详细描述请参考send()。参数to用来指定欲传送的网络地址,结构sockaddr请参考bind()。参数tolen为sockaddr的结构长度。
返回值:
成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno 中
EBADF 参数s非法的socket处理代码。
EFAULT 参数中有一指针指向无法存取的内存空间。
ENOTSOCK 参数 s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断的。
ENOBUFS 系统的缓冲内存不足。
EINVAL 传给系统调用的参数不正确。
socket(AF_INET, SOCK_DGRAM, 0);//IPV4 、UDP
socket (AF_INET, SOCK_STREAM, 0) ;//IPV4、TCP
fcntl()函数可以对一个已经打开的文件描述符执行一系列控制操作,譬如复制一个文件描述符(与 dup、dup2作用相同)、获取/设置文件描述符标志、获取/设置文件状态标志等,类似于一个多功能文件描述符管理工具箱。fcntl()函数原型如下所示(可通过"man 2 fcntl"命令查看):
#include
#include
int fcntl(int fd, int cmd, … /* arg */ )
函数参数和返回值含义如下:
fd:文件描述符。
cmd:操作命令。此参数表示我们将要对 fd 进行什么操作,cmd 参数支持很多操作命令,大家可以打开 man手册查看到这些操作命令的详细介绍,这些命令都是以 F_XXX开头的,譬如 F_DUPFD、 F_GETFD、F_SETFD等,不同的cmd具有不同的作用,cmd操作命令大致可以分为以下5 种功能:
复制文件描述符(cmd=F_DUPFD或cmd=F_DUPFD_CLOEXEC);
获取/设置文件描述符标志(cmd=F_GETFD或 cmd=F_SETFD);
获取/设置文件状态标志(cmd=F_GETFL或 cmd=F_SETFL);
获取/设置异步IO 所有权(cmd=F_GETOWN或 cmd=F_SETOWN);
获取/设置记录锁(cmd=F_GETLK或cmd=F_SETLK);
linux下串口的阻塞和非阻塞操作
有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY;第二个是可以在打开串口之后通过fcntl()函数进行控制。
阻塞的定义:
对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,移植到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数;
对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩下的空间大于等于将要写入的字节数,执行写入操作,返回写入的字节数。
非阻塞的定义:
对于read,no block指当串口输入缓冲区没有数据的时候,read函数立即返回,返回值为0。
对于write,no block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将进行写操作,写入当前串口输出缓冲区剩下空间允许的字节数,然后返回写入的字节数。
为了便于通过程序来获得和修改终端参数,Linux还提供了tcgetattr函数和tcsetattr函数。tcgetattr用于获取终端的相关参数,而tcsetattr函数用于设置终端参数。
详见如下:
LINUX 使用tcgetattr与tcsetattr函数控制终端
mkfifo命令用于创建FIFO(又名命名管道)。
Q1。 什么是命名管道?
要理解这一点,你应该首先意识到基本管道的概念。 你会看到包含竖线(|)的命令。 这个栏被称为管道。 它所做的是创建两个进程之间的通信通道(执行完整命令时)。
例如:
ls | grep .txt
上面提到的命令由两个程序组成: ls和grep 。 这两个程序都由管道(|)分开。 所以这里的管道是什么,它创建了这些程序之间的通信通道 - 当执行上述命令时,ls的输出将作为输入提供给grep。 最后,在终端上显示的输出只包含那些在其中包含’.txt’字符串的条目。
详细可参考这里
Linux mkfifo初学者命令教程(带示例)
主要区别就是用户可否在系统启动或模块装载时为参数指定相应值,在驱动程序里,参数的用法如同全局变量。
Linux内核之module_param()函数使用说明
char *strstr(const char *haystack, const char *needle)
参数
haystack – 要被检索的 C 字符串。
needle – 在 haystack 字符串内要搜索的小字符串。
返回值
该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。
#include
#include
int main()
{
const char haystack[20] = "RUNOOB";
const char needle[10] = "NOOB";
char *ret;
ret = strstr(haystack, needle);
printf("字符串是: %s\n", ret);
return(0);
}
输出
字符串是: NOOB
epoll是linux下实现IO multiplex的利器。一般编程实现方式如下:
使用epoll_create创建一个epoll fd
使用epoll_ctl往epoll fd里添加需要监听的fd,并注册需要监听的事件(由于EPOLLLET边缘触发方式更加高效,所以一般都使用边缘触发方式)
使用epoll_wait等待事件,然后依次处理各个事件,反复循环。
彻底弄懂EPOLLOUT事件
epoll使用详解:epoll_create、epoll_ctl、epoll_wait、close
Unix/Linux编程:epoll详解
getpots是Shell命令行参数解析工具,旨在从Shell Script的命令行当中解析参数。getopts被Shell程序用来分析位置参数,option包含需要被识别的选项字符,如果这里的字符后面跟着一个冒号,表明该字符选项需要一个参数,其参数需要以空格分隔。冒号和问号不能被用作选项字符。getopts每次被调用时,它会将下一个选项字符放置到变量中,OPTARG则可以拿到参数值;如果option前面加冒号,则代表忽略错误;
命令格式:
getopts optstring name [arg...]
命令描述:
optstring列出了对应的Shell Script可以识别的所有参数。比如:如果 Shell Script可以识别-a,-f以及-s参数,则optstring就是afs;如果对应的参数后面还跟随一个值,则在相应的optstring后面加冒号。比如,a:fs 表示a参数后面会有一个值出现,-a value的形式。另外,getopts执行匹配到a的时候,会把value存放在一个叫OPTARG的Shell Variable当中。如果 optstring是以冒号开头的,命令行当中出现了optstring当中没有的参数将不会提示错误信息。
Shell脚本中的while getopts用法小结