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

2023-05-16

这篇我们来做个小实验,实现开发板上运行服务端,可以直接控制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 24

struct 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){
		//数据寄存器置1
		writel(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 5001

int main(int argc,char **argv)
{
	int fd;
	int newfd;
	int len;
	int flag = 1;
	//设备节点的pfd
	int 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和port
	if(!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时:




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • git push方法

    自己的代码提交到自己的原主分支 克隆下来以后进入文件夹 git add git commit m 34 doing 34 git config global user email 34 xxxx 64 xxxx 34 git config
  • os.system()中路径包含空格导致无法读取文件

    问题 os system 中路径包含空格导致无法读取文件 pcd root 61 34 media mjy My Passport data bkp 1208 02 1208 1 02 34 cmd 61 34 ls 34 43 pcd r
  • Github SSH方式避开私有仓密码输入

    SSH配置流程 xff1a https blog csdn net u013778905 article details 83501204 克隆方式 xff1a git clone git 64 github com xxx xxx git
  • Github常用License总结(MIT/Apache/GPL)

    MIT 比较宽松的许可证是 MIT 许可证 xff0c 只要用户在项目副本中包含了版权声明和许可声明 xff0c 他们就可以拿你的代码做任何想做的事情 xff0c 你也无需承担任何责任 from https www zhihu com qu
  • FAISS C++版本安装教程

    FAISS的Python版本安装起来是很快乐的 xff0c conda就可以轻松安装 但是C 43 43 版本需要花费一点功夫 网上关于C 43 43 的教程除了官方以外少之有少 xff0c 官方教程又过于繁琐 xff0c 特此整理自己的安
  • not a genuine ST device,可能是个“假”芯片

    浅析Keil5报错Connection refused due to device mismatch 的原因 哔哩哔哩 not a genuine ST device 事情就得从这个截图说起 xff0c 看来看去 xff0c 试了试其他的都
  • NCLT数据集

    NCLT数据集的groundtruth文件 xff0c 包含的是velodyne在odom坐标系中的位姿
  • onnxruntime (C++/CUDA) 编译安装及部署

    前几天使用了LibTorch对模型进行C 43 43 转换和测试 xff0c 发现速度比原始Python的Pytorch模型提升了将近2倍 现在尝试以下另一种跨平台的模型转换方式 Onnx xff0c 可实现跨X86 ARM架构的迁移应用
  • 激光雷达闭环检测/地点识别算法OverlapTransformer/SeqOT(2022)

    最新激光雷达闭环检测 地点识别算法 OverlapTransformer已经完整开源 xff0c 相关论文已经被RAL IROS 2022收录 https github com haomo ai OverlapTransformer Ove
  • 我的创作纪念日

    初心未改 xff0c 继续向前
  • 最新激光雷达闭环检测/地点识别算法CVTNet(2023)

    CVTNet以激光点云多类投影生成的二维图为输入 xff0c 利用cross transformer将多类信息交叉融合 xff0c 为激光点云提取强特异性描述子 xff0c 实现SLAM闭环检测或全局定位功能 此外 xff0c CVTNet
  • 判断一条sql是否走了索引

    参考 https zhuanlan zhihu com p 137647823 准备 CREATE TABLE 96 book 96 96 id 96 int 11 NOT NULL AUTO INCREMENT 96 name 96 va
  • C语言网络编程——TCP

    C语言网络编程 TCP 1 1 套接字1 1 1 流套接字 xff08 SOCK STREAM xff09 1 1 2 数据报套接字 xff08 SOCK DGRAM xff09 1 1 3 原始套接字 xff08 SOCK RAW xff
  • ROS入门学习三——launch文件

    launch作用 xff1a 便于一次启动多个节点 xff0c 可启动本地节点和远程节点及修改添加参数服务器参数 lt launch gt lt launch gt 是所有launch文件的根标签 lt node gt node为子集标签
  • ssh连接不上 ping不通 ssh连接虚拟机连不上 远程连接不上可能出现的问题

    如果检查过ssh服务启动 防火墙也关闭了 sshd也安装了 但是怎么ping都ping不通虚拟机网关ip 但是本机可以ping通的话 检查是否虚拟机端 wifi 和 你得xshell 或者finshell 是否在同一个局域网 同一个wifi
  • Shell脚本

    文章目录 第 1 章 shell基础1 1 运维 amp shell 了解 1 1 1 运维基础1 1 2 shell简介 1 2 shell脚本 记忆 1 2 1 创建脚本1 2 2 脚本使用 1 3 变量 应用 1 3 1 什么是变量1
  • Hive基本DDL操作

    1 数据库的DDL操作 xff08 1 xff09 创建数据库 数据库在HDFS上的默认存储路径是 user hive warehouse 数据库名 db hive gt create database db hive 两者等价hive g
  • Windows和Linux双系统时间不对的问题。

    解决Windows与Ubuntu双系统时间同步问题 2016年07月11日 21 05 30 阅读数 xff1a 33115 1 问题发现 本子上装的是Window 10 win7升级 和Ubuntu GNOME 14 04的双系统 一直以
  • stm32移植freertos报错keil

    Using Compiler 39 V5 06 update 7 build 960 39 folder 39 d Keil v5 ARM ARMCC Bin 39 compiling main c USER FreeRTOSConfig
  • ARMv8 (arrch64)pytorch深度学习环境搭建

    Aarch64 安装Anaconda 和 pytorch 一 安装miniconda 参考链接 xff1a 82条消息 Jetson Nano xff08 aarch64 xff09 搭建miniconda 和mmdetection环境 瑾

随机推荐

  • GPU 选择 深度学习 图像识别

    GPU 选择 深度学习 图像识别 1 显卡1 1 Nvidia显卡分类1 1 1 Geforce系列1 1 2 Quadro系列1 1 3 Tesla系列1 2 GPU几个比较重要的参数GPU架构 xff1a CUDA核心数量 xff1a
  • git 合并两个分支

    这里讲解具体的思想 xff0c 具体的提交命令百度上有 目前的场景是将两个非master上的分支进行合并 xff0c 并且不造成冲突 比如现在有两个分支a xff0c b 现在将b合并到a 首先及将b分支上的代码clone下来 xff0c
  • ubuntu中解决ROS--Gazebo添加模型库,解决打开后无模型的问题

    ubuntu中解决Gazebo添加模型库 xff0c 解决打开后无模型的问题 1 在主目录中ctrl 43 h 下载https bitbucket org osrf gazebo models downloads ExBot ROS专区 x
  • 大小端模式

    定义 xff1a 数据存放在地址中 xff0c 一个地址码对应一个字节 内存的低地址存放数据的低位 xff0c 则存储方式为小端存储 xff1b 内存的低地址存放数据的高位 xff0c 则为大端存储 判断大小端的方法有两种 xff1a 数据
  • Matlab二维插值

    Matlab二维插值 interp2函数 xff08 网格节点 xff09 Y 61 interp2 x y z xi yi method method nearest 最邻近插值linear xff08 默认 xff09 双线性插值cub
  • 4、ROS话题通信实战,代码逐行解析

    在前面小节已经实现了ROS工作空间的创建 xff0c 这里开始功能包的开发实战了 首先创建功能包 xff1a cd ROS src 创建功能包topic xff0c 指定依赖roscpp和std msgs包 catkin create pk
  • 大数据学习(三十)JOIN过程中的mapreduce阶段

    前言 xff1a join分为mapjoin 和 common 普通 join mapjoin 是没有reduce阶段 只有map阶段 在map阶段进行join操作 xff08 此知识点也会在大表join小表中体现 xff09 common
  • Gunicorn介绍、安装及使用

    1 简介 Gunicorn Green Unicorn 是一个 UNIX 下的 WSGI HTTP 服务器 xff0c 它是一个 移植自 Ruby 的 Unicorn 项目的 pre fork worker 模型 它既支持 eventlet
  • Spring Boot POM 详解

    正如这幅图所展示的那样 xff0c 在Spring IO Framework体系中 xff0c Spring Boot处在Execution layer xff0c 来看看官方对这层的解释 xff1a The Spring IO Execu
  • 基于阿木实验室P200飞行器simulink模型开发的多旋翼无人机自抗扰控制器(ADRC)参数调整和仿真

    1 飞行器模型参数 参考P200飞行器参数 利用网站https www flyeval com 计算飞行器如下 xff1a 2 参数设置具体如下 1 xff09 模型主要包括总线 期望数据生成模块 控制器 PWM生成器 飞行器对象模型 2
  • mkdir()函数

    一 创建目录 1 1 direct h 头文件 int mkdir const char path mode t mode 函数名 mkdir 功 能 建立一个目录 用 法 int mkdir const char dirname 头文件库
  • react路由基础与传参

    react router dom 1 react的一个插件 xff0c 专门用来实现单页面 2 基于react的项目基本都会用到它 路由的基本使用 1 路由导航区标签为Link或NavLink标签 lt Link to 61 34 xxx
  • ROS TF工具的使用

    1 打印坐标系转换关系 tf echo 命令格式 xff1a rosrun tf tf echo lt source frame gt lt target frame gt 输出数据类型 xff1a geometry msgs Transf
  • RK平台defconfig,Kconfig,Makefile配置

    1 简介 本文是基于RK平台 xff0c defconfig Kconfig Makefile配置总结 在编译内核之前 xff0c 我们可以对内核源代码进行配置 配置的目的主要是确定哪些模块会编译到内核当中 每次添加移植驱动文件时都要修改M
  • EEG信号中常见的干扰和噪声信号

    原文章 转载是为收集整理 xff0c 方便看 xff0c 如不允许 xff0c 联系可删 在EEG ERP研究中 xff0c 最令人头痛的问题之一是各种干扰和噪声信号混入到EEG ERP信号中 xff0c 因此 xff0c 数据分析的第一步
  • Linux编程——多路复用实现TCP双向通信

    ubuntu下模拟服务器与单个客户端之间的双向通信 xff0c 多路复用实现 功能与使用 服务器与客户端可以双向收发消息 xff0c 如果任意一方被外部强制断开 xff0c 另一方也会退出程序 任意一方输入 quit 并发送 xff0c 客
  • 通过Mavlink协议向Ardupilot请求数据流并解析数据

    通过Mavlink消息请求数据流 参考网页 xff1a 从自动驾驶仪请求数据 开发文档 ardupilot org 在这里我们使用Mavlink的REQUEST DATA STREAM 消息来获取我们需要的数据流 xff08 此消息可以设置
  • ROS学习笔记(二):ROS话题的发布与订阅

    第十讲 发布者Publisher的编程 1 创建功能包 learning topic cd test1 src catkin create pkg learning topic std msgs rospy roscpp geometry
  • 人工智能安全(二)—攻击

    1 Deep Leakage from Gradients 代码地址 xff1a https gitee com dugu1076 ai dlg git xff08 这份代码是我自己全部加上注解后的 xff0c 删除了所有多余代码 xff0
  • 通过TCP/IP实现PC(客户端)远程控制开发板(服务器)上LED灯的实验

    这篇我们来做个小实验 xff0c 实现开发板上运行服务端 xff0c 可以直接控制led灯 xff0c 客户端通过 socket连接到服务端 xff0c 通过发送指令来远程控制服务端的led灯 我们用平台总线的思想来编写驱动程序 xff0c