单片机
返回首页

代码示例_ioctl

2025-02-07 来源:cnblogs

//头文件

#include

#include

#include

#include

#include


#include

#include

#include


#define LED_NUM_ON        _IOW('L',0x1122,int)

#define LED_NUM_OFF        _IOW('L',0x3344,int)

#define LED_ALL_ON        _IO('L',0x1234)

#define LED_ALL_OFF        _IO('L',0x5678)


//面向对象编程----设计设备的类型

struct s5pv210_led{

    unsigned int major;

    struct class * cls;

    struct device * dev;

    int data;

};

struct s5pv210_led *led_dev;


volatile unsigned long *gpco_conf;

volatile unsigned long *gpco_data;



//实现设备操作接口

int led_open(struct inode *inode, struct file *filp)

{

    

    printk('--------^_^ %s------------n',__FUNCTION__);

    //将对应的管脚设置为输出

    *gpco_conf &= ~(0xff<<12);   //19--12清0

    *gpco_conf |= 0x11<<12;        //19---12赋值:00010001


    return 0;

}

ssize_t led_write(struct file *filp, const char __user *buf, size_t size, loff_t *flags)

{

    int ret;

    printk('--------^_^ %s------------n',__FUNCTION__);


    //应用空间数据转换为内核空间数据

    ret = copy_from_user(&led_dev->data,buf,size);

    if(ret != 0){

        printk('copy_from_user error!n');

        return -EFAULT;

    }


    if(led_dev->data){

        //点灯

        *gpco_data |= 0x3<<3;

    }else{

        //灭灯

        *gpco_data &= ~(0x3<<3);

    }


    return size;

}


long led_ioctl(struct file *filp, unsigned int cmd , unsigned long args)

{

    int num = args+2;

    printk('--------^_^ %s------------n',__FUNCTION__);

    switch(cmd){

        case LED_NUM_ON:        //将某个灯点亮

            if(num != 3 && num != 4)

                return -EINVAL;

            else

                *gpco_data |= 0x1 << num;

            break;

        case LED_NUM_OFF:        //将某个灯点灭掉

            if(num != 3 && num != 4)

                return -EINVAL;

            else

                *gpco_data &= ~(0x1 << num);

            break;

        case LED_ALL_ON:        //两个灯同时亮

            *gpco_data |= 0x3<<3;

            break;

        case LED_ALL_OFF:        //两个灯同时灭

            *gpco_data &= ~(0x3<<3);

            break;

        default:

            printk('unknow cmd!n');

    }


    return 0;

}


int led_close(struct inode *inode, struct file *filp)

{

    printk('--------^_^ %s------------n',__FUNCTION__);

    //灭灯

        *gpco_data &= ~(0x3<<3);

    return 0;

}



static struct file_operations fops = {

    .open = led_open,

    .write = led_write,

    .unlocked_ioctl = led_ioctl,

    .release = led_close,

};



//加载函数和卸载函数

static int __init led_init(void)   //加载函数-----在驱动被加载时执行

{

    int ret;

    printk('--------^_^ %s------------n',__FUNCTION__);

    //0,实例化设备对象

    //参数1 ---- 要申请的空间的大小

    //参数2 ---- 申请的空间的标识

    led_dev = kzalloc(sizeof(struct s5pv210_led),GFP_KERNEL);

    if(IS_ERR(led_dev)){

        printk('kzalloc error!n');

        ret = PTR_ERR(led_dev);

        return -ENOMEM;

    }

    

    //1,申请设备号

#if 0

    //静态申请主设备号

    led_dev->major = 256;

    ret = register_chrdev(led_dev->major,'led_drv',&fops);

    if(ret < 0){

        printk('register_chrdev error!n');

        return -EINVAL;

    }

#else

    //动态申请主设备号

    led_dev->major = register_chrdev(0,'led_drv',&fops);

    if(led_dev->major < 0){

        printk('register_chrdev error!n');

        ret =  -EINVAL;

        goto err_kfree;

    }

#endif


    //2,创建设备文件-----/dev/led1

    led_dev->cls = class_create(THIS_MODULE,'led_cls');

    if(IS_ERR(led_dev->cls)){

        printk('class_create error!n');

        ret = PTR_ERR(led_dev->cls);

        goto err_unregister;

    }

    

    led_dev->dev = device_create(led_dev->cls,NULL,MKDEV(led_dev->major,0),NULL,'led');

    if(IS_ERR(led_dev->dev)){

        printk('device_create error!n');

        ret = PTR_ERR(led_dev->dev);

        goto err_class;

    }



    //3,硬件初始化----地址映射


        gpco_conf = ioremap(0xE0200060,8);

        gpco_data = gpco_conf+1;

    

    return 0;


err_class:

    class_destroy(led_dev->cls);


err_unregister:

    unregister_chrdev(led_dev->major,'led_drv');

    

err_kfree:

    kfree(led_dev);

    return ret;


    

}


static void __exit led_exit(void)   //卸载函数-----在驱动被卸载时执行

{

    printk('--------^_^ %s------------n',__FUNCTION__);

    device_destroy(led_dev->cls,MKDEV(led_dev->major,0));

    class_destroy(led_dev->cls);

    unregister_chrdev(led_dev->major,'led_drv');

    kfree(led_dev);

}


//声明和认证

module_init(led_init);

module_exit(led_exit);

MODULE_LICENSE('GPL');


#include

#include

#include

#include

#include

#include

#include


#define LED_NUM_ON        _IOW('L',0x1122,int)

#define LED_NUM_OFF        _IOW('L',0x3344,int)

#define LED_ALL_ON        _IO('L',0x1234)

#define LED_ALL_OFF        _IO('L',0x5678)



int main(void)

{


    int fd;


    fd = open('/dev/led',O_RDWR);

    if(fd < 0){

    perror('open');

    exit(1);

    }


    //闪灯

    while(1){

    //第一个灯闪

    ioctl(fd,LED_NUM_ON,1);

    sleep(1);

    ioctl(fd,LED_NUM_OFF,1);

    sleep(1);

    

    //第二个灯闪

    ioctl(fd,LED_NUM_ON,2);

    sleep(1);

    ioctl(fd,LED_NUM_OFF,2);

    sleep(1);


    //两个灯同时闪

    ioctl(fd,LED_ALL_ON);

    sleep(1);

    ioctl(fd,LED_ALL_OFF);

    sleep(1);


    }


    close(fd);

    return 0;

}


#指定内核源码路径

KERNEL_DIR = /home/farsight/s5pv210/kernel/linux-3.0.8

CUR_DIR = $(shell pwd)

MYAPP = test


all:

    #让make进入内核源码编译,同时将当前目录中的c程序作为内核模块一起编译

    make -C $(KERNEL_DIR) M=$(CUR_DIR) modules

    arm-none-linux-gnueabi-gcc -o $(MYAPP) $(MYAPP).c


clean:

    #删除上面编译生成的文件

    make -C $(KERNEL_DIR) M=$(CUR_DIR) clean

    rm -rf $(MYAPP)


install:

    cp *.ko $(MYAPP) /opt/rootfs/drv_module


#指定当前目录下哪个文件作为内核模块编

obj-m = led_drv.o


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 家用电器遥控器

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • DS1669数字电位器

  • HA1377 桥式放大器 BCL 电容 17W(汽车音频)

    相关电子头条文章