新闻详情

新闻详情

首页 / 资讯中心 / 详情

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

发布时间:2026/10/2 1:37:43来源:尧图网络
针对嵌入式系统开发板的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灯和蜂鸣器
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

GlusterFS集群部署脚本合集 2026/10/2 2:24:16

GlusterFS集群部署脚本合集

GlusterFS 集群部署脚本合集(整合版 txt 可直接复制粘贴)适用环境:CentOS 7.x GlusterFS 7.9(阿里云 Storage SIG 源) 集群规模:node1~node4(存储节点) client(客户端&…

阅读更多 →
跑腿订单价格每单都在变,分账系统怎么跟上?动态计价场景下的实时分账架构设计 2026/10/2 2:24:16

跑腿订单价格每单都在变,分账系统怎么跟上?动态计价场景下的实时分账架构设计

一个被忽视的架构难题 做跑腿小程序后端的同学应该都遇到过这个场景:用户下单时,系统根据距离、时段、天气、重量、优惠券等多个因子实时算出一个订单金额。这个金额每单都不同,甚至在用户犹豫的几分钟内都可能因为时段切换(比如从…

阅读更多 →
make_unique / make_shared vs 裸 new:三个理由与反直觉权衡 2026/10/2 2:24:16

make_unique / make_shared vs 裸 new:三个理由与反直觉权衡

std::make_unique(C14 起)和 std::make_shared(C11 起)几乎总是创建智能指针的首选。但它们到底好在哪、有没有代价、什么时候该反着来?这篇给三个硬理由,再补一个反直觉的权衡——没有银弹,得看…

阅读更多 →
悬垂指针与悬垂引用:生命周期错误的排查套路 2026/10/2 2:24:16

悬垂指针与悬垂引用:生命周期错误的排查套路

指针变量里的地址一个字节都没变,代码一行也没改,可昨天还打印出 127.0.0.1 的代码,今天读出来是一串垃圾数字 —— 这是 C 里最难查的一类 bug:悬垂指针(dangling pointer)。它的成因不是「指针写错了」&a…

阅读更多 →
shared_ptr 完全指南:引用计数、控制块与开销 2026/10/2 2:24:15

shared_ptr 完全指南:引用计数、控制块与开销

std::unique_ptr 把「独占所有权」钉死在类型上,但现实里经常需要多个对象同时引用同一份资源:缓存、父子节点、观察者列表……这时 std::shared_ptr(共享所有权指针,shared pointer)登场。它用引用计数(re…

阅读更多 →
早间30分钟清收件箱:AI批处理这3条提示词够用 2026/10/2 2:24:09

早间30分钟清收件箱:AI批处理这3条提示词够用

收件箱最让人消耗精力的, 根本就不是回复的难度有多么高, 而是需要一封接着一封地先把它点开, 然后再一封接着一封地去费力地组织语言。相比之下使用批处理这种方式绝对比所谓的自动代发要靠谱得多: 人工智能主要的作用是负责进行分类和起草草稿, 而你所需要做的仅仅是对事实情…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