湖北汽院嵌入式系统开发实验(共15页).doc

上传人:飞****2 文档编号:13898177 上传时间:2022-05-01 格式:DOC 页数:15 大小:57KB
返回 下载 相关 举报
湖北汽院嵌入式系统开发实验(共15页).doc_第1页
第1页 / 共15页
湖北汽院嵌入式系统开发实验(共15页).doc_第2页
第2页 / 共15页
点击查看更多>>
资源描述

《湖北汽院嵌入式系统开发实验(共15页).doc》由会员分享,可在线阅读,更多相关《湖北汽院嵌入式系统开发实验(共15页).doc(15页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、精选优质文档-倾情为你奉上实验二 嵌入式 Linux 多线程通信实验程( thread)是在共享内存空间中并发的多道执行路径,它们共享一个进程的资源,如文件描述和信号处理。P( S): 将信号量 S 的值减 1,即 S=S-1; 如果 S0,则该进程继续执行;否则该进程状态置为阻塞状态,进程 PCB 排入信号量PCB 队列末尾,放弃 CPU,等待 V 操作的执行。V( S):1 将信号量 S 的值加 1,即 S=S+1;2 如果 S0,释放信号量队列中第一个 PCB 所对应的进程,将进程状态由阻塞态改为就绪态。执行 V 操作的进程继续执行。#include #include #include

2、#include #define MAXSIZE 10int stackMAXSIZE;int size=50;int front=-1,rear=0;sem_t avail,full; /avail 表示可用的空缓冲区,full 表示已存放产品的缓冲区/生产者pthread_t provider,customer,end;void provider_fun(void) /full 表示已存放产品的缓冲区int i=1;sleep(5);while(i=size) /生产50 个产品,需要放入到MAXSIZE 个缓冲区中sem_wait(&avail); /avail 信号量P 操作,表示将可

3、用的空缓冲区个数减1stackrear=i;printf(produce the %d productn,stackrear);rear=(rear+1)%MAXSIZE;i+;sleep(1);sem_post(&full); /full 信号量V 操作,表示将存放产品的缓冲区个数加1pthread_exit(NULL);/消费者void customer_fun(void)int i=1;while(i=size)sem_wait(&full); /fulll 信号量P 操作,表示将存放产品的缓冲区个数减1front=(front+1)%MAXSIZE;printf(t consume t

4、he%d productn,stackfront);stackfront=0;sleep(2);sem_post(&avail); /avail 信号量V 操作,表示将可用的空缓冲区个数加1i+;pthread_exit(NULL);void end_fun(void)char ch; scanf(%c,&ch); pthread_cancel(provider); pthread_cancel(customer);d pthread_exit(NULL); printf(exit!n);void main()pthread_t provider,customer; /定义生产者线程对象和消费

5、者线程对象sem_init(&avail,0,MAXSIZE); /将avail 信号量初始化为MAXSIZEsem_init(&full,0,0); /将full 信号量初始化为0 pthread_create(&provider, NULL, (void *)provider_fun, NULL); / 创建生产者线程 pthread_create(&customer, NULL, (void *)customer_fun, NULL);/ 消费者线程 pthread_create(&end, NULL, (void *)end_fun, NULL);pthread_join(provid

6、er,NULL);pthread_join(customer,NULL);pthread_join(end,NULL);sem_destroy(&avail);sem_destroy(&full);实验三、嵌入式 Linux 网络通信实验3、TCP套接字通信步骤服务器端:(1)调用socket()创建套接字,然后初始化struct sockaddr_in结构体。(2)调用bind函数()为套接字绑定一个IP地址和一个端口号。(3)调用listen()函数使套接字成为监听套接字,侦听指定的端口。(4)调用accept()函数,使服务器处于阻塞状态,等待接受客户端连接请求。一旦建立连接,将产生新的

7、套接字,此时就有两个套接字了,原来的那个套接字还在监听等待指定的端口,而新产生的套接字则准备发送或接受数据。(5)利用send/sendto和recv/recvfrom进行数据传输。当然也可以调用write或read.(6)数据传输完毕,关闭套接字。请补充server.c中代码/fuwuqi#include #include / 包含套接字函数库 #include #include / 包含AF_INET相关结构 #include / 包含AF_INET相关操作的函数 #include #include /bzero()#define MAXDATASIZE 50int main() int

8、server_sockfd; /服务器端socket描述符变量,用以监听客户端的TCP连接int new_sockfd ; /当监听到并接受一个TCP连接时,accept()返回一个新的socket,用这个socket接受数据struct sockaddr_in server_addr; /服务器端sockaddr_in的数据结构struct sockaddr_in client_addr; /用于accept()存放客户端的socket数据结构int client_addr_len; /用于返回struct sockaddr_in的长度,作为accept()中的一个参数char bufMAX

9、DATASIZE; /创建一个buf来存放接受的数据int numbytes; /用以返回接受到的字节数 server_sockfd = socket(AF_INET , SOCK_STREAM , 0); /创建一个TCP套接字,其中协议族为AF_INET,套接字类型为SOCK_STREAM,第三个参数为0server_addr.sin_family = AF_INET; /server_addr.sin_family为AF_INET server_addr.sin_addr.s_addr = inet_addr(10.10.58.130); /server_addr.sin_addr.s_

10、addr为服务器端IP地址,需经inet_addr()转化为网络IP字节序 server_addr.sin_port =htons(1025); /server_addr.sin_port为一个大于1024的端口号,需经htons()转化为网络字节序 bind(server_sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr); /将server_sockfd绑定到server_addr指定的IP和端口上 listen(server_sockfd,5); /为server_sockfd创建包含5个TCP连接的监听队列,将其

11、设置为监听套接字 while (1) client_addr_len = sizeof(struct sockaddr_in); /计算sockaddr_in的长度 new_sockfd= accept(server_sockfd,(struct sockaddr *)&client_addr,&numbytes);/等待接受客户端发来的TCP连接,若连接成功,返回新的socket numbytes = recv(new_sockfd,buf,20, 0); /将客户端发来的数据存放在buf中,返回接受到的字节数 if (numbytes) printf( %s n,buf); /输出buf中

12、数据 sleep(3); send(new_sockfd,I am server,20, 0); /向客户端发送I am server close(new_sockfd);if(8=getchar() break; close(server_sockfd); return 0; 客户端:(1)调用socket()创建套接字,然后初始化struct sockaddr_in结构体,注意服务器端和客户端的struct sockaddr_in结构体应该一致。(2)调用connection()函数与服务器建立连接。(3)利用send/sendto和recv/recvfrom进行数据传输. 当然也可以调用

13、write或read.(4)数据传输完毕,关闭套接字。 请补充client.c中代码/KEHU#include #include / 包含套接字函数库 #include #include / 包含AF_INET相关结构 #include / 包含AF_INET相关操作的函数 #include #include /bzero()#define MAXDATASIZE 50int main(int argc, char *argv) int sockfd,result; /客户端socket描述符变量struct sockaddr_in server_addr;/与服务器端sockaddr_in的

14、数据结构一致char bufMAXDATASIZE; /用以接受服务器端发送过来的数据 int numbytes; /用以返回从服务端发送过来的数据字节数 sockfd = socket(AF_INET,SOCK_STREAM, 0); /创建一个TCP套接字,其中协议族为AF_INET,套接字类型为SOCK_STREAM,第三个参数为0 server_addr.sin_family =AF_INET;/address_addr_addr.sin_family为AF_INET server_addr.sin_addr.s_addr = inet_addr(10.10.58.130); /add

15、ress_addr_addr.sin_addr.s_addr为服务器端IP地址,需经inet_addr()转化为网络IP字节序 server_addr.sin_port =htons(1025);/address_addr_addr.sin_port为一个大于1024的端口号,需经htons()转化为网络字节序 result = connect(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr);/与address_addr_addr指定的服务器建立连接 send(sockfd,this is client,20, 0)

16、; /向服务器端发送this is clientsleep(3); numbytes = recv(sockfd,buf,50, 0); /接受服务器端发送过来的数据,保存在buf中 if (numbytes) printf( %s n,buf); /输出buf里面的数据 close(sockfd); return 0;实验四、嵌入式 Linux 串行端口编程实验6. 什么是全双工和半双工全双工(Full duplex)是说计算机可以同时接受和发送数据也就是它有两个分开的数据传输通道(一个传入,一个传出)。半双工(Half duplex)表示计算机不能同时接受和发送数据,而在某一时刻它只能单一

17、的传送或者接收。这通常意味着,它只有一个数据通道。半双工并不是说RS-232的某些信号不能使用,而是,它通常是使用了有别于RS-232的其他不支持全双工的标准。#include/*标准输入输出定义*/#include/*标准函数库定义*/#include/*Unix 标准函数定义*/#include#include#include/*文件控制定义*/#include/*PPSIX 终端控制定义*/#include/*错误号定义*/#define FALSE -1#define TRUE 0int speed_arr = B38400, B19200, B9600, B4800, B2400,

18、B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, ;int name_arr = 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, ;char buffer1024;int Length;/int nByte = write(fd, buffer ,Length);/读取串口数据代码:dchar buff1024;int Len;void set_speed(int fd, int speed)int

19、 i; int status; struct termios Opt;tcgetattr(fd, &Opt); for ( i= 0; i 0) /printf(nLen %dn,nread); buffnread+1 = 0; printf(%s, buff); memset(buff,0,1024); close(fd); exit (0);实验五、嵌入式 Linux 内核编程实验你可以使用头文件 linux/fs.h中的函数register_chrdev来实现注册一个某个驱动模块对应的主设备号。register_chrdev一般在int device_init()函数中调用,即将内核驱动

20、模块加载入内核意味着要向内核注册自己。如果你向函数register_chrdev传递为0的主设备号,那么返回的就是动态分配的主设备号。此时应该通过命令 “cat /proc/devices”命令输出得到,使用mknod统调用建立设备文件。4Linux 的驱动程序编译方法(1)将其源代码添加到内核源文件中,然后静态编译整个内核,再运行新的内核来测试(2)编译为模块的形式,单独加载运行调试5驱动程序与应用程序的区别(1)应用程序一般有一个 main 函数,从头到尾执行一个任务;驱动程序却不同,它没有 main 函数,通过使用宏module_init(初始化函数名); 将初始化函数加入内核全局初始化

21、函数列表中,在内核初始化时执行驱动的初始化函数,从而完成驱动的初始化和注册,之后驱动便停止等待被应用软件调用。驱动程序中有一个宏moudule_exit(退出处理函数名)注册退出处理函数。它在驱动退出时被调用。(2)应用程序可以和 GLIBC 库连接,因此可以包含标准的头文件,比如, 在驱动程序中是不能使用标准 C 库的,因此不能调用所有的 C 库函数,比如输出打印函数只能使用内核的 printk函数,包含的头文件只能是内核的头文件,比如: 。7字符驱动程序编写流程(1) 包含字符设备驱动程序所必需包含的头文件(2) 定义字符设备文件名、主设备号或由系统动态分配设备号(3) 编写file_op

22、erations结构体中功能接口函数,如以上device_read、device_write, device_open(4) 定义file_operations结构变量,建立用户程序调用函数与驱动功能接口的对应关系。(5) 编写字符设备驱动程序加载函数,完成设备文件注册及必要的初始化(6) 编写字符设备驱动程序卸载函数,完成注销及必要的环境恢复。(7) 编写Makefile文件,使用make来编译Makefile,生成*.ko内核模块文件(8) 使用“insmod *.ko”加载设备驱动程序,并调用dmesg来查看输出结果(9) 使用“cat /proc/devices” 查看获取主设备号(1

23、0) 使用“mknod /dev/设备文件名 主设备号 0”来创建设备文件(11) 编写用户应用程序,调用用户调用接口对驱动功能接口进行测试。(12) 使用“rmmod /dev/设备文件名”卸载驱动模块,并调用dmesg查看#include /模块所需的大量符号和函数定义#include /文件系统相关的函数和头文件#include /cdev结构的头文件#include /copy_to_user()/copy_from_user()定义#define DEVICE_NAME Dev_frame/定义模块名,用”cat /proc/devices”命令查看int DEVICE_MAJOR

24、= 0; /如果为0,则由系统自动分配主设备号#define M_LENGTH 10char core_data0M_LENGTHM_LENGTH;/定义内核数据矩阵char core_data1M_LENGTHM_LENGTH; /*-*/ int device_open(struct inode *inode, struct file *filp) charc=a;inti,j;printk(user open device.n); for(i=0;iM_LENGTH;i+)/初始化数据for(j=0;jM_LENGTH;j+)core_data0ij=c+j;/初始化内核数据矩阵 ret

25、urn 0; /*-*/ ssize_t device_write(struct file *filp,const char *buffer, size_t count, loff_t *f_pos) inti,j;printk(user write data to driver.n);/将用户空间传递过来buffer里面的数据复制到内核空间core_data1数组中 copy_from_user(buffer,core_data1,count); for(i=0;iM_LENGTH;i+)for(j=0;jM_LENGTH;j+)printk(%c,core_data1i);/使用print

26、k打印内核空间core_data1数组中元素printk(n);return count;/*-*/ssize_t device_read(struct file *filp, char *buffer, size_t count, loff_t *f_pos) printk(user read data from driver.n);copy_to_user(buffer,core_data0,count);/将内核空间core_data0数组复制到用户空间buffer return count; /*-*/int device_ioctl(struct inode *inode, stru

27、ct file *file, unsigned int cmd, unsigned long arg) printk(user ioctl runing.n);switch(cmd)case 1:printk(cmd = %d.n,cmd);break; case 2: printk(cmd = %d.n,cmd);break;case 3: printk(cmd = %d.n,cmd);break;case 4: printk(cmd = %d.n,cmd);break;case 5:printk(cmd = %d.n,cmd);break; return cmd; /*-*/ int de

28、vice_release(struct inode *inode, struct file *filp) printk(device releasen); return 0; /*- device_fops 结构定义文件操作函数体之后- -*/ struct file_operations device_fops = .owner=THIS_MODULE, .read=device_read,/将用户接口函数read与驱动功能函数device_read对应起来 .unlocked_ioctl=device_ioctl, /将用户接口函数ioctl与驱动功能函数device_ioctl对应起来

29、.open=device_open, /将用户接口函数open与驱动功能函数device_open对应起来 .write=device_write,/将用户接口函数write与驱动功能函数device_write对应起来 .release=device_release,/将用户接口函数release与驱动功能函数device_release对应起来;/*-*/ int device_init(void) int ret; /*字符驱动程序注册:第1个参数为0(表示由系统自动分配主设备号),第2个参数为设备文件名,第3个参数为struct file_operations结构体变量指针*/ret=

30、register_chrdev(0,Demo_device,&device_fops);if(ret0)printk(register chrdev failure!n);/字符驱动程序注册失败 return ret; elseprintk(register chrdev ok!n);DEVICE_MAJOR=ret;/将系统分配的主设备号保存 return 0; void device_exit(void) /字符驱动程序注销,第1个参数为主设备号,第2个参数为设备文件名, unregister_chrdev(0,Demo_device);printk(unregister chrdev o

31、k!n); module_init(device_init); /指定insmod-加载时执行device_initmodule_exit(device_exit);/rmmod-卸载时执行执行device_exit实验六、嵌入式 Linux Qt GUI 使用实验/firstDialog.cpp/#include #include firstDialog.hfirstDialog:firstDialog(QWidget *parent) : QDialog(parent) lineEdit_1 = new QLineEdit; label_1 = new QLabel(+); lineEdi

32、t_2 = new QLineEdit; label_2= new QLabel(=);lineEdit_3 = new QLineEdit; sumButton = new QPushButton(sum);jianfaButton = new QPushButton(jianfa); /*按钮部件大小和字体设置*/ sumButton-resize(50, 20); sumButton-setFont(QFont(Times, 18, QFont:Bold); connect(sumButton, SIGNAL(clicked(), this, SLOT(clickfun();connect(this, SIGNAL(sumsignal(QString,QString), this, SLOT(sumfun(QString,QString); connect(jianfunButton, SIGNAL(clicked(), this, SLOT(clickfun(); connect(this, SIGNAL(sumsignal(QString,QString), this, SLOT(jianfun(QString,QString)

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com