ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

针对嵌入式系统开发板的RGB灯、蜂鸣器或其他设备的设计驱动程序,完成驱动程序的编译和加载。

针对嵌入式系统开发板的RGB灯、蜂鸣器或其他设备的设计驱动程序,完成驱动程序的编译和加载。 实验目的熟练运用相关知识并相结合起来掌握socket通信掌握套接字编程的方法实验原理及内容要求针对嵌入式系统开发板的RGB灯、蜂鸣器或其他设备的设计驱动程序完成驱动程序的编译和加载。设计一个驱动程序的测试程序。要求通过套接字编程实现和上位机的高效通信。测试程序作为远程控制的服务器端。设计一个上位机程序上位机程序作为客户端。上位机通过套接字编程方法发送相关指令给测试程序测试程序调用驱动接口实现对开发板RGB灯、蜂鸣器或其他硬件设备的控制。上位机程序通过C#实现实验步骤及数据记录在led_test.c中编写LED和蜂鸣器代码char *led_on 0\n; char *led_off 1\n; #define PORT 8085 //端口号 #define MAX_LINE 2048 #define LISTENQ 20 int main(int argc , char **argv) { int i, maxi, maxfd, listenfd, connfd, sockfd; int fd; int nready , client[FD_SETSIZE]; ssize_t n, ret; fd_set rset , allset; char buf[MAX_LINE],send[MAX_LINE]; socklen_t clilen; struct sockaddr_in servaddr , cliaddr; /*(1) 得到监听描述符*/ listenfd socket(AF_INET , SOCK_STREAM , 0);//TCP /*(2) 绑定套接字*/ bzero(servaddr , sizeof(servaddr)); servaddr.sin_family AF_INET; servaddr.sin_addr.s_addr htonl(INADDR_ANY); servaddr.sin_port htons(PORT); bind(listenfd , (struct sockaddr *)servaddr , sizeof(servaddr)); /*(3) 监听*/ listen(listenfd , LISTENQ); /*(4) 设置select*/ maxfd listenfd; maxi -1; for(i0 ; iFD_SETSIZE ; i) { client[i] -1; }//for FD_ZERO(allset); FD_SET(listenfd , allset); /*(5) 进入服务器接收请求死循环*/ while(1) { rset allset;//middle variable nready select(maxfd1 , rset , NULL , NULL , NULL); if(FD_ISSET(listenfd , rset)) { /*接收客户端的请求*/ clilen sizeof(cliaddr); printf(\naccpet connection~\n); if((connfd accept(listenfd , (struct sockaddr *)cliaddr , clilen)) 0) { perror(accept error.\n); exit(1); }//if printf(accpet a new client: %s:%d\n, inet_ntoa(cliaddr.sin_addr) , cliaddr.sin_port); /*将客户链接套接字描述符添加到数组*/ for(i0 ; iFD_SETSIZE ; i) { if(client[i] 0) { client[i] connfd; break; }//if }//for if(FD_SETSIZE i) { perror(too many connection.\n); exit(1); }//if FD_SET(connfd , allset); if(connfd maxfd) maxfd connfd; if(i maxi) maxi i; if(--nready 0) continue; }//if for(i0; imaxi ; i) { if((sockfd client[i]) 0) continue; if(FD_ISSET(sockfd , rset)) { /*处理客户请求*/ printf(\nreading the socket~~~ \n) bzero(buf , MAX_LINE); if((n read(sockfd , buf , MAX_LINE)) 0) { close(sockfd); FD_CLR(sockfd , allset); client[i] -1; }//if else{ printf(clint[%d] send message: %s\n, i , buf); switch(buf[0]) { case 1:{write(sockfd , 1 , strlen(1)); fd open(/dev/led_chrdev0, O_RDWR); if(fd0) printf(led_chrdev0 open success\n); else printf(led_chrdev0 open fail\n); write(fd, led_on, strlen(led_on)); close(fd); sleep(1); }break; case 2:{ write(sockfd , 2 , strlen(2)); fd open(/dev/led_chrdev0, O_RDWR); write(fd, led_off, strlen(led_off)); close(fd); }break; case 3:{write(sockfd , 3 , strlen(3)); fd open(/dev/led_chrdev1, O_RDWR); if(fd0) printf(led_chrdev1 open success\n); else printf(led_chrdev1 open fail\n); write(fd, led_on, strlen(led_on)); close(fd); sleep(1); }break; case 4:{ write(sockfd , 4 , strlen(4)); fd open(/dev/led_chrdev1, O_RDWR); write(fd, led_off, strlen(led_off)); close(fd); }break; case 5:{write(sockfd , 5 , strlen(5)); fd open(/dev/led_chrdev2, O_RDWR); if(fd0) printf(led_chrdev2 open success\n); else printf(led_chrdev2 open fail\n); write(fd, led_on, strlen(led_on)); close(fd); sleep(1); }break; case 6:{ write(sockfd , 6 , strlen(6)); fd open(/dev/led_chrdev2, O_RDWR); write(fd, led_off, strlen(led_off)); close(fd); }break; case 7:{write(sockfd , 7 , strlen(7)); fd open(/dev/led_chrdev3, O_RDWR); if(fd0) printf(beep open success\n); else printf(beep open fail\n); write(fd, led_off, strlen(led_off)); close(fd); }break; case 8:{ write(sockfd , 8 , strlen(8)); fd open(/dev/led_chrdev3, O_RDWR); write(fd, led_on, strlen(led_on)); close(fd); }break; } // while(fgets(send , MAX_LINE , stdin) ! NULL) // { // write(sockfd , send , strlen(send)); //bzero(send , MAX_LINE); // send[0]\n; // }//注释的为发送命令 if((ret write(sockfd , buf , n)) ! n) { printf(error writing to the sockfd!\n); break; }//if }//else if(--nready 0) break; }//if }//for }//while }2.编写scoket_server通过scoket通信控制LED灯和蜂鸣器通过套接字编程实现和上位机的高效通信。char *led_on 0\n; char *led_off 1\n; #define PORT 8085 #define MAX_LINE 2048 #define LISTENQ 20 int main(int argc , char **argv) { int i, maxi, maxfd, listenfd, connfd, sockfd; int fd; int nready , client[FD_SETSIZE]; ssize_t n, ret; fd_set rset , allset; char buf[MAX_LINE],send[MAX_LINE]; socklen_t clilen; struct sockaddr_in servaddr , cliaddr; /*(1) 得到监听描述符*/ listenfd socket(AF_INET , SOCK_STREAM , 0);//TCP /*(2) 绑定套接字*/ bzero(servaddr , sizeof(servaddr)); servaddr.sin_family AF_INET; servaddr.sin_addr.s_addr htonl(INADDR_ANY); servaddr.sin_port htons(PORT); bind(listenfd , (struct sockaddr *)servaddr , sizeof(servaddr)); /*(3) 监听*/ listen(listenfd , LISTENQ); /*(4) 设置select*/ maxfd listenfd; maxi -1; for(i0 ; iFD_SETSIZE ; i) { client[i] -1; }//for FD_ZERO(allset); FD_SET(listenfd , allset); /*(5) 进入服务器接收请求死循环*/ while(1) { rset allset;//middle variable nready select(maxfd1 , rset , NULL , NULL , NULL); if(FD_ISSET(listenfd , rset)) { /*接收客户端的请求*/ clilen sizeof(cliaddr); printf(\naccpet connection~\n); if((connfd accept(listenfd , (struct sockaddr *)cliaddr , clilen)) 0) { perror(accept error.\n); exit(1); }//if printf(accpet a new client: %s:%d\n, inet_ntoa(cliaddr.sin_addr) , cliaddr.sin_port); /*将客户链接套接字描述符添加到数组*/ for(i0 ; iFD_SETSIZE ; i) { if(client[i] 0) { client[i] connfd; break; }//if }//for if(FD_SETSIZE i) { perror(too many connection.\n); exit(1); }//if FD_SET(connfd , allset); if(connfd maxfd) maxfd connfd; if(i maxi) maxi i; if(--nready 0) continue; }//if for(i0; imaxi ; i) { if((sockfd client[i]) 0) continue; if(FD_ISSET(sockfd , rset)) { /*处理客户请求*/ printf(\nreading the socket~~~ \n); bzero(buf , MAX_LINE); if((n read(sockfd , buf , MAX_LINE)) 0) { close(sockfd); FD_CLR(sockfd , allset); client[i] -1; }//if else{ printf(clint[%d] send message: %s\n, i , buf); switch(buf[0]) { case 1:{write(sockfd , 1 , strlen(1)); fd open(/dev/led_chrdev0, O_RDWR); if(fd0) printf(led_chrdev0 open success\n); else printf(led_chrdev0 open fail\n); write(fd, led_on, strlen(led_on)); close(fd); sleep(1); }break; case 2:{ write(sockfd , 2 , strlen(2)); fd open(/dev/led_chrdev0, O_RDWR); write(fd, led_off, strlen(led_off)); close(fd); }break; case 3:{write(sockfd , 3 , strlen(3)); fd open(/dev/led_chrdev1, O_RDWR); if(fd0) printf(led_chrdev1 open success\n); else printf(led_chrdev1 open fail\n); write(fd, led_on, strlen(led_on)); close(fd); sleep(1); }break; case 4:{ write(sockfd , 4 , strlen(4)); fd open(/dev/led_chrdev1, O_RDWR); write(fd, led_off, strlen(led_off)); close(fd); }break; case 5:{write(sockfd , 5 , strlen(5)); fd open(/dev/led_chrdev2, O_RDWR); if(fd0) printf(led_chrdev2 open success\n); else printf(led_chrdev2 open fail\n); write(fd, led_on, strlen(led_on)); close(fd); sleep(1); }break; case 6:{ write(sockfd , 6 , strlen(6)); fd open(/dev/led_chrdev2, O_RDWR); write(fd, led_off, strlen(led_off)); close(fd); }break; case 7:{write(sockfd , 7 , strlen(7)); fd open(/dev/led_chrdev3, O_RDWR); if(fd0) printf(beep open success\n); else printf(beep open fail\n); write(fd, led_off, strlen(led_off)); close(fd); }break; case 8:{ write(sockfd , 8 , strlen(8)); fd open(/dev/led_chrdev3, O_RDWR); write(fd, led_on, strlen(led_on)); close(fd); }break; case 9:{ write(sockfd , 9 , strlen(9)); fd open(/dev/led_chrdev4, O_RDWR); if(fd0) printf(relay open success\n); else printf(relay open fail\n); write(fd, led_off, strlen(led_off)); close(fd); sleep(1); }break; case 0:{ write(sockfd , 0 , strlen(0)); fd open(/dev/led_chrdev4, O_RDWR); write(fd, led_on, strlen(led_on)); close(fd); }break; } // while(fgets(send , MAX_LINE , stdin) ! NULL) // { // write(sockfd , send , strlen(send)); //bzero(send , MAX_LINE); // send[0]\n; // }//注释的为发送命令 if((ret write(sockfd , buf , n)) ! n) { printf(error writing to the sockfd!\n); break; }//if }//else if(--nready 0) break; }//if }//for }//while }3.编写led_dev.c文件#define DEV_NAME led_chrdev #define DEV_CNT (4) static dev_t devno; struct class *led_chrdev_class; struct led_chrdev { struct cdev dev; unsigned int __iomem *va_dr; unsigned int __iomem *va_gdir; unsigned int __iomem *va_iomuxc_mux; unsigned int __iomem *va_ccm_ccgrx; unsigned int __iomem *va_iomux_pad; unsigned long pa_dr; unsigned long pa_gdir; unsigned long pa_iomuxc_mux; unsigned long pa_ccm_ccgrx; unsigned long pa_iomux_pad; unsigned int led_pin; unsigned int clock_offset; }; static int led_chrdev_open(struct inode *inode, struct file *filp) { unsigned int val 0; struct led_chrdev *led_cdev (struct led_chrdev *)container_of(inode-i_cdev, struct led_chrdev, dev); filp-private_data container_of(inode-i_cdev, struct led_chrdev, dev); printk(open\n); led_cdev-va_dr ioremap(led_cdev-pa_dr, 4); led_cdev-va_gdir ioremap(led_cdev-pa_gdir, 4); led_cdev-va_iomuxc_mux ioremap(led_cdev-pa_iomuxc_mux, 4); led_cdev-va_ccm_ccgrx ioremap(led_cdev-pa_ccm_ccgrx, 4); led_cdev-va_iomux_pad ioremap(led_cdev-pa_iomux_pad, 4); val ioread32(led_cdev-va_ccm_ccgrx); val ~(3 led_cdev-clock_offset); val | (3 led_cdev-clock_offset); iowrite32(val, led_cdev-va_ccm_ccgrx); iowrite32(5, led_cdev-va_iomuxc_mux); iowrite32(0x1F838, led_cdev-va_iomux_pad); val ioread32(led_cdev-va_gdir); val ~(1 led_cdev-led_pin); val | (1 led_cdev-led_pin); iowrite32(val, led_cdev-va_gdir); val ioread32(led_cdev-va_dr); val | (0x01 led_cdev-led_pin); iowrite32(val, led_cdev-va_dr); return 0; } static int led_chrdev_release(struct inode *inode, struct file *filp) { struct led_chrdev *led_cdev (struct led_chrdev *)container_of(inode-i_cdev, struct led_chrdev, dev); iounmap(led_cdev-va_dr); iounmap(led_cdev-va_gdir); iounmap(led_cdev-va_iomuxc_mux); iounmap(led_cdev-va_ccm_ccgrx); iounmap(led_cdev-va_iomux_pad); return 0; } static ssize_t led_chrdev_write(struct file *filp, const char __user * buf, size_t count, loff_t * ppos) { unsigned long val 0; unsigned long ret 0; int tmp count; kstrtoul_from_user(buf, tmp, 10, ret); struct led_chrdev *led_cdev (struct led_chrdev *)filp-private_data; val ioread32(led_cdev-va_dr); if (ret 0) val ~(0x01 led_cdev-led_pin); else val | (0x01 led_cdev-led_pin); iowrite32(val, led_cdev-va_dr); *ppos tmp; return tmp; } static struct file_operations led_chrdev_fops { .owner THIS_MODULE, .open led_chrdev_open, .release led_chrdev_release, .write led_chrdev_write, }; static struct led_chrdev led_cdev[DEV_CNT] { {.pa_dr 0x0209C000,.pa_gdir 0x0209C004,.pa_iomuxc_mux 0x20E006C,.pa_ccm_ccgrx 0x20C406C,.pa_iomux_pad 0x20E02F8,.led_pin 4,.clock_offset 26}, {.pa_dr 0x20A8000,.pa_gdir 0x20A8004,.pa_iomuxc_mux 0x20E01E0,.pa_ccm_ccgrx 0x20C4074,.pa_iomux_pad 0x20E046C,.led_pin 20,.clock_offset 12}, {.pa_dr 0x20A8000,.pa_gdir 0x20A8004,.pa_iomuxc_mux 0x20E01DC,.pa_ccm_ccgrx 0x20C4074,.pa_iomux_pad 0x20E0468,.led_pin 19,.clock_offset 12}, {.pa_dr 0x0209C000,.pa_gdir 0x0209C004,.pa_iomuxc_mux 0x20E0080,.pa_ccm_ccgrx 0x20C406C,.pa_iomux_pad 0x20E030C,.led_pin 19,.clock_offset 26}, }; static __init int led_chrdev_init(void) { int i 0; dev_t cur_dev; printk(led chrdev init\n); alloc_chrdev_region(devno, 0, DEV_CNT, DEV_NAME); led_chrdev_class class_create(THIS_MODULE, led_chrdev); for (; i DEV_CNT; i) { cdev_init(led_cdev[i].dev, led_chrdev_fops); led_cdev[i].dev.owner THIS_MODULE; cur_dev MKDEV(MAJOR(devno), MINOR(devno) i); cdev_add(led_cdev[i].dev, cur_dev, 1); device_create(led_chrdev_class, NULL, cur_dev, NULL, DEV_NAME %d, i); } return 0; } module_init(led_chrdev_init); static __exit void led_chrdev_exit(void) { int i; dev_t cur_dev; printk(led chrdev exit\n); for (i 0; i DEV_CNT; i) { cur_dev MKDEV(MAJOR(devno), MINOR(devno) i); device_destroy(led_chrdev_class, cur_dev); cdev_del(led_cdev[i].dev); } unregister_chrdev_region(devno, DEV_CNT); class_destroy(led_chrdev_class); } module_exit(led_chrdev_exit); MODULE_AUTHOR(embedfire); MODULE_LICENSE(GPL);4.设计上位机作为客户端上位机通过套接字编程方法发送相关指令给测试程序测试程序调用驱动接口实现对开发板RGB灯、蜂鸣器的控制。C#上位机驱动实验.zip资源-CSDN文库主要代码Socket client; private void button1_Click(object sender, EventArgs e) { ///创建客户端 client new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); ///IP地址 IPAddress ip IPAddress.Parse(textBox1.Text); ///端口号 IPEndPoint endPoint new IPEndPoint(ip, int.Parse(textBox2.Text)); ///建立与服务器的远程连接 client.Connect(endPoint); ///线程问题 Thread thread new Thread(ReciveMsg); thread.IsBackground true; thread.Start(client); } /// summary /// 客户端接收到服务器发送的消息 /// /summary /// param nameo客户端/param void ReciveMsg(object o) { Socket client o as Socket; while (true) { try { ///定义客户端接收到的信息大小 byte[] arrList new byte[1024 * 1024]; ///接收到的信息大小(所占字节数) int length client.Receive(arrList); string msg DateTime.Now Encoding.UTF8.GetString(arrList, 0, length); listBox1.Items.Add(msg); } catch (Exception) { ///关闭客户端 client.Close(); } } } private void button2_Click(object sender, EventArgs e) { listBox1.Items.Clear(); } private void button3_Click(object sender, EventArgs e) { if (textBox3.Text ! ) { SendMsg(textBox3.Text); } } /// summary /// 客户端发送消息给服务端 /// /summary void SendMsg(string str) { byte[] arrMsg Encoding.UTF8.GetBytes(str); client.Send(arrMsg); } private void button4_Click(object sender, EventArgs e) { button4.Text 点亮红灯; byte[] arrMsg Encoding.UTF8.GetBytes(1); client.Send(arrMsg); } private void button5_Click(object sender, EventArgs e) { //if (button5.Text.ToString().Equals(open_beep)) //{ button5.Text 开蜂鸣器; byte[] arrMsg Encoding.UTF8.GetBytes(7); client.Send(arrMsg); } private void button6_Click(object sender, EventArgs e) { button6.Text 关闭红灯; byte[] arrMsg Encoding.UTF8.GetBytes(2); client.Send(arrMsg); } private void button7_Click(object sender, EventArgs e) { button7.Text 点亮绿灯; byte[] arrMsg Encoding.UTF8.GetBytes(3); client.Send(arrMsg); } private void button8_Click(object sender, EventArgs e) { button8.Text 关闭绿灯; byte[] arrMsg Encoding.UTF8.GetBytes(4); client.Send(arrMsg); } private void button9_Click(object sender, EventArgs e) { button9.Text 点亮蓝灯; byte[] arrMsg Encoding.UTF8.GetBytes(5); client.Send(arrMsg); } private void button10_Click(object sender, EventArgs e) { button10.Text 关闭蓝灯; byte[] arrMsg Encoding.UTF8.GetBytes(6); client.Send(arrMsg); } private void button11_Click(object sender, EventArgs e) { button11.Text 关蜂鸣器; byte[] arrMsg Encoding.UTF8.GetBytes(8); client.Send(arrMsg); } } }5. 在保持联网的情况下输入以下命令sudo apt-get install nfs-kernel-serversudo apt-get install nfs-commonsudo apt-get install portmap因为已经下载了所以它会有下图出现1.进入/etc/exports中sudo vim /etc/exports在文件最后加入如下内容/nfsFile *(rw,sync,no_root_squash)2.开发板Ping主机端3.挂载sudo busybox mount -n -o nolock,rsize1024 192.168.7.5:/nfsFile /mnt/4.进入/mnt/12/文件夹下5.运行开发板端输入./serverC#端运行控制面板实验结果结论上位机可以下发指令控制LED灯和蜂鸣器
返回列表