[LINUX] [Raspberry Pi] Minimum device driver creation memo to output GPIO

Premise

--Run on Raspberry Pi --When you write something to the device file, GPIO21 is output. --The output ends when you rmmod the module --Raspberry Pi Model B + (maybe) -Simple character device driver creation memo (cdev) --Qiita continued --No error handling

code

driver.c


#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h> // copy_from_user
#include <linux/cdev.h> // cdev★
#include <linux/ioport.h>
#include <linux/io.h>
#define NODE_NAME "kuredev"
#define SUCCESS 0

MODULE_LICENSE("Dual BSD/GPL");

static int major_num = 0;
static unsigned char k_buf[1024];
static int data_size;
static int read_count = 0;
static int minor_num = 1;//★
static struct cdev kure_cdev;//★
static void __iomem *gpio_map;
static volatile uint32_t *gpio_base;


static void gpio_set(void){
        printk("gpio_set\n");
        request_mem_region(0x20200000, 4096, "kure");
        gpio_map = ioremap_nocache(0x20200000, 4096);
        gpio_base = (volatile uint32_t *)gpio_map;

        gpio_base[2] = 0x8;
        gpio_base[7] = 0x200000;
}

static void gpio_clear(void){
        printk("gpio_clear\n");
        request_mem_region(0x20200000, 4096, "kure");
        gpio_map = ioremap_nocache(0x20200000, 4096);
        gpio_base = (volatile uint32_t *)gpio_map;

        gpio_base[2] = 0x8;
        gpio_base[10] = 0x200000;

}


static int kure_open(struct inode *inode, struct file *file){
        printk("kure_open\n");
        return SUCCESS;
}

static int kure_release(struct inode *inode, struct file *file){
        printk("kure_release\n");
        return SUCCESS;
}

static ssize_t kure_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos){
        printk("kure_read, count: %d, data_size: %d\n", count, data_size);
        if(read_count){
                return 0;
        }
        int len;
        if(count > data_size){
                len = data_size;
        }else{
                len = count;
        }
        printk("len: %d\n", len);
        copy_to_user(buf, k_buf, len);
        read_count++;
        return len;
}

static ssize_t kure_write(struct file *file, char __user *buf, size_t count,loff_t *f_pos){
        printk("kure_write, count = %d\n", count);
        copy_from_user(k_buf, buf, count);
        data_size = count;

        gpio_set();
        return count;
}

struct file_operations kure_fops = {
        .owner = THIS_MODULE,
        .read = kure_read,
        .write = kure_write,
        .open = kure_open,
        .release = kure_release
};

static int kure_init(void){
        dev_t dev = MKDEV(major_num, 0);//★
        alloc_chrdev_region(&dev, 0, minor_num, NODE_NAME);//★
        major_num = MAJOR(dev);//★
        cdev_init(&kure_cdev, &kure_fops);//★
        kure_cdev.owner = THIS_MODULE;//★
        cdev_add(&kure_cdev, MKDEV(major_num, 0), minor_num);//★

        printk("kure_init\n");
        return SUCCESS;
}

static void kure_exit(void){
        gpio_clear();
        dev_t dev = MKDEV(major_num, 0);//★
        cdev_del(&kure_cdev);//★
        unregister_chrdev_region(dev, minor_num);//★

        printk("kure_exit\n");
}


module_init(kure_init);
module_exit(kure_exit);

Makefile


HOME ?= /home/pi
ARCH := arm
KPATH := $(HOME)/raspberry/linux

obj-m := driver.o

all:
        make ARCH=$(ARCH) -C $(KPATH) M=$(PWD)  modules

clean:
        make ARCH=$(ARCH) -C $(KPATH) M=$(PWD) clean

Run

$ make
$ sudo insmod driver.ko
$ sudo mknod -m 666 /dev/kuredev c 242 0
$ echo 0 > /dev/kuredev ★ Output
$ sudo rm -rf /dev/kuredev
$sudo rmmod driver ★ Output ends

When output, with ↓ [Raspberry Pi] A small memo to control GPIO from userland via register --Qiita

Recommended Posts

[Raspberry Pi] Minimum device driver creation memo to output GPIO
Output from Raspberry Pi to Line
Translate I2C device driver for Arduino to Python for Raspberry pi
Simple character device driver creation memo (cdev)
Raspberry Pi 4 setup memo
Simple character device driver creation memo (Read / Write implementation)
I talked to Raspberry Pi
Introducing PyMySQL to raspberry pi3
Raspberry Pi + Python + OpenGL memo
A memo when connecting bluetooth from a smartphone / PC to Raspberry Pi 4
Port FreeRTOS to Raspberry Pi 4B
Install ghoto2 on Raspberry Pi (memo)
[Raspberry Pi] Changed Python default to Python3
A memo to simply use the illuminance sensor TSL2561 with Raspberry Pi 2
Connect two USB cameras to Raspberry Pi 4
How to install NumPy on Raspberry Pi