树莓派驱动开发简单案例完整过程(动态加载驱动)

2023-11-06

1.下载树莓派os镜像:https://www.raspberrypi.org/downloads/raspbian/ 

2.使用命令:uname -a 查看树莓派内核:Linux raspberrypi 4.19.118-v7+ #1311 SMP Mon Apr 27 14:21:24 BST 2020 armv7l GNU/Linux

3.一般使用是树莓派镜像中不含有内核源码,因此要下载树莓派内核源码:在目录/usr/src 下执行命令:sudo apt-get install raspberrypi-kernel-headers

******* 将会下载到与uname -a 查看树莓派内核版本号一致的内核源码。如果不一致,可能无法用于内核驱动的使用。

4.编写驱动helloworld.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>

#define HELLOWORLD_MAJOR      200           //主设备号
#define HELLOWORLD_NAME     "helloworld"    //名字

static char readbuf[30]; /*读缓冲 */
static char writebuf[30];  /* 写缓冲 */
static char kerneldata[] = {"Hello World!"};


static int helloworld_open(struct inode *inode, struct file *filp)
{
   	printk("helloworld_open\r\n");
    return 0;
}

static int helloworld_release(struct inode *inode, struct file *filp)
{
   	printk("helloworld_release\r\n");
    return 0;   
}

static ssize_t helloworld_read(struct file *filp, __user char *buf, size_t count,
			loff_t *ppos)
{ 
    int ret  = 0;
    printk("helloworld_read\r\n");
    memcpy(readbuf, kerneldata, sizeof(kerneldata));
    ret = copy_to_user(buf, readbuf, count);

    return 0;  
}

static ssize_t helloworld_write(struct file *filp, const char __user *buf,
			 size_t count, loff_t *ppos)
{
    int ret = 0;
    printk("helloworld_write\r\n");
    ret = copy_from_user(writebuf, buf, count);
    if(ret == 0) {
        printk("kernel recevdata:%s\r\n", writebuf);
    }

    return 0; 
}

/*
 * 字符设备 操作集合
 */
static struct file_operations helloworld_fops={
    .owner = THIS_MODULE,
    .open = helloworld_open,
    .release = helloworld_release,
    .read = helloworld_read,
    .write = helloworld_write,
};


static int __init helloworld_init(void)
{
    int ret = 0;
    printk("hello world init\r\n");

    /* 注册字符设备 */
    ret = register_chrdev(HELLOWORLD_MAJOR, HELLOWORLD_NAME, &helloworld_fops);
    if(ret < 0) {
        printk("helloworld init failed!\r\n");
    }

	return 0;
}

static void __exit helloworld_exit(void)
{
    printk("helloworld_exit\r\n");	
    /* 注销字符设备 */
    unregister_chrdev(HELLOWORLD_MAJOR, HELLOWORLD_NAME);

}

/*
 模块入口与出口
 */
module_init(helloworld_init);  /* 入口 */
module_exit(helloworld_exit);  /* 出口 */

MODULE_LICENSE("GPL");      
MODULE_AUTHOR("changhaijun");


5.编写Makefile

ifneq ($(KERNELRELEASE),)
obj-m := helloworld.o
else  
KDIR := /usr/src/linux-headers-4.19.118-v7+/  #树莓派内核源码目录
PWD := $(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm *.o *.ko *.mod.c modules.order Module.symvers
.PHONY:clean
endif

6.将helloworld.c 和 Makefile 放在同一个目录下执行:make   生成.ko文件

7.加载驱动与卸载驱动

(1)动态加载驱动执行:insmod  helloworld.ko    查看驱动是否加载上执行命令:cat /proc/devices

(2)卸载驱动执行命令:rmmod helloworld.ko   查看驱动是否卸载执行命令:cat /proc/devices

8.手动创建设备节点执行命令:mknod /dev/helloworld  c 200  0        (c 表示字符设备)  查看是否创建:ls  /dev

9.编写应用程序helloworldApp.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int ret = 0;
    int fd = 0;
    char *filename;
    char readbuf[30], writebuf[30];
    static char usrdata[] = {"user data!"};

    if(argc != 3) {
        printf("Error usage!\r\n");
        return -1;
    }

    filename = argv[1];

    fd = open(filename, O_RDWR);
    if(fd < 0 ) {
        printf("Can't open file %s\r\n", filename);
        return -1;
    }

    if(atoi(argv[2]) == 1){ /*  璇?*/
        /* read */
        ret = read(fd, readbuf, 13);
        if (ret < 0) {
            printf("read file %s failed!\r\n", filename);
        }
        else {
            printf("APP read data:%s\r\n", readbuf);
        }
    }

    /* write */
    if(atoi(argv[2]) == 2) { /* 鍐?*/ 
        memcpy(writebuf, usrdata, sizeof(usrdata));
        ret = write(fd, writebuf, 11);
        if (ret < 0) {
            printf("write file %s failed!\r\n", filename);
        }else {
            printf("APP writedata:%s\r\n", writebuf);
        }
    }

    /* close */
    ret = close(fd);
    if(ret < 0) {
        printf("close file %s falied!\r\n", filename);
    }

    return 0 ;

}

