嵌入式系统开发.docx
《嵌入式系统开发.docx》由会员分享,可在线阅读,更多相关《嵌入式系统开发.docx(19页珍藏版)》请在冰豆网上搜索。
嵌入式系统开发
目录
多进程程序设计2
1.摘要2
2.设计目的2
3.设计要求2
4.设计原理3
5.功能设计3
5.1任务进程的建立3
5.2子进程创建子进程4
5.3管道通信的实现5
5.4进程C的LS-L指令9
6.心得体会10
7.参考文献10
附录:
程序代码11
多进程程序设计
1.摘要
众所周知,目前市场火爆的是嵌入式控制系统,单片机属于嵌入式控制系统的控制器,单片机执行的任务单一,分时复用是其应用宗旨。
而嵌入式系统是多个任务之间的执行,这里的任务就是指进程的启动,它意味着在操作系统进程表中注册过一个新项目,为这个新进程分配独有的数据去、指令区,在指令区中装载属于它的程序代码等等。
创建新进程后,原进程的执行流继续执行,新进程的执行流继续执行,新进程产生了一个新的执行流开始执行,执行流一分为二。
这要与进程更改操作区分,进程更改只不过是让执行流跳转到外部指令区中执行,等到外部指令完成后,执行流再跳回到原指令区。
2.设计目的
本课程设计通过设计多进程程序,掌握创建多进程的方法,掌握通过有名管道实现进程之间的通信,掌握进程中运行现有程序的方法。
3.设计要求
1)创建子进程1及子进程2。
2)子进程1创建子进程A、B,子进程1等待子进程A、B退出后退出。
3)子进程A、B之间通过有名管道FIFO1进行通信,实现生产者-消费者功能。
4)子进程2创建子进程C、D,子进程C运行“ls–l”命令,子进程D通过有名管道FIFO1作为消费者与进程A通信。
4.设计原理
图1
5.功能设计
5.1任务进程的建立
在LINUX系统下,只有一个语句可以启动新进程,那就是fork函数的调用,类似于WINDOWS系统下API函数的调用。
Fork函数一旦被某个进程的执行流执行,会创建一个新的进程,此进程是挂名在原进程之下,被称为父进程,新生成的的进程被称为子进程。
唯一不同的是,fork()语句返回给父进程的值是子进程编号,而返回给子进程的值是0。
样例参考代码如下:
Intmain()
{
Pid_tchild1,child2,child;
child1=fork();
child2=fork();
if(child1==-1)
{
printf(“child1forkerror\n”);
exit
(1);
}
elseif(child1==0)
{
printf(“Iamchild1\n”);
}
}
样例参考代码的验证:
图2
5.2子进程创建子进程
通过上面子进程的创建,下面创建子进程1的子进程A、B的创建,创建原理大致相同,
在实现成功建立子进程1的情况下,再创建子进程A、B的创建。
部分样例参考代码如下:
elseif(child1==0)
{
printf("constructthefirstchild\n");
A=fork();
B=fork();
if(A<0)
{
printf("forktheAerror\n");
exit(0);
}
elseif(A==0)
{
printf("forktheAsucess.\n");
exit(0);
}
exit(0);
if(B<0)
{
printf("forktheBerror\n");
exit(0);
}
elseif(B==0)
{
printf("forktheBsuccess.\n");
exit(0);
}
exit(0);
}
printf("quiltthechild1,it’sover\n");
exit(0);
}
5.3管道通信的实现
首先我们应该明白我们为什么要使用管道通信,了解了为什么才能明白管道通信的作用,以及以后要不要使用管道通信,和怎么使用管道通信的问题。
下面我来阐述下我对此问题的理解。
管道通信主要应用于要在不相关的进程间数据交换,这样我们使用FIFO队列文件管理就可以实现进程间的数据交换,区别于单片机的地方也在于此,单片机暂停当前任务去执行别的任务只有靠中断完成。
FIFO文件通常也称为命名管道(namedpipe)。
命名管道是一种特殊类型的文件,它在文件系统中以文件名的形式存在。
5.3.1创建命名管道
方式1:
mknodfilenamep
方式2:
调用mkfifo函数
int mkfifo(const char *pathname, mode_t mode);
int mknod(const char *pathname, mode_t mode | S_FIFO, (dev_t)0);
创建结果:
图3
5.3.2生产者和消费者通信
所谓的生产者和消费者二者的关系举个例子是这样的,生产者将货物搬上销售架,消费者是买走货物。
这里面有三个物体生产者和消费者还有一个购物平台,对应到计算机的世界里生产者是数据提供的一方,而消费者是使用数据的一方,中间变量购物平台是计算机里的寄存器。
生产者样例参考代码:
#define FIFO_NAME "/tmp/my_fifo1"
#define BUFFER_SIZE PIPE_BUF
#define TEN_MSG (1024 * 1024 * 10)
int main()
{
int pipe_fd;
int res;
int open_mode = O_WRONLY;
int bytes_sent = 0;
char buffer[BUFFER_SIZE + 1]; //缓存
printf("Productor Program beginning...\n"); //初始化程序
if(access(FIFO_NAME, F_OK) == -1)//检查FIFO文件是否存在
{
res = mkfifo(FIFO_NAME, 0777);
if(res !
= 0)
{
fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);
exit(EXIT_FAILURE);
}
}
printf("Process %d opening FIFO O_WRONLY\n", getpid());
pipe_fd = open(FIFO_NAME, open_mode); //检查完毕,打开FIFO文件
printf("Process %d result %d\n", getpid(), pipe_fd);
if(pipe_fd !
= -1)
{
while(bytes_sent < TEN_MSG){
res = write(pipe_fd, buffer, BUFFER_SIZE); //向FIFO写入数据
if(res == -1)
{
fprintf(stderr, "Write error on pipe\n");
exit(EXIT_FAILURE);
}
bytes_sent += res;
}
(void)close(pipe_fd);
}
Else
{
exit(EXIT_FAILURE);
}
printf("Process %d finished\n", getpid());
exit(EXIT_SUCCESS);
}
代码运行:
图4
消费者样例代码程序
#define FIFO_NAME "/tmp/my_fifo"
#define BUFFER_SIZE PIPE_BUF
int main()
{
int pipe_fd;
int res;
int open_mode = O_RDONLY;
char buffer[BUFFER_SIZE + 1];
int bytes = 0;
printf("COnsumer Program beginning...");
memset(buffer,'\0', sizeof(buffer));
printf("Process %d opeining FIFO O_RDONLY\n", getpid());
pipe_fd = open(FIFO_NAME, open_mode);
printf("Process %d result %d\n", getpid(), pipe_fd);
if (pipe_fd !
= -1)
{
Do
{
res = read(pipe_fd, buffer, BUFFER_SIZE);
bytes += res;
}while(res > 0);
close(pipe_fd);
}
else
{
exit(EXIT_FAILURE);
}
printf("Process %d finished, %d bytes read\n", getpid(), bytes);
exit(EXIT_SUCCESS);
}
代码运行结果:
图5
5.4进程C的LS-L指令
部分代码如下:
elseif(C==0)
{
printf("forktheCsucess.\n");
printf("Iamchild1andIexcute’ls-l’\n");
if(execlp(“ls”,”ls”,”-l”,NULL)<0)
{
printf(“child1exclperror\n”);
}
exit(0);
}
运行图示:
图6
6.心得体会
通过本次设计,让我对LINUX系统用了一点了解,同时过程当中遇到过很多问题,通过与室友和同学讨论,最终还是取得了一定的收获,团队合作才能共赢,集思广益才能发挥出团队的创造力。
对于嵌入式系统,我也只是入门级别的,以后如果从事嵌入式系统的设计和开发是远远不够的,还有很长的一段路要走。
正所谓师傅领进门,修行在个人,显然我没达到古人求知的境界,修行不够,自我能力尚待提高,不过我有信心能弄明白所学的,如果我有幸从事嵌入式。
最后在这里我要向我们的老师表达崇高的敬意,在您的帮助下,我有了一定的收获,也意识到了自己身处的位置,继续学习,永远不忘老师的教诲
7.参考文献
1.刘丽.LINUX子进程创建方法[J].计算机科学,2014,10(15):
2-3
2.张勇、杨帅.基于LINUX进程间通信方法[J/OL].
3.刘明.LINUX[J].计算机科学,2011,10(03):
01-06
4.王晶.进程间通信[J].计算机科学,2009,10(02):
01-02
5.王月.LINUX子进程创建[J].中国学术期刊,2008,13(15):
02-06
附录:
程序代码
创建进程代码如下:
#include
#include
#include
intmain(int)
{
pid_tchild1,child2,A,B;
if((child1=fork())<0)
{
printf("forkchild1error\n");
exit(0);
}
elseif(child1==0)
{
printf("constructthefirstchild\n");
A=fork();
B=fork();
if(A<0)
{
printf("forktheAerror\n");
exit(0);
}
elseif(A==0)
{
printf("forktheAsucess.\n");
exit(0);
}
exit(0);
if(B<0)
{
printf("forktheBerror\n");
exit(0);
}
elseif(B==0)
{
printf("forktheBsuccess.\n");
exit(0);
}
exit(0);
}
printf("quiltthechild1,it’sover\n");
exit(0);
if((child2=fork())<0)
{
printf("forkthechild2error\n");
exit(0);
}
elseif(child2==0)
{
printf("constructthesecondchild\n");
C=fork();
D=fork();
if(C<0)
{
printf("forktheCerror\n");
exit(0);
}
elseif(C==0)
{
printf("forktheCsucess.\n");
printf("Iamchild1andIexcute’ls-l’\n");
if(execlp(“ls”,”ls”,”-l”,NULL)<0)
{
Printf(“Child1exclperror\n”);
}
exit(0);
}
exit(0);
if(D<0)
{
printf("forktheDerror\n");
exit(0);
}
elseif(D==0)
{
printf("forktheDsuccess.\n");
exit(0);
}
exit(0);
}
printf("quiltthechild2,it’sover\n");
exit(0);
}
A生产者程序:
#include
#include
#include
#include
#include
#include
#include
#include
#define FIFO_NAME "/tmp/my_fifo"
#define BUFFER_SIZE PIPE_BUF
#define TEN_MSG (1024 * 1024 * 10)
int main()
{
int pipe_fd;
int res;
int open_mode = O_WRONLY;
int bytes_sent = 0;
char buffer[BUFFER_SIZE + 1];
printf("Productor Program beginning...\n");
//检查FIFO文件是否存在
if(access(FIFO_NAME, F_OK) == -1){
res = mkfifo(FIFO_NAME, 0777);
if(res !
= 0){
fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);
exit(EXIT_FAILURE);
}
}
printf("Process %d opening FIFO O_WRONLY\n", getpid());
//打开FIFO文件
pipe_fd = open(FIFO_NAME, open_mode);
printf("Process %d result %d\n", getpid(), pipe_fd);
if(pipe_fd !
= -1){
while(bytes_sent < TEN_MSG){
res = write(pipe_fd, buffer, BUFFER_SIZE); //向FIFO写入数据
if(res == -1){
fprintf(stderr, "Write error on pipe\n");
exit(EXIT_FAILURE);
}
bytes_sent += res;
}
(void)close(pipe_fd);
}
else{
exit(EXIT_FAILURE);
}
printf("Process %d finished\n", getpid());
exit(EXIT_SUCCESS);
}
B消费者代码:
#include
#include
#include
#include
#include
#include
#include
#define FIFO_NAME "/tmp/my_fifo"
#define BUFFER_SIZE PIPE_BUF
int main()
{
int pipe_fd;
int res;
int open_mode = O_RDONLY;
char buffer[BUFFER_SIZE + 1];
int bytes = 0;
printf("COnsumer Program beginning...");
memset(buffer,'\0', sizeof(buffer));
printf("Process %d opeining FIFO O_RDONLY\n", getpid());
pipe_fd = open(FIFO_NAME, open_mode);
printf("Process %d result %d\n", getpid(), pipe_fd);
if (pipe_fd !
= -1)
{
do{
res = read(pipe_fd, buffer, BUFFER_SIZE);
bytes += res;
}while(res > 0);
close(pipe_fd);
}
else
{
exit(EXIT_FAILURE);
}
printf("Process %d finished, %d bytes read\n", getpid(), bytes);
exit(EXIT_SUCCESS);
}