这篇我们来做个小实验,实现开发板上运行服务端,可以直接控制led灯,客户端通过socket连接到服务端,通过发送指令来远程控制服务端的led灯。

我们用平台总线的思想来编写驱动程序,这里分为LED平台驱动程序和LED平台设备程序。

先看看LED平台设备程序plat_led_pdev.c的代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>//led4、led5
#define GPF3_CON 0x114001e0
#define GPF3_SIZE 24
//led3
#define GPX1_CON 0x11000C20
#define GPX1_SIZE 24struct resource led_res[] = {//内存资源[0] = {.start = GPF3_CON,.end = GPF3_CON+GPF3_SIZE-1,.flags = IORESOURCE_MEM,},[1] = {.start = GPX1_CON,.end = GPX1_CON+GPX1_SIZE-1,.flags = IORESOURCE_MEM,},//中断资源,通过中断号去描述[2] = {.start = 67,//自定义的中断号.end = 67,.flags = IORESOURCE_IRQ,},
};struct platform_device led_pdev = {.name = "exynos4412_led",.id= -1,.num_resources = ARRAY_SIZE(led_res),.resource = led_res,
};static int __init plat_led_dev_init(void)
{return platform_device_register(&led_pdev);
}static void __exit plat_led_dev_exit(void)
{platform_device_unregister(&led_pdev);
}module_init(plat_led_dev_init);
module_exit(plat_led_dev_exit);
MODULE_LICENSE("GPL");

