IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 树莓派引脚驱动编写(2) -> 正文阅读

[系统运维]树莓派引脚驱动编写(2)

1.续上篇文章的代码测试过后这节真正来验证是否驱动成功
(1)首先改写驱动代码(在linux源码树目录的/driver/char下)
注意:在编译之前可以先备份以下

#include <linux/fs.h>                   //file_operations声明
#include <linux/module.h>       //module_init  module_exit声明
#include <linux/init.h>         //__init  __exit 宏定义声明
#include <linux/device.h>               //class  devise声明
#include <linux/uaccess.h>      //copy_from_user 的头文件
#include <linux/types.h>        //设备号  dev_t 类型声明
#include <asm/io.h>             //ioremap iounmap的头文件

static struct class *pin4_class;
static struct device *pin4_class_dev;

static dev_t devno;                     //设备号
static int major = 231;                         //主设备号
static int minor = 0;                           //次设备号
static char* module_name = "pin4";      //模块名

volatile unsigned int *GPFSEL0 = NULL;
volatile unsigned int *GPSET0  = NULL;
volatile unsigned int *GPCLR0  = NULL;

static int pin4_open(struct inode *inode, struct file *file)
{
        printk("pin4_open\n");  //内核的打印函数,和printf相似
        //配置pin4引脚为输出引脚
        *GPFSEL0 &= ~(0X6 << 12);//把bit14,bit13配置成0
        *GPFSEL0 |= (0X01 << 12);//把bit12配置成1
        return 0;
}


static int pin4_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
        printk("pin4_read\n");
        return 0;
}

static ssize_t pin4_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
        int userCmd;

        printk("pin4_write\n");
        //获取上层write函数的值
        copy_from_user(&userCmd,buf,count);
        //根据值来操作io口,高电平或低电平
        printk("get value\n");
        if(userCmd == 1)
        {
                *GPSET0 |= 0x1 << 4;
        }
        else if(userCmd == 0)
        {
                *GPCLR0 |= 0X1 << 4;
        }
        else
        {
                printk("undo\n");
        }
        return 0;
}


static struct file_operations pin4_fops = {
        .owner = THIS_MODULE,
        .open = pin4_open,
        .write = pin4_write,
        .read = pin4_read,
};

int __init pin4_drv_init(void)          //实际驱动入口
{

        int ret;
        printk("insmod driver pin4 success\n");
        //创建设备号
        devno = MKDEV(major, minor);
        //注册驱动,告诉内核,把这个驱动加入到内核驱动的链表中
        ret = register_chrdev(major, module_name, &pin4_fops);
        //让代码在/dev自动生成设备
        pin4_class = class_create(THIS_MODULE, "myfirstdemo");
        //创建设备文件
        pin4_class_dev = device_create(pin4_class, NULL, devno, NULL, module_name);
        //物理地址转换为虚拟地址,io寄存器映射成普通内存单元进行访问
        GPFSEL0 = (volatile unsigned int *)ioremap(0x3f200000,4);
        GPSET0  = (volatile unsigned int *)ioremap(0x3f20001C,4);
        GPCLR0  = (volatile unsigned int *)ioremap(0x3f200028,4);
        return 0;
}


void __exit pin4_drv_exit(void)
{
        //卸载驱动时解除映射
        iounmap(GPFSEL0);
        iounmap(GPSET0);
        iounmap(GPCLR0);

        device_destroy(pin4_class, devno);
        class_destroy(pin4_class);
        unregister_chrdev(major, module_name);  //卸载驱动
        //卸载驱动与创建的顺序相反

}

module_init(pin4_drv_init);  //入口,内核加载该驱动的时候,这个宏会被调用
module_exit(pin4_drv_exit);
MODULE_LICENSE("GPL v2");   //声明GPL规范

(2)编译在linux源码树目录下执行ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 modules进行编译,然后将生成的.ko文件拷贝到树莓派上去,然后在树莓派上加载驱动模块sudo insmod pin4driver2.ko可以用llsmod查看是否加载成功,然后给/dev/pin4赋予666 权限sudo chmod 666 /dev/pin4

(3)修改测试文件

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

int main()
{
        int fd;
        int cmd;
        int data;

        fd = open("/dev/pin4",O_RDWR);
        if(fd<0){
                printf("open failed\n");
                perror("reson:");
        }
        else{
                printf("open success\n");

        }
        printf("input command : 1/0\n1:set pin4 high\n0:set pin4 low\n");
        scanf("%d",&cmd);
        if(cmd == 1){
				data = 1;
        }
        if(cmd == 0){
                data = 0;
        }
        printf("data = %d\n");
        fd = write(fd,&data,1);


}

(4)编译测试文件arm-linux-gnueabihf-gcc pin4under.c -o realtest生成realtest的可执行文件用file + 文件名查看改可执行文件适用的平台,以及demsg查看底层打印信息,然后同样将该可执行文件拷贝到树莓派上去。
(5)执行测试文件然后在树莓派上用gpio readall查看引脚的电平变化。

注意:拷贝时可以用mdk5sum + 文件名查看拷贝过后文件是否有损坏。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-09-14 13:47:18  更:2021-09-14 13:48:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 16:55:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码