埋め込まれたLINUXドライバーが14のソフトウェアとハードウェアの分離プログラミング(2)コード例を学習(構造体リソース構造を介して実装)

組み込みLINUXドライバーが14のソフトウェアとハ​​ードウェアの分離プログラミング(2つ)のコード例を学習

1.ハードウェア情報の構成

//btn_led_dev.c
include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
struct resource led_src_B[] = {
    
    
    {
    
        //用于保存寄存器地址
        .start = 0XC001B000,
        .end   = 0XC001B000 + 0X24,
        .flags = IORESOURCE_MEM
    },
    {
    
    
       用于保存GPIO号
        .start =26 ,
        .end   =26 ,
        .flags = IORESOURCE_IRQ
    }
};
static void dd_close(struct device *dev){
    
    }//WARNING: at drivers/base/core.c:196
static struct platform_device btn_led_dev= {
    
    
    .name = "LED_",//硬件驱动名称
    .id   = 1,//当有多个同名配件驱动时,用ID加以区分
    .dev = {
    
    
            .release = dd_close  //用于消除警告
        },
    .num_resources = 2,//一般可以用ARRAY_SIZE(led_src_B) ,即:数组元素个数
    .resource = led_src_B//数组首地址
};

static int btn_led_dev_init(void){
    
    
    platform_device_register(&btn_led_dev); // 注册硬件信息
    return 0;
}
static void btn_led_dev_exit(void){
    
    
    platform_device_unregister(&btn_led_dev_3); //释放硬件信息注册
}
module_init(btn_led_dev_init);
module_exit(btn_led_dev_exit);
MODULE_LICENSE("GPL");

2.ソフトウェアドライバーコード:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
void * ioremap_ret ;
unsigned long *base;
unsigned long *outenb;
unsigned long *altfn;
int myprobe(struct platform_device * pl_reg){
    
    
    struct resource *phy_src = platform_get_resource(pl_reg,IORESOURCE_MEM,0); //保存寄存器地址
    struct resource *gpio_src = platform_get_resource(pl_reg,IORESOURCE_IRQ,0);//保存GPIO号
    ioremap_ret = ioremap((phy_src ->start),0x24);//寄存器地址和虚拟地址的映射
    base   = (unsigned long *) ioremap_ret;//GPIO号对应寄存器首地址
    *base   &= ~(0x1 << gpio_src ->start);
    outenb = (unsigned long *) (ioremap_ret + 0x4);
    *outenb |=  (0x1 << gpio_src -> start);    
    if(gpio_src->start < 15){
    
    
        altfn  = (unsigned long *) (ioremap_ret +  0x20);
        *altfn &= ~(0x3 << (gpio_src ->start * 2));
        *altfn |=  (0x1 << (gpio_src ->start * 2));
    }
    else {
    
    
        altfn  = (unsigned long *) (ioremap_ret +  0x24);
        *altfn &= ~(0x3 << ((gpio_src -> start - 16) * 2));
        *altfn |=  (0x1 << ((gpio_src -> start - 16) * 2));
    }
    return 0;
}
int myremove(struct platform_device *pl_rem){
    
    
    struct resource *phy_src = platform_get_resource(pl_rem,IORESOURCE_MEM,0);
    struct resource *gpio_src = platform_get_resource(pl_rem,IORESOURCE_IRQ,0);
    ioremap_ret = ioremap(phy_src ->start,0x24);
    base   = (unsigned long *) ioremap_ret;
    *base   |= (0x1 << gpio_src -> start);
    return 0;
}

struct platform_driver bl_pd = {
    
    
    .probe = myprobe,
    .remove = myremove,
    .driver = {
    
    
        .name = "LED_" //用做和硬件驱动的匹配名称
    }
};

static int btn_led_init(void){
    
    
    platform_driver_register(&bl_pd);
    return 0;
}
static void btn_led_exit(void){
    
    
    platform_driver_unregister(&bl_pd);
}
module_init(btn_led_init);
module_exit(btn_led_exit);
MODULE_LICENSE("GPL");
                                  

おすすめ

転載: blog.csdn.net/weixin_47273317/article/details/108295744