10.交叉编译工具编译应用程序helloworldApp.c

gcc -Wall -o helloworldApp helloworldApp.c  

 生成 helloworldApp

11.执行应用程序:./helloworldApp  /dev/helloworld 1    输出:APP read  data:Hello World!

     执行应用程序:./helloworldApp  /dev/helloworld 2    输出:APP writedata:user data!

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

树莓派驱动开发简单案例完整过程(动态加载驱动) 的相关文章

  • 包名中的“dev”后缀?

    使用 apt get 时 我看到一些软件包的名称后面有一个 dev 后缀 libreadline5 libreadline dev zlib1g zlib1g dev 这些到底是什么 我应该安装它们吗 你需要这些编译并链接因为它们提供了要链
  • 为什么我们可以将 sockaddr 转换为 sockaddr_in

    我明白为什么强制转换很有用sockaddr to sockaddr in 但我不明白这怎么可能 据我所知 它们的大小相同sockaddr in添加了sin zero使其大小相同 我想知道编译器如何知道从哪里获取信息sockaddr in如果
  • Makefiles:从一个目录获取.cpp,并将编译后的.o放在另一个目录中

    我正在开发适用于移动设备 Windows Mobile 6 和 Android 的跨平台 2D 引擎 我的 Windows 版本已基本准备就绪 但我仍需要确保 Android 上也提供相同的功能 我想要的是一个Makefile在项目的根目录
  • 为什么我的 sed 命令在使用变量时失败?

    使用 bash 我尝试插入日期变量并搜索该日期的日志文件 然后将输出发送到文件 如果我像这样对日期进行硬编码 它会起作用 sed n Nov 22 2010 p file gt log file 但如果我这样做就会失败 date Nov 2
  • 删除损坏的链接 Unix

    我想删除损坏的链接 但在此之前我想确认目录中是否存在链接文件 我们来调用一下链接A if a A then print ya A is ther fi But if A链接已损坏 那么我该如何检查 find L type l找到损坏的符号链
  • 与 grep 类似地突出显示文本,但不过滤掉文本[重复]

    这个问题在这里已经有答案了 使用 grep 时 它将突出显示与正则表达式匹配的行中的任何文本 如果我想要这种行为 但同时让 grep 打印出所有行怎么办 快速浏览完 grep 手册页后 我发现一无所获 使用确认 看看它的 passthru此
  • accept() 创建一个新套接字是什么意思?

    我的问题基于以下理解 套接字由 ip port 定义 服务器和客户端都有自己的套接字 Socket连接由五组server ip server port client ip client port protocol定义 套接字描述符是标识套接
  • 在 Linux 上的 makefile 和 Makefile 之间进行选择

    我想在一个目录中同时使用 Makefile 和 makefile 进行 make 默认情况下 它将执行makefile 我可以选择执行 Makefile 吗 提前致谢 最简单的选择是使用 f make f Makefile From man
  • 如何在 Linux 上使用 Python 导出

    我需要在 Python 中进行这样的导出 export MY DATA my export 我尝试过这样做 python mode coding utf 8 import os os system export MY DATA my exp
  • 如何从 ext2/ext3 文件系统上的稀疏文件中删除一些块

    当您写入稀疏文件时 ext2 ext3 文件系统会自动分配块 但是当我不再需要其中的某些块时 我发现没有办法做到这一点 感觉就像使用 malloc 而不使用 free 是否可以 释放 稀疏文件的某些块 如果是的话 怎么样 不要告诉我将其复制
  • bcrypt_lib.node:未定义符号:node_module_register

    Error home george Desktop myProject node modules bcrypt build Release bcrypt lib node undefined symbol node module regis
  • 使用curl复制本地文件[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有办法用curl复制本地文件 我需要它作为cp命令的替代品 这有点奇怪 但我正在一个 cp 不可用的环境中工作 你可以说 curl o
  • 汇编语言中的全局_start是什么?

    这是我的汇编级代码 section text global start start mov eax 4 mov ebx 1 mov ecx mesg mov edx size int 0x80 exit mov eax 1 int 0x80
  • 如何使用AWK从文件中连续输出行

    我有一个多行文件 我想连续输出文件的某些行 比如第一次 从第1行打印到第5行 下次 打印第2行到第6行 依此类推 我发现 AWK 是一个非常有用的函数 我尝试自己编写代码 但它什么也没输出 以下是我的代码 bin bash for n in
  • 专门逐行调试

    我有一个用 Pascal 编写的脚本 我会以这种方式调试它 在每一行停止 转储内存中所有变量的值 然后转到下一行 是否可以使用 gdb 或其他 Linux 开源工具来完成此操作 使用选项编译文件 g fpc gpc g file pas R
  • 在内核模块中执行shell命令

    是否可以在内核模块中执行shell命令 我知道我们可以在用户空间 C 代码中使用system子程序 我正在调试一个存在内存泄漏问题的内核模块 在无限循环中执行 insmod 和 rmmod module ko 后 8G RAM 的系统在几分
  • ModemManager:mmcli 获取信号强度

    我无法检索 Sierre Wireless MC7304 上的信号强度 另外通过 mmcli 发送 AT 命令似乎不起作用 sudo mmcli m org freedesktop ModemManager1 Modem 0 signal
  • Android Studio无法更新

    我正在运行 Mint 14 Linux 并且在使用 Android Studio 时遇到了一个主要问题 运行更新功能时 所有软件包都会返回 访问被拒绝 状态 我怎样才能解决这个问题 如何授予下载和安装的权限 附加信息 studio sh 正
  • 为什么当设置为 TLS 选择器时,ES 和 DS 在 64 位内核上最终会归零?

    下面的 32 位程序调用set thread area 2 http linux die net man 2 set thread area在 GDT 中创建一个条目 该条目旨在用于 TLS 通常将结果选择器放入FS or GS并成功使用
  • 如何在 Python 中将列表变量传递给 subprocess.call 命令

    我有一个清单 apps apps append wq35a5huqlja45jsyukrpmwuiayovrmh apps append q7mimvgduueernwvw4y22t5huemykntw apps append pmudbp

随机推荐

  • 【分析方法】A/B test

    A B测试是什么 怎么做 有什么作用呢 本篇文章为大家分享了几种应用场景及案例 告诉大家如何在团队中有效推进A B测试 一 A B测试 为了检测某些用户到底属于哪一类别 我们定制了A类用户喜欢的产品和B类用户喜欢的产品 统计并对比了不同方案
  • 给jupyter添加多个python版本的kernel

    两种方法 1 想添加的python版本已存在 1 通过ipykernel为jupyter添加python环境 activate env name python m ipykernel install name env name 2 关闭py
  • Windows安装Anaconda,创建pytorch环境,pycharm配置环境

    目录 1 简介 2 安装Anaconda 3 创建一个独立的环境 4 安装依赖的库 5 安装pytorch 6 pycharm中使用conda环境 7 到这里安装就结束了 希望对您有所帮助 如有什么错误请指正 1 简介 安装Anaconda
  • C++:重载

    一 重载 重载 重载函数是函数的一种特殊情况 为方便使用 C 允许在同一范围中声明几个功能类似的同名函数 但是这些同名函数的形式参数 指参数的个数 类型或者顺序 必须不同 也就是说用同一个函数完成不同的功能 重载函数常用来实现功能类似而所处
  • git fatal: unable to access  Failed to connect to localhost port 1080: Connection refused

    git 拉取 更新子模块失败 提示失败 Submodule libXesBase https git xxxxx com xesoa libXesBase git registered for path libXesBase Cloning
  • 整合google,51ditu和mapbar的地图API

    http blog 163 com goodluck lq 126 blog static 63285386201001994058213
  • Java中的异常处理机制的简单原理和应用。

    异常是指java程序运行时 非编译 所发生的非正常情况或错误 与现实生活中的事件很相似 现实生活中的事件可以包含事件发生的时间 地点 人物 情节等信息 可以用一个对象来表示 Java使用面向对象的方式来处理异常 它把程序中发生的每个异常也都
  • 基于STM32F103单片机的车牌识别图像处理识别系统 原理图PCB程序设计

    硬件电路的设计 末尾附文件 系统硬件系统分析设计 1 STM32单片机核心电路设计 STM32系列处理器是意法半导体ST公司生产的一种基于ARM 7架构的32位 支持实时仿真和跟踪的微控制器 选择此款控制芯片是因为本系统设计并非追求成本的最
  • React通过axios拿到数据后,使用hooks,通过map函数对列表进行渲染

    导入hooks 导入你封装的http模块 引入样式 import React useEffect useState from react import http from API import index scss 默认导出一个函数组价 并
  • C#学习记录——.NET的三层架构

    每一个不曾起舞的日子 都是对生命的辜负 尼采 每一个不读书的的日子 都是对时光的辜负 今天学习 零基础学C 3 0 NET的三层架构 为了实现大型应用系统后续功能的扩展性和程序的灵活性 NET编程语言借鉴了JAVA的MVC思想 产生了三层架
  • MySQL - 第9节 - MySQL内外连接

    目录 1 内连接 2 外连接 2 1 左外连接 2 2 右外连接 3 简单案例 1 内连接 表的连接分为内连接和外连接 内连接实际上就是利用where 子句对两种表形成的笛卡儿积进行筛选 我们前面学习的查询都是内连接 也是在开发过程中使用的
  • Markdown语法--Obsidian笔记

    Markdown 语法 笔记 文章目录 Markdown 语法 笔记 语法分类 文字层级类 1 标题 2 段落 3 区块引用 4 代码区块 5 列表 6 待办事项 文字格式类 1 样式 2 表格 链接引用类 1 链接 2 图片 3 脚注 4
  • Dubbo与Spring Cloud的区别

    这是个老生常谈的问题 每个技术团队在业务转型微服务化架构的时候都会纠结过这个选型问题 首先 dubbo 之前确实在 2012 年的时候发布了最后一个版本 2 5 3 并且停止维护更新 在2017年的时候又 起死回生 官方宣布重启更新 并重点
  • 2021图像检索综述

    论文地址 Deep Image Retrieval A Survey 本文是2021年最新的关于图像检索的综述 介绍了基于内容的图像检索 content based image retrieval CBIR 在深度学习技术上的进展 目录 0
  • Traceback (most recent call last): File “D:/python_workspace/hello.py“, line 3, in <module>

    错误背景 python的初学者 在学习多行语句 错误信息如下 错误原因 变量有字符串类型 有整型类型 有浮点型 在java 里面 String标识字符串类型 Int标识整型 在python里面 a yy1 就是字符串类型 a 1就是数字类型
  • 29_content 阶段的concat 模块

    文章目录 提升性能 content 阶段的 caoncat 模块 concat 模块的指令 示例配置 提升性能 content 阶段的 caoncat 模块 功能 当页面需要访问多个小文件时 把它们内容合并到一次http 响应中返回 提升性
  • 数组排序的方法?

    1 sort排序 let arr 1 2 3 4 5 6 7 8 9 0 9 8 7 6 3 4 5 5 var res console log arr 排序前 1 2 3 4 5 6 7 8 9 0 9 8 7 6 3 4 5 5 arr
  • SSD目标检测算法原理(上)

    目录 一 目标检测概述 1 1 项目演示介绍 1 2 图片识别背景 1 3 目标检测定义 二 目标检测算法原理 2 1 任务描述 2 2 目标检测算法必备基础 2 3目标检测算法模型输出 目标检测 overfeat模型 R CNN模型 候选
  • h2database源码解析-查询优化器原理

    目录 一 成本计算规则 二 单表查询 三 多表关联查询 一 成本计算规则 h2的查询优化器基于成本的 因此在执行查询前 会基于成本计算使用哪个索引 如果涉及多表关联 还会计算不同表关联顺序的成本 最终基于最小成本得出执行计划 单表查询时 遍
  • 树莓派驱动开发简单案例完整过程(动态加载驱动)

    1 下载树莓派os镜像 https www raspberrypi org downloads raspbian 2 使用命令 uname a 查看树莓派内核 Linux raspberrypi 4 19 118 v7 1311 SMP M