2023/7/4驱动开发,点灯

#ifndef __HEAD_H__
#define __HEAD_H__

// #define PHY_LED1_MODER 0X50006000
// #define PHY_LED1_ODR   0X50006014
// #define PHY_RCC        0X50000A28

//定义寄存器组织结构体
typedef struct{
    unsigned int moder;
    unsigned int otyper;
    unsigned int ospeedr;
    unsigned int pupdr;
    unsigned int idr;
    unsigned int odr;
}gpio_t;
//定义GPIOE和GPIOF
#define GPIOE ((gpio_t *)0X50006000)
#define GPIOF ((gpio_t *)0X50007000)
#define RCC (*(volatile unsigned int *)0X50000A28)

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

int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int fd = open("/dev/mychrdev", O_RDWR);
    if (fd < 0)
    {
        printf("打开设备文件失败\n");
        exit(-1);
    }
    while (1)
    {
        printf("请输入控制哪个灯-- 1:led1 2:led2 3:led3 1:开 0关>>");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = '\0';
        write(fd, buf, sizeof(buf));
    }
    
    close(fd);
    return 0;
}
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"
int major; //用于保留主设备号
char kbuf[128] = {0};

unsigned int *led1_moder;
unsigned int *led1_odr;

unsigned int *led2_moder;
unsigned int *led2_odr;

unsigned int *led3_moder;
unsigned int *led3_odr;

unsigned int *vir_rcc;
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{
    int ret;
    size = sizeof(kbuf) < size ? sizeof(kbuf) : size;
    ret = copy_to_user(ubuf, kbuf, size);
    if(ret)
    {
        printk("copy_to_user failed\n");
        return -EIO;
    }
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{
    int ret;
    size = sizeof(kbuf) < size ? sizeof(kbuf) : size;
    ret = copy_from_user(kbuf, ubuf, size);
    if(ret)
    {
        printk("copy_from_user failed\n");
        return -EIO;
    }
    //开关灯逻辑
    if(kbuf[0] == '1')
    {
        // 1 开灯 0 关灯
        if(kbuf[1] == '1')
        {
            (*led1_odr) |= (0x1 << 10);
        }else{
            (*led1_odr) &= (~(0x1 << 10));
        }
    }else if(kbuf[0] == '2')
    {
        if(kbuf[1] == '1')
        {
            (*led2_odr) |= (0x1 << 10);
        }else{
            (*led2_odr) &= (~(0x1 << 10));
        }
    }else if(kbuf[0] == '3')
    {
        if(kbuf[1] == '1')
        {
            (*led3_odr) |= (0x1 << 8);
        }else{
            (*led3_odr) &= (~(0x1 << 8));
        }
    }
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

struct file_operations fops=
{
    .open = mycdev_open,
    .read = mycdev_read,
    .write = mycdev_write,
    .release = mycdev_close,
};

static int __init mycdev_init(void)
{
    major = register_chrdev(0, "mychrdev", &fops);
    if( major < 0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功major=%d\n", major);
    //映射物理寄存器
    printk("这是地址:GPIOE->MODER= %x\n", GPIOE->moder);
    led1_moder = ioremap(0X50006000, 4);
    led1_odr = ioremap(0X50006014, 4);

    led2_moder = ioremap(0X50007000, 4);
    led2_odr = ioremap(0X50007014, 4);

    led3_moder = ioremap(0X50006000, 4);
    led3_odr = ioremap(0X50006014, 4);

    vir_rcc = ioremap(0X50000A28, 4);

    printk("寄存器地址映射成功\n");
    //寄存器初始化
    //led1
    (*vir_rcc) |= (0x1 << 4); //rcc使能

    (*led1_moder) &= (~(0x3 << 20)); //设置使能
    (*led1_moder) |= (0x1 << 20);
    (*led1_odr) &= (~(0x1 << 10)); //灭灯
    //led2
    (*led2_moder) &= (~(0x3 << 20)); //设置使能
    (*led2_moder) |= (0x1 << 20);
    (*led2_odr) &= (~(0x1 << 10)); //灭灯
    //led3
    (*led3_moder) &= (~(0x3 << 16)); //设置使能
    (*led3_moder) |= (0x1 << 16);
    (*led3_odr) &= (~(0x1 << 8)); //灭灯
    printk("硬件寄存器初始化成功\n");
    return 0;
}
static void __exit mycdev_exit(void)
{
    //取消寄存器 地址映射
    iounmap(vir_rcc);
    iounmap(led1_moder);   
    iounmap(led1_odr);
    iounmap(led2_moder);
    iounmap(led2_odr);
    iounmap(led3_moder);
    iounmap(led3_odr);

    //字符设备驱动的注销
    unregister_chrdev(major, "mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值