再看看LED平台驱动程序plat_led_pdrv.c的代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/fs.h>
#include <linux/slab.h>//封装设备信息
struct led_dev{int dev_major;struct class * cls;struct device *dev;struct resource * res;void *reg_base;
};
//定义设备信息
struct led_dev *samsung_led;ssize_t led_pdrv_write(struct file *filp, const char __user *buf, size_t count, loff_t *fops)
{int ret;int value;ret = copy_from_user(&value, buf, count);if(ret){printk("copy_from_user error\n");return -EFAULT;}if(value){//数据寄存器置1writel(readl(samsung_led->reg_base+4) | (0x3<<4), samsung_led->reg_base+4);}else{writel(readl(samsung_led->reg_base+4) & ~(0x3<<4), samsung_led->reg_base+4);}return count;
}int led_pdrv_open(struct inode *inode, struct file *filp)
{printk("---------%s---------\n",__FUNCTION__);return 0;
}int led_pdrv_close(struct inode *inode, struct file *filp)
{printk("---------%s---------\n",__FUNCTION__);return 0;
}const struct file_operations led_fops = {.write = led_pdrv_write,.open = led_pdrv_open,.release = led_pdrv_close,
};//实现初始化
int led_pdrv_probe(struct platform_device *pdev)
{printk("---------%s---------\n",__FUNCTION__);samsung_led = kzalloc(sizeof(struct led_dev),GFP_KERNEL);if(samsung_led == NULL){printk("kzalloc error\n");return -ENOMEM;}samsung_led->dev_major = register_chrdev(0,"led_drv", &led_fops);samsung_led->cls = class_create(THIS_MODULE,"led_cls");samsung_led->dev = device_create(samsung_led->cls, NULL, MKDEV(samsung_led->dev_major, 0), NULL,"led0");//获取资源samsung_led->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);//地址映射samsung_led->reg_base = ioremap(samsung_led->res->start, resource_size(samsung_led->res));//设置寄存器状态,这里时输出状态writel((readl(samsung_led->reg_base) & ~(0xff<<16))| (0x11<<16), samsung_led->reg_base);return 0;
}int led_pdrv_remove(struct platform_device *pdev)
{iounmap(samsung_led->reg_base);device_destroy(samsung_led->cls, MKDEV(samsung_led->dev_major, 0));class_destroy(samsung_led->cls);unregister_chrdev(samsung_led->dev_major, "led_drv");   kfree(samsung_led);return 0;
}
//用于匹配
const struct platform_device_id led_id_table[] = {{"exynos4412_led",0x4444},{"s5pv210_led",0x3333},{"e3c6410_led",0x2222},
};struct platform_driver led_pdrv = {.probe = led_pdrv_probe,.remove = led_pdrv_remove,.driver = {.name = "samsung_led_drv",//可以用于做匹配,也可以不用于做匹配},.id_table = led_id_table,
};static int __init plat_led_drv_init(void)
{return platform_driver_register(&led_pdrv);
}static void __exit plat_led_drv_exit(void)
{platform_driver_unregister(&led_pdrv);
}module_init(plat_led_drv_init);
module_exit(plat_led_drv_exit);
MODULE_LICENSE("GPL");

接着看服务器led_server.c的代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>#define SERVER_PORT 5001int main(int argc,char **argv)
{int fd;int newfd;int len;int flag = 1;//设备节点的pfdint pfd;int value;struct sockaddr_in ipv4addr;struct sockaddr_in clientaddr;char ipaddr[16];fd = socket(AF_INET, SOCK_STREAM, 0);if(fd == -1){printf("server socket error\n");exit(1);}bzero(&ipv4addr,sizeof(ipv4addr));ipv4addr.sin_family = AF_INET;ipv4addr.sin_port = htons(SERVER_PORT); ipv4addr.sin_addr.s_addr = htonl(INADDR_ANY);  if(bind(fd, (struct sockaddr*)&ipv4addr,sizeof(ipv4addr)) < 0){perror("bind");exit(1);}if(listen(fd,5) < 0){perror("listen");exit(1);}printf("server starting...\n");//地址复用if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(int))==-1){perror("setsockopt"); exit(1); }len = sizeof(clientaddr);newfd = accept(fd, (struct sockaddr*)&clientaddr,&len);if(newfd == -1){perror("accept");exit(1);}//打印客户端的ip和portif(!inet_ntop(AF_INET,(void*)&clientaddr.sin_addr.s_addr,ipaddr,sizeof(clientaddr))){perror("inet_ntop");exit(1);}printf("client ip:%s,port:%d is connected\n",ipaddr,ntohs(clientaddr.sin_port));pfd = open("/dev/led0",O_RDWR);if(pfd < 0){perror("open");exit(1);}while(1){//读取客户端通过socket发来的数据read(newfd,&value,4);if(value == 1 || value ==0)//间接控制设备write(pfd,&value,4);else{printf("client quiting...\n");break;}}close(newfd);close(fd);close(pfd);return 0;
}

最后看客户端led_client.c的代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>#define SERVER_PORT 5001
//开发板ip地址
#define SERVER_IP "192.168.1.100"int main(int argc,char **argv)
{int fd;int value;struct sockaddr_in ipv4addr;fd = socket(AF_INET, SOCK_STREAM, 0);if(fd == -1){printf("client socket error\n");exit(1);}bzero(&ipv4addr,sizeof(ipv4addr));ipv4addr.sin_family = AF_INET;ipv4addr.sin_port = htons(SERVER_PORT);if(inet_pton(AF_INET,SERVER_IP,(void *)&ipv4addr.sin_addr.s_addr) != 1){perror("client inet_pton");exit(1);}printf("client starting...\n");if(connect(fd,(struct sockaddr *)&ipv4addr,sizeof(ipv4addr)) < 0){perror("connect");exit(1);}while(1){//1代表点亮led,0代表熄灭led,其他数字代表客户端退出程序printf("please select to led on/off(1:on/0:off/other:quit)");scanf("%d",&value);if(value == 1 || value == 0)write(fd,&value,4);else{write(fd,&value,4);printf("client quiting...\n");break;}//吸收垃圾字符getchar();}close(fd);return 0;
}

加载驱动并在开发板上运行服务器程序:

这里我直接在ubuntu上运行客户端,此时服务器已经连接上客户端,ubuntu上运行客户端如下:

我们在客户端上输入1,代表点亮led,输入0代表熄灭led,其他字符代表客户端退出。这里我们仅操作led4和led5

看看开发板的led情况,输入1时:

输入0时:

通过TCP/IP实现PC(客户端)远程控制开发板(服务器)上LED灯的实验相关推荐

  1. STM32F 103C8T6开发板 点亮LED灯

    每组IO口含下面7个寄存器.7个寄存器可以控制一组GPIO的16个IO口. GPIOx_CRL:端口配置低寄存器 GPIOx_CRH:端口配置高寄存器 GPIOx_IDR:端口输入寄存器 GPIOx_ ...

  2. 野火霸道STM32开发板点亮LED灯课后作业

    #include "stm32f10x.h" int main(void) {     //打开GPIOB端口的时钟     *(unsigned int *)0x40021018 ...

  3. 嵌入式系统开发设计——按键控制LED灯实现

    一.实验目的 掌握STM32固件库的使用方法: 掌握基于库函数模板的开发方法: 掌握基于固件库进行GPIO端口编程的方法: 4.规范编程格式. 二.实验内容 1.查阅STM32-V5开发板按键.LED ...

  4. firefly-rk3288开发板Linux驱动——LED驱动

    本文主要介绍三个部分的内容:一.准备SDK源码 二.如何操作GPIO 三.LED设备驱动的实现.由于firefly官方一直在对源码进行更新,所以本文只以我正在用的版本介绍.此外,官方提供的下载工具版本 ...

  5. 关于PC客户端软件开发的一些思考

    PC客户端(Win/Mac)开发四年的从业者来回答一波,PC客户端广义的应该指的是所有运行在个人电脑上的软件(包括Mac.Linux.Win)这三类主流的操作系统. 它的前景好坏的话,主要的对比对象, ...

  6. tftpd32、虚拟机、PC机、开发板之间的文件传输

    问题:如何在电脑虚拟机上的Linux C程序下载到开发板呢? 首先,虚拟机上安装Linux系统 Linux上的操作有: 编辑好Hello.c源程序 接着编译,因为最后是要在开发板执行程序,所以使用编译 ...

  7. 显示网络没有服务器地址,tcp/ip cp报告了错误738:服务器没有指派地址

    连接ADSL宽带的时候,会遇到各种各样的错误提示,并且,每种错误一般都会有代码的说明. 这次,我遇到的错误提示是: 连接到ADSL时出错 正在检查网络协议连接 tcp/ip cp报告了错误738:服务 ...

  8. 小熊派开发板实践:智慧路灯沙箱实验之真实设备接入

    摘要:尝试用小熊派开发板(E53_SC1.NB35)真实设备代替模拟器完成构建智慧路灯应用实验体验. 智慧路灯是城市智能化道路上重要一环,智慧路灯的实施具有节约公共照明能耗.减少因照明引起的交通事故等 ...

  9. linux流水灯实验,小静视频第二期:第三节ARM开发板linux下流水灯流水灯的实现...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 视频来自:优酷 一.ARM+Linux硬件操作流程及对代码的简单理解 二.NFS挂载网络文件系统 ①准备NFS文件系统目录 1. 准备 NFS 文件系统目 ...

  10. 【正点原子FPGA连载】 第八章 LED灯闪烁实验摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

    1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: h ...

最新文章

  1. 什么是大数据口子_大数据分析师年薪几十万,学什么专业才能从事大数据?
  2. Gulp快速入门教程
  3. 0/0型极限等于多少_求极限时是否可以进行代入?
  4. 简单的JSP登录程序
  5. EasyWechat中代金券的发放总结
  6. each,collect map collect! map!
  7. dt测试软件的学习心得,无线网络优化dt测试心得_适合新手入门,高手进阶_5年项目经验实战经验.docx...
  8. vim+linux+ctags+taglist+winmanager+grep+cscope+supertab+visualmark--ctags
  9. Mybatis源码阅读(二):动态节点解析2.1 —— SqlSource和SqlNode
  10. perl 安装html,centos perl 安装HTML-Parser时报错
  11. 鼠标滚轮控制音量软件
  12. 赵明回应雷军“生死看淡,不服就干”:很像古惑仔
  13. 都有什么行业是“三年不开张,开张吃三年”?或是稳赚不赔的暴利行业?
  14. 图像 - 灰度化、灰度反转、二值化
  15. AngularJS transclude 理解及例子
  16. win10前置耳机插孔没声音_win10头戴式耳机麦克风没声音怎么办
  17. 统信操作系统UOS上手操作与初体验、功能测试
  18. 使用 Java 下载FTP文件
  19. 什么是 JWT Token
  20. 国科大学习资料--人工智能原理与算法-第十三次作业解析(学长整理)

热门文章

  1. HICE第四天笔记 12月8日
  2. linux下latex使用教程,LaTeX使用--XeLaTeX入门基础(二)
  3. 西门子触摸屏脚本程序_西门子触摸屏实例程序
  4. 西北工业大学noj数据结构实验003稀疏矩阵转置
  5. 深度学习非自回归语音合成与自回归语音合成对比
  6. 【C语言】筛选法求素数
  7. 行政区划代码(道路要素)
  8. mac matlab安装libsvm
  9. mysql 笛卡尔积
  10. win10 mysql 卸载不干净,安装提示,The service already exists