更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。
物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机领域.https://blog.csdn.net/weixin_39804904?type=blog
上午:系统调用 孔令春老师
下午:标准I/O口
教学内容:
1、不需要操作硬件的直接由函数内部完成,并将
结果反馈给应用程序,如:strcpy等字符串操
作函数。(不涉及到内核)
需要操作硬件的,则通过封装系统调用实现相
应的功能,如:printf等。(涉及到内核,因为必须控制硬件)
小知识:32位机有4G寻址空间,用户占据3G(0——3G-1),内核占据1G(3G--4H-1)
2、man有7个文件,第一个是shell,第二个是系统调用,第三个用户函数。
3、系统调用就是直接在内核提供的接口工作,一般程序工作在用户态,系统调用结束后,又要切换回用户态。这种环境的切换会消耗掉许多时间。而I/O口不同虽然是库函数去系统调用,但有内存缓冲器,能一次性操作完成,从而节省时间。
4、装内核,
在linux-2.6.18.i686/kernel/sys.c文件中添加源代码
asmlinkage int sys_girl(int x)
{
printk(“ffsdfsd%d\n”,x);
}
打开linux-2.6.18.i686/include/asm-i386/unistd.h
#define __NR_girl XXX
在ifdef __KERNEL__前加上 define __KERNEL__
打开linux-2.6.18.i686/arch/i386/kernel/syscall_table.S
该表的最后加上:
.long sys_foo
改完之后:
cp /boot/config-2.6.*** .config
打入下面命令:make;make modules_install;make install
make (编译内核和模块)
make modules_install (安装模块)
make install (安装内核文件)
5、卸载内核,/boot/grup/grup.conf里面的14-17行;
在继续删掉initrd-2.6.18-prep.img文件夹
6、printf("fdsa");
printf("fdsafdsa")
程序到这里都不会输出到设备,仅仅在缓冲器中;只有在\n之后才会把缓存器清除,打印到标准输出设备。如果不打\n也可以输入命令fflush(stdout):刷新标准输出设备
7、sscanf
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
char *pf;
pf=strstr("gfdsgfsdname = 200","name = " );
sscanf("gfdsgfsdname = 200", "name = %[0-9]", buf);
结果:buf=200;
~~~~~~~~~`
sscanf("gfdsgfsdname = 200", "name = %[0-9]", buf);
结果:buf=0;
~~~~~~~~~~~~~
sscanf("dsadsname = 200", "%[0-9]", buf);
结果:buf=0;
~~~~~~~~~~~~~~
char *pf;
pf=strstr("gfdsgfsdname = 200","name = " );
sscanf("dsadsname = 200,result = /'girl'/","name = %d",name = \'%[^\']",&a, buf);
结果:a=200,buf=girl
~~~~~~~~~~~~~~~
常见用法。
char buf[512] = {0};
sscanf("123456 ", "%s", buf);
printf("%s\n", buf);
结果为:123456
取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
sscanf("123456 ", "%4s", buf);
printf("%s\n", buf);
结果为:1234
取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
sscanf("123456 abcdedf", "%[^ ]", buf);
printf("%s\n", buf);
结果为:123456
取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
printf("%s\n", buf);
结果为:123456abcdedf
取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
printf("%s\n", buf);
结果为:123456abcdedf
给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,
先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中
sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
printf("%s\n", buf);
结果为:12DDWDFF
给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)
sscanf(“hello, world”, "%*s%s", buf);
printf("%s\n", buf);
结果为:world
%*s表示第一个匹配到的%s被过滤掉,即hello,被过滤了,如果没有空格则结果为 NULL。
分隔字符串2006:03:18
int a, b, c;
sscanf("2006:03:18", "%d:%d:%d", &a, &b, &c);
分隔字符串2006:03:18 - 2006:04:18
char sztime1[16] = "", sztime2[16] = "";
sscanf("2006:03:18 - 2006:04:18", "%s - %s", sztime1, sztime2);
分隔字符串2006:03:18-2006:04:18
char sztime1[16] = "", sztime2[16] = "";
sscanf("2006:03:18-2006:04:18", "%[0-9,:] - %[0-9,:]", sztime1, sztime2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8、int sprintf(char *buf, const char *format, …);
把format的内容写入buf中去,例如:
int ip1=192,ip2=168,ip3=222,ip4=66
sprintf(buf,"%d.%d%.%d.%d",ip1, ip2, ip3, ip4);
printf("%s\n",buf);
结果:192.168.222.66
9.代码编辑器Source Insight 3.5,用中文启动程序覆盖.exe文件,用SourceInsight个人配置的“配置2”替换我的文档中的“设置”里面的内容。
ctr+鼠标左键,跳转到函数或变量
shift+f8高亮
为了能方便在linux下调试,可以把建工程文件通过sanba放在共享目录下。
10、STDOUT_FILENO和STDIN_FILENO 与 stdout和stdin
STDOUT_FILENO和STDIN_FILENO:整型,宏。
stdout和stdin:流指针,指向文件。
11、open的应用,返回的是文件描述符。(int)
在一个open--write(1)--write(2)---close:连续写不会覆盖前面的内容。
在open--write(1)--close--open--write(2)--close:后面的内容会覆盖前面的内容。
在open--write(1)--close--open--write(2)--close:如果想重新打开的时候内容清零,加O_TRUNC
在open--write(1)--close--open--write(2)--close:如果想接着内容写,加O_APPEND
在open--write--read--close:此模式下read不到文件中的内容,因为在write之后,文件指针指向了文件尾,读出的数据是空,要读数据必须是open--write--close--open--read--close。
12、open、close、read和write是属于系统调用,系统的调用的操作文件是以文件符方式。
int open(char *pathname,int flag)或者int open(char *pathname,int flag,mode_t mode)
pathname:文件路径例如: ./test
flag: 打开方式O_RDONLY\O_WRONLY\O_RDWR三种方式,但可以与O_CREAT、O_TRUNC、O_APPEND配合使用。
mode:一般指的是用户权限。
ssize_t read(int fd, void *buf ,size_t count);
fd:文件描述符。
buf:缓冲区首地址。
count:读取的字符个数。
返回值:成功返回实际读取到的字符个数。失败返回-1,可以利用perror去查看原因。
ssize_t write(int fd, const void *buf,size_t count);
fd:文件描述符。
buf:数据首地址。
count:写入数据的字符个数。
返回值:成功返回实际写入数据的字符个数。失败返回-1,可以利用perror去查看原因。
int close(int fd);
参数:
fd是调用open打开文件返回的文件描述符。
返回值:成功返回0。失败返回-1,可以利用perror去查看原因。
13、fopen、fclose、fwrite、fread、rewind、fseek和ftell都是i/o标准库函数,操作文件是以文件指针的方式.FILE *fp;
14、文件流的检测
int feof(FILE *stream);
判断文件是否处于文件结束位置,处于文件结束位置返回1,否则返回0。
int ferror(FILE *stream);
检查文件在用各种输入输出函数进行读写过程中是否出错。返回0表示没有错,否则有错。
void clearerr(FILE *stream);
清除EOF和stream表明的错误。
ulimit -n可以判断文件表述符的大小