S5PV210实现单个LED灯的OPEN和CLOSE

//Makefile

#内核路径
KERNEL_DIR=/home/me/farsight/linux-3.0.8
#驱动程序代码所在的路径
CUR_DIR=$(shell pwd)
#驱动程序的名称
DRV_NAME1 = led_drv
APP_NAME = led_app

all:
        make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
        arm-none-linux-gnueabi-gcc -o $(APP_NAME) $(APP_NAME).c

clean:
        make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
        rm -rf $(APP_NAME)

install:
        cp -raf *.ko $(APP_NAME) /opt/rootfs/drv_module

#到底要把哪个.c编译成模块
obj-m = $(DRV_NAME1).o

//应用层

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

int main(void)
{
    int fd;
    fd = open("/dev/led_drv",O_RDWR);
    if(fd < 0)
    {
        perror("open");
        exit(1);
    }
    sleep(2);
    close(fd);
    return 0;
}
 

//内核驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/slab.h>

struct LED{
    volatile unsigned int GPC0_CON;
    volatile unsigned int GPC0_DAT;
};

struct fs210_led{
    int major;
    struct class * clazz;
    struct device *dev;
    struct LED * led;
};

struct fs210_led * fs210_led;


int led_drv_open(struct inode * node, struct file * filp)
{
    printk("----------%s----------\n",__FUNCTION__);
    //开灯
    fs210_led->led->GPC0_DAT |= (0x03 << 3);
    return 0;
}

int led_drv_release(struct inode * node, struct file * filp)
{
    printk("----------%s----------\n",__FUNCTION__);
    //关闭灯
    fs210_led->led->GPC0_DAT &= ~(0x03 << 3);
    return 0;
}
    
const struct file_operations fops = {
    .owner = THIS_MODULE,
    .open = led_drv_open,
    .release = led_drv_release,
};


static int __init led_drv_init(void)
{
   int ret;
   // 0.初始化全局的结构体对象
   fs210_led = kzalloc(sizeof(struct fs210_led), GFP_KERNEL);
   if(fs210_led == NULL)
   {
        printk("kzalloc error\n");
        return -ENOMEM;
   }
   
   // 1.申请/注册设备号
   //申请设备号
   //参数1:0 -- 内核默认分配未使用的
   //参数2:描述(自定义)
   //参数3:file_operation指针
   //返回值:大于0成功   负数失败
   fs210_led->major = register_chrdev(0, "led_drv", &fops);
   if(fs210_led->major < 0)
   {
        printk("register_chrdev error\n");
        ret = -EINVAL;
        goto kzalloc_err;
   }

   // 2.创建类
   // 创建类
   //参数1:当前模块
   //参数2:类描述(自定义)
   fs210_led->clazz = class_create(THIS_MODULE, "led_class");
   if(IS_ERR(fs210_led->clazz))
   {
        printk("register_chrdev error\n");
        ret = PTR_ERR(fs210_led->clazz);
        goto register_chrdev_err;
   }

   // 3.创建设备节点
   // mknod /dev/xxx  c  major  minor
   // 创建设备结点
   // 参数1: 类对象
   // 参数2: 父类
   // 参数3: 设备号
   // 参数4: 私有数据
   // 参数5: 设备节点名称
   fs210_led->dev = device_create(fs210_led->clazz, NULL, MKDEV(fs210_led->major, 0), NULL, "led_drv");
   if(IS_ERR(fs210_led->dev))
   {
        printk("device_create error\n");
        ret = PTR_ERR(fs210_led->dev);
        goto class_create_err;
   }

   // 4.硬件初始化
   //映射
   fs210_led->led = ioremap(0xE0200060, sizeof(struct LED));
   //配置GPIO引脚为输出
   fs210_led->led->GPC0_CON &= ~(0xff << 12);
   fs210_led->led->GPC0_CON |= (0x11 << 12);
   //先关闭灯
   fs210_led->led->GPC0_DAT &= ~(0x03 << 3);
   return 0;

   class_create_err:
           class_destroy(fs210_led->clazz);
   register_chrdev_err:
           unregister_chrdev(fs210_led->major, "led_drv");
   kzalloc_err:
           kfree(fs210_led);
        
   return ret;
}

static void __exit led_drv_exit(void)
{
    iounmap(fs210_led->led);
    device_destroy(fs210_led->clazz, MKDEV(fs210_led->major, 0));
    class_destroy(fs210_led->clazz);
    unregister_chrdev(fs210_led->major, "led_drv");
    kfree(fs210_led);
}

module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__Lewis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值