《嵌入式编程基础.ppt》由会员分享,可在线阅读,更多相关《嵌入式编程基础.ppt(38页珍藏版)》请在三一办公上搜索。
1、嵌入式编程基础,linux 平台下的应用程序类型,linux 下的应用程序主要有两种特殊的文件来代表:可执行文件和脚本程序。可执行文件是能够被计算机直接执行的程序,相当于win平台下exe文件。脚本程序则是一组指令,这些指令将由另外一个程序(一般来说是shell 解释器)来执行,相当于dos下的bat文件。,Shell如何解释执行命令,内置命令-直接执行实例程序(用户给出路径的)-按照用户给出的路径执行实例程序(用户未给出路径)-按照PATH变量给出的路径执行,将被搜索的那些子目录都被保存到一个名字为PATH的shell变量里面,和dos下的情况差不多。PATH 是由系统管理员预先配置好了的,
2、通常包括/bin,/usr/bin,/usr/local/bin,你可以使用echo$PATH来显示。如果你是使用的root登陆系统,则还会多包括/sbin,/usr/sbin目录。,应用程序开发流程,编写应用程序(vi编辑器)编译应用程序(编译器)调试运行应用程序(调试器)执行(直接输入程序命令运行),应用程序开发流程(实例),为了快速获得对linux 平台下应用程序设计的体验,我们首先编写经典的hello world程序。下面的代码来自 c programming language第一章#include main()printf(hello,worldn);,利用vi进行编辑,首先,进入l
3、inux的控制台界面。然后,在某个目录建立一个空的c程序文件,比如利用touch/home/zhaohui/linuxApp/hello.c命令 然后cd到当前目录,调用vi编辑器对这个空文件进行编辑,输入这个程序的源代码,(利用vihello.c命令,进入vi编辑器,然后进入vi 的编辑状态,然后输入程序,然后进入vi的命令状态,进行源程序的保存和vi 的退出,回到shell 提示符。)-hello.c-#include int main()printf(Hello,Linux programmingworld!n);return 0;-,gcc 编译和程序运行,然后在当前目录输入编译这个程
4、序的命令,在程序没有错误的情况下,会在当前目录得到一个可执行文件hello。程序的运行如图所示。注意:如果你只是输入 gcc hello.c则生成的可执行文件的名字是a.out,过程总结,这个命令会依次调用gcc的预编译器(cpp),汇编器(生成.s文件),编译器(生成.o文件)和链接器程序(ld)。$gcc-E hello.c-o hello.cpp$gcc-x cpp-output-c hello.cpp-o hello.o$gcc hello.o-o hello提示:命令$gcc O2-S hello.c 可以得到.s汇编文件。如果打算学习某个c语言程序所对应的汇编代码。可以参考csap
5、p的第三章。诸如变量、数组、指针、控制流、子程序等。当然也可以使用objdump d hello来查看汇编代码。诸如objdump等这些命令称为binutils,是非常强大的代码分析工具。比如addr2line,ar,as,gprof,ld,nm,objcopy,objdump,ranlib,size,strings,strip等。具体可以参考其man命令手册。,文件I/O编程,文件描述符文件I/O相关操作函数open函数close函数lseek函数read函数write函数dup和dup2函数fcntl函数,文件描述符,文件描述符定义 linux中每打开一个文件都有一个文件描述符与之对应。该
6、描述符是一个非负整数。取值0对应标准输入,表示键盘1对应标准输出,一般屏幕2表示出错输出,一般到屏幕,文件I/O操作函数-open、close函数,Open函数可以打开一个文件,也可以创建并打开文件;调用方式:#include#include#include Int open(const char pathname,int flag)调用成功返回文件描述符,失败返回-1Close函数-关闭一个文件,释放该文件上的记录锁调用方法:#includeInt close(int filedes)返回成功0,出错-1,文件I/O操作函数-read函数,Read函数用来读取打开文件的数据用法:#inclu
7、de ssize_t read(int filedes,void*buf,size_t nbytes)函数作用:filedes所代表的文件的当前位移量处读取nbytes个字节的数据到buf中,size_t是一个无符号整数,返回类型ssize_t是带符号整数。返回值:成功,返回读到的字节数,到文件结尾返回0;错返回-1,文件I/O读写-程序示例,LED灯-GPIO实验程序,文件I/O操作函数-dup函数,复制一个现存的文件描述符用法:#include int dup(int filedes);int dup2(int filedes,int filedes2);返回值:成功,返回新的文件描述符;
8、失败,返回-1,文件I/O操作函数-lseek,Lseek函数-每个打开的文件都关联着一个文件位移量,用来标识读或写文件时的起始位置,lseek重新设置文件位移量。,进程控制开发,进程控制开发进程的几个基本概念进程相关几个函数进程间通信网络编程,进程控制开发-基本概念,进程几个基本概念进程-程序的执行 进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。父子进程 由于linux是一个多用户的操作系统,在同一时间可能会有多个用户争夺系统资源,进程
9、为了及时,及早的完成任务(得到系统资源)就创建了子进程来争夺系统资源。一旦子进程创建成功,父子进程就会一起从创建处继续执行,两个进程相互争夺系统资源。,进程开发控制-创建进程函数,fork和vfork函数作用:创建进程特点:调用一次,返回两次;子进程中执行返回值为0,父进程中执行,返回值为子进程ID。调用方法:#include#include Pid_t fork(void);Pid_t vfork(void);,#include#include#includeInt main(void)pid_t pid;if(pid=fork()0)err_sys(“fork errorn”);Else
10、if(pid=0)printf(“this is process of child!n”);Else printf(“parent process pid=%d!n”,getpid();,进程控制开发-退出进程函数,Exit函数和_exit函数 作用:停止进程的执行,进程停下剩下的所有操作,清楚进程中包括PCB在内的各种数据结构,并终止本进程的运行。区别:exit()函数退出前会保证缓冲区的数据不丢失 _exit()函数退出前丢失缓冲区数据,进程控制开发-等待函数,Wait和waitpid函数作用:等待子进程终止函数区别:waitpid与wait的作用相同,waitpid多了两个参数调用方法:
11、#include#includepid_t wait(int*statloc)pid_t waitpid(pid_t pid,int*staloc,int option);,进程控制开发-竞态条件,竞态条件 当多个进程都对某个共享数据进行处理,但最后的结果取决于进程的运行顺序,则发生竞态条件(race condition)。,进程控制开发,Exec函数作用:通过系统调用函数,可以根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。,进程间通信,管道 管道pipe用于亲缘进程间的通信,fd0管道读,fd1管道写;半双工通信,可看成一个文件,
12、只是只存在于内存中,可以通过read、write进行读写;每次写的内容都放在管道缓冲区末尾,读取都从缓冲区头部;,有名管道FIFO 管道有名,两个不相关的进程也可以通过它交换数据。原型:#include#includeInt mkfifo(const char*pathname,mode_t mode);,消息队列创建或连接消息队列 int msgget(key_t key int msgflg);Key的产生 key_t ftok(const char*path,int id);发送消息int msgsnd(int msqid,const void*msgp,size_t msgsz,int
13、 msgflg);接收消息int msgrcv(int msqid,void*msqp,size_t msgsz,long msgtyp,int msgflg);销毁消息队列int msgctl(int msqid,int cmd,struct msqid_ds*buf);,信号量 信号量是一种linux资源,它可以让不同的进程间进行相互通信,因此它也被看做成IPC集中的一员。信号量的作用是在两个或多个进程访问公共资源集时保持同步表示方法:struct semaphore 该结构包含一个指向等待队列的指针和一个整数计数器,信号量相关函数创建信号量 int semget(key_t key,in
14、t nsems,int semflg);信号量初始化 int semctl(int semid,int semnum,int cmd,),共享内存Mmap()系统调用使得进程之间通过映射一个普通文件来实现共享内存。普通文件被映射到进程地址空间以后,进程可以像访问普通内存一样对文件进行访问系统V共享内存系统V共享内存和mmap()的实现不太一样。系统V的共享内存只存在于内存中,所以当一个进程终止时,需要继续保留着共享内存,一旦共享内存被删除,就再也找不到了,但是共享内存需要被注销时,也有编程者来实现。,Mmap()函数代码:#include#includeVoid*mmap(void*start
15、,size_t length,int prot,int flags,int fd,off_t offset);,系统V的共享内存创建共享内存 要创建共享内存,可使用shmget函数 调用方法:int shmget(key_t key,int size,int shmflg)使用共享内存 创建内存,有了共享内存ID,然后进行映射,映射到具体的地址空间,利用shmat函数,网络编程,网络编程的基本概念TCP/IP协议常用的网络编程函数,网络编程基本概念,客户端与服务器端客户端:客户程序,这个方法通过不同的途径应用于很多不同类型的应用程序,最常见就是目前在因特网上用的网页。服务器:被动的角色(从)。
16、等待来自客户端的要求。处理要求并传回结果。先启动服务器端,等待客户端的程序运行并建立连接。服务器端的程序负责监听,等待有一个客户端的程序发来请求。,TCP/IP协议,协议模型Socket编程 根据系统实现了TCP/UDP或者IP层的接口,调用该接口进行网络编程,网络编程,网络编程服务器编程:创建套接扣绑定套接口设置套接口为监听模式,进入被动接受连接请求状态接受请求,建立连接读/写数据终止连接客户端程序:创建套接口与远程服务程序连接读/写数据终止连接,创建套接口socket函数绑定套接口调用bind函数建立连接调用connect函数监听调用listen函数接受请求调用accept函数关闭套接字字节转换函数getsockname和getpeername函数,作业,见附录文件 作业-嵌入式编程.doc,