wwwxxx国产_337p日本欧洲亚洲大胆张筱雨_免费在线看成人av_日本黄色不卡视频_国产精品成熟老女人_99视频一区_亚洲精品97久久中文字幕_免费精品视频在线_亚洲色图欧美视频_欧美一区二三区

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4142|回復: 0
收起左側

platform驅動模型編程總結(基于mini2440平臺的LED驅動)

[復制鏈接]
ID:60266 發表于 2014-8-18 02:24 | 顯示全部樓層 |閱讀模式
sysfs與platform的相關基礎介紹可以參考博文【 sysfs   platform總線 】。
platform模型驅動編程,需要實現platform_device(設備)與platform_driver(驅動)在platform(虛擬總線)上的注冊、匹配,相互綁定,然后再做為一個普通的字符設備進行相應的應用,總之如果編寫的是基于字符設備的platform驅動,在遵循并實現platform總線上驅動與設備的特定接口的情況下,最核心的還是字符設備的核心結構:cdev、 file_operations(他包含的操作函數接口)、dev_t(設備號)、設備文件(/dev)等,因為用platform機制編寫的字符驅動,它的本質是字符驅動。

在一般情況下,2.6內核中已經初始化并掛載了一條platform總線在sysfs文件系統中。那么我們編寫platform模型驅動時,需要完成兩個工作:1:實現platform驅動 2:實現platform設備,然而在實現這兩個工作的過程中還需要實現其他的很多小工作,在后面介紹。platform模型驅動的實現過程核心架構就很簡單,如下所示。



platform驅動模型三個對象:platform總線、platform設備、platform驅動。
platform總線對應的內核結構:struct bus_type-->它包含的最關鍵的函數:match()
platform設備對應的內核結構:struct platform_device-->注冊:platform_device_register(unregiste)
platform驅動對應的內核結構:struct platform_driver-->注冊:platform_driver_register(unregiste)


簡單介紹下platform驅動的工作過程:設備(或驅動)注冊的時候,都會引發總線調用自己的match函數來尋找目前platform總線是否掛載有與該設備(或驅動)名字匹配的驅動(或設備),如果存在則將雙方綁定;如果先注冊設備,驅動還沒有注冊,那么設備在被注冊到總線上時,將不會匹配到與自己同名的驅動,然后在驅動注冊到總線上時,因為設備已注冊,那么總線會立即匹配與綁定這時的同名的設備與驅動,再調用驅動中的probe函數等;如果是驅動先注冊,同設備驅動一樣先會匹配失敗,匹配失敗將導致它的probe函數暫不調用,而是要等到設備注冊成功并與自己匹配綁定后才會調用。




接下來講解如下實現platform驅動與設備的詳細過程。
實現platform驅動的詳細過程



1:定義驅動實例 mini2440_led_platform_driver
static struct platform_driver mini2440_led_platform_driver = {
.probe  = mini2440_led_probe,
.remove = __devexit_p(mini2440_led_remove),
.driver = {
.name = "mini2440_led_platform_device_driver",
.owner = THIS_MODULE,
}
};

2:實現驅動實例成員函數:probe  mini2440_led_probe
probe函數中要實現的功能包括:設備號的申請,字符設備內核對象cdev的定義、初始化、綁定file_operations,注冊字符設備內核對象cdev,在/dev下動態創建設備文件。
3:platform模型驅動寫字符設備仍要實現字符設備的核心結構file_operations,第一步的cdev要用到
將file_operations結構體中open、write、read等要用到的接口函數實現。
4:實現驅動實例成員函數:remove mini2440_led_remove
remove函數中要實現的功能與probe中的相反,進行相關設備與資源的注銷。
【probe與remove函數其實對應前面用非platform機制寫驅動的時候所實現的模塊加載與卸載函數,而在platform機制中,模塊的加載與卸載函數調用的是 設備或驅動的注冊函數】
5:實現驅動的加載與卸載函數:
在加載函數中,調用驅動的注冊函數,platform_driver_register(...);
在卸載函數中,調用驅動的卸載函數,platform_driver_unregister(...);
實現platform設備的詳細過程

platform設備的實現有兩種方法:
     1:最笨的一種:直接在內核源代碼里面添加相關的資源代碼,\arch\arm\mach-s3c2440\mach-mini2440.c
     2:編寫設備模塊,用insmod命令加載該設備模塊到platform總線上。
當然用第二種了,不過這兩種方法的原理與要寫的代碼都是一樣的,但是第一種不用自己注冊,因為系統初始化的時候會將mach-mini2440.c中struct platform_device *mini2440_devices[] __initdata 設備數組中包含的所有設備注冊到總線上。而第二種手動注冊,一個字活。
1:定義設備與資源實例
static struct resource mini2440_led_resource[] = {
        [0] = {
                .start = 0x56000010,
                .end   = 0x56000010 + 12,
                .flags = IORESOURCE_MEM
        },
};
static struct platform_device mini2440_platform_device_led = {
        .name           = " mini2440_led_platform_device_driver ",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(mini2440_led_resource),
        .resource       =  mini2440_led_resource ,
        .dev            = {
              .release  = mini2440_led_platform_device_release,
        },
};

2:實現設備的成員函數release  
static void mini2440_led_platform_device_release(struct device * dev)
{
    return ;
}
3:實現設備的加載與卸載函數:
在加載函數中,調用設備的注冊函數,platform_device_register(...);
在卸載函數中,調用設備的卸載函數,platform_device_unregister(...);

多個設備的同時注冊:platform_add_devices(struct platform_devices **devs,int num);
struct platform_devices **devs設備數組,num包含的設備數目

驅動與設備是否成功注冊,我們都可以在/sys/bus/platform/devices(drivers)/下查看

下面是代碼清單:
//////////////////////////////
設備模塊:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>

static void mini2440_led_platform_device_release(struct device * dev)
{
    return ;
}
static struct resource mini2440_led_resource[] = {
        [0] = {
                .start = 0x56000010,
                .end   = 0x56000010 + 12,
                .flags = IORESOURCE_MEM
        },
};
static struct platform_device mini2440_platform_device_led = {
        .name           = "mini2440_led_platform_device_driver",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(mini2440_led_resource),
        .resource       = mini2440_led_resource,
        .dev            = {
              .release  = mini2440_led_platform_device_release,
        },
};
static int __init mini2440_led_platform_device_init(void)
{
    printk("mini2440_led_platform_device add ok!\n");
return platform_device_register(&mini2440_platform_device_led);
}
static void __exit mini2440_led_platform_device_exit(void)
{
    printk("mini2440_led_platform_device remove ok!\n");
platform_device_unregister(&mini2440_platform_device_led);
}
MODULE_AUTHOR("xxxx");
MODULE_LICENSE("GPL");
module_init(mini2440_led_platform_device_init);
module_exit(mini2440_led_platform_device_exit);
//////////////////////////////
驅動模塊:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>

#define GLOBAL_LED_MAJOR  250

static unsigned int global_led_major = GLOBAL_LED_MAJOR;
static struct cdev *led_cdev = NULL;
static struct class *led_class = NULL;

static volatile unsigned long *gpfcon = NULL;
static volatile unsigned long *gpfdat = NULL;
static volatile unsigned long *gpfup = NULL;

static int mini2440_led_open(struct inode * inode,struct file * file)
{
printk("mini2440_open[kernel_space]\n");
*gpfcon &=~((0x3<<0) | (0x3<<8) |(0x3<<10) |(0x3<<12)|(0x3<<14));
*gpfcon |= (0x1<<0) | (0x1<<8) |(0x1<<10) |(0x1<<12)|(0x1<<14);
return 0;
}
static ssize_t mini2440_led_read(struct file * file,const char __user * in,size_t size,loff_t * off)
{
printk("mini2440_read[kernel_space]\n");
return 0;
}
static ssize_t mini2440_led_write(struct file * file,const char __user * in,size_t size,loff_t * off)
{
    int ret;
char ker_buf;
printk("mini2440_write[kernel_space]\n");
ret = copy_from_user(&ker_buf,in,size);
printk("ker_buf =%d\n",ker_buf);
if(ker_buf)
{
*gpfdat &=~((0x1<<4)|(0x1<<5)|(0x1<<6)|(0x1<<7));
      
*gpfdat |= (0x1<<0);
}
else
{
*gpfdat |=(0x1<<4)|(0x1<<5)|(0x1<<6)|(0x1<<7);
*gpfdat &= ~(0x1<<0);
}
return 0;
}
struct file_operations led_fops = {
.owner = THIS_MODULE,
.open  = mini2440_led_open,
.read  = mini2440_led_read,
.write = mini2440_led_write,
};
static int __devinit mini2440_led_probe(struct platform_device *pdev)
{
int ret;
int err;
dev_t devno;
struct resource *pIORESOURCE_MEM;
devno = MKDEV(global_led_major,0);
printk(KERN_ALERT"mini2440_led_probe!\n");
if (devno) {
ret = register_chrdev_region(devno,1,"mini2440_led_platfor_driver");
} else {
ret = alloc_chrdev_region(&devno,0,1,"mini2440_led_platfor_driver");
global_led_major = MAJOR(devno);
}
if (ret < 0) {
return ret;
}
led_cdev = cdev_alloc();
cdev_init(led_cdev,&led_fops);
led_cdev->owner = THIS_MODULE;
err = cdev_add(led_cdev,devno,1);
led_class = class_create(THIS_MODULE,"mini2440_led_platfor_driver");
device_create(led_class,NULL,MKDEV(global_led_major,0),NULL,"platfor_driver_for_mini2440_led");
pIORESOURCE_MEM = platform_get_resource(pdev,IORESOURCE_MEM,0);
gpfcon = ioremap(pIORESOURCE_MEM->start,pIORESOURCE_MEM->end - pIORESOURCE_MEM->start);
gpfdat = gpfcon + 1;
gpfup  = gpfcon + 2;
if (err) {
printk(KERN_NOTICE"Error %d adding led_cdev",err);
return -1;
} else {
printk(KERN_NOTICE"platform_driver_for_mini2440_led init ok!\n");
return 0;
}
}




static int __devexit mini2440_led_remove(struct platform_device *pdev)
{
    printk("mini2440_led_remove!\n");
cdev_del(led_cdev);
iounmap(gpfcon);
unregister_chrdev_region(MKDEV(global_led_major,0),1);
device_destroy(led_class, MKDEV(global_led_major,0));
class_destroy(led_class);
return 0;
}
static struct platform_driver mini2440_led_platform_driver = {
.probe  = mini2440_led_probe,
.remove = __devexit_p(mini2440_led_remove),
.driver = {
.name = "mini2440_led_platform_device_driver",
.owner = THIS_MODULE,
}
};
static int __init mini2440_led_platform_driver_init(void)
{
    printk("platform_driver_for_mini2440_led init\n");
return platform_driver_register(&mini2440_led_platform_driver);
}

static void __exit mini2440_led_platform_driver_exit(void)
{
    printk("platform_driver_for_mini2440_led exit\n");
platform_driver_unregister(&mini2440_led_platform_driver);
}
MODULE_AUTHOR("xxx");
MODULE_LICENSE("GPL");
module_param(global_led_major,int,S_IRUGO);
module_init(mini2440_led_platform_driver_init);
module_exit(mini2440_led_platform_driver_exit);
///////////////////////
Makefiel

ifneq ($(KERNELRELEASE), )
obj-m  := mini2440_led_platform_driver.o
else
KDIR := /home/tools/linux-2.6.32.2
all:
make -C $(KDIR)  M=/linux_prg/platform_driver_device_module/driver_module/  modules  modules
clean:
rm -f *.ko  *.o  *.mod.o  *.mod.c  *.symvers
endif




回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
欧美色一级片| 精品国产百合女同互慰| 国产精品九九| 国产精品免费精品自在线观看| 自拍av在线| 精品久久亚洲一级α| 91video| 91精品视频国产| 日本不卡一区| 国产精品91久久| 亚洲丝袜一区在线| 日韩欧美在线免费| www成人在线观看| 久久99伊人| 日本一区二区在线看| 中文在线а√天堂| 黄色毛片在线观看| 天天av导航| 欧洲精品乱码久久久久蜜桃| 中文字幕视频一区二区| 国精产品久拍自产在线网站| 亚洲欧美视频二区| 久久这里只有精品18| 国外成人免费视频| 国产精品69av| 欧美高清视频一区二区| 亚洲国产精品久久久久秋霞蜜臀 | 欧美精品乱码| 国产在视频一区二区三区吞精| yiren22综合网成人| 国产视频一二三| 伊人午夜电影| 四虎国产精品成人永久免费影视| 国产绿帽刺激高潮对白| 久久久午夜影院| 欧美激情精品久久久久久免费 | 天堂精品一区二区三区| 91久久久在线| 91av视频在线| 美女性感视频久久久| 国产亚洲精品久久久久久牛牛| 欧美一区二区三区视频免费 | 欧美日韩系列| 国产91视觉| 国产精品美女在线| 69久久夜色精品国产69| 欧美成人精品一区二区三区| 亚洲欧美精品伊人久久| 亚洲天堂久久| 国产成人黄色| 欧美日韩另类图片| 日韩一区免费| 99国内精品久久久久| 电影一区二区三区| 欧美极品videos大乳护士| 在线观看三级视频| 3d玉蒲团在线观看| 色呦呦久久久| h片精品在线观看| 国内在线免费视频| 2020国产在线| free性欧美| 亚洲一区资源| 四虎成人在线| av日韩在线免费观看| 小说区图片区亚洲| 日韩精品一区二区三区中文字幕| 91国拍精品国产粉嫩亚洲一区| 成人爽a毛片免费啪啪| 竹内纱里奈兽皇系列在线观看| 日本不卡1234视频| 久久野战av| 亚洲日日夜夜| caoporn成人免费视频在线| 在线日韩成人| 一区二区三区韩国免费中文网站| 自拍偷拍精品| 偷偷www综合久久久久久久| 欧美激情日韩| 久久一二三区| 国产一区二区三区免费观看| av在线播放成人| 国产肉丝袜一区二区| 国产精品你懂的在线| 夜夜精品视频一区二区 | 爱啪导航一精品导航站| 日本www视频在线观看| 色琪琪原网站亚洲香蕉| 在线影院福利| 天天影视久久综合| 欧美男人天堂| 在线日韩成人| 婷婷亚洲五月| 男女男精品网站| 国产不卡在线视频| 亚洲欧洲另类国产综合| 精品久久久精品| 欧美一区二区三区公司| 亚洲午夜精品久久久久久久久久久久 | 成人美女免费网站视频| 精品在线一区| 久久香蕉视频网站| 日韩av.com| 四虎国产精品成人免费入口| 日本系列第一页| 97人人爽人人爽人人爽| 翔田千里精品久久一区二| 奇米影视888狠狠狠| 男人午夜天堂| 久久99精品久久| 香蕉成人影院| 欧美手机视频| 国模精品一区二区| 不卡av影片| 国产精品欧美三级在线观看| 一区二区自拍| 国产成人午夜精品5599| 亚洲视频一区二区在线观看| 欧美日韩国产精品成人| 中文字幕亚洲一区在线观看 | 中文字幕色婷婷在线视频| 国产人妖ts一区二区| 好看的日韩av电影| 成人aa视频在线观看| 午夜一区二区三区在线观看| 亚洲国产精品人久久电影| 97国产精品人人爽人人做| 国产在线精品日韩| 五月婷婷狠狠操| 99成人在线观看| www.av黄色| 影视先锋午夜av| 182tv在线播放| 麻豆精品少妇| 青青国产91久久久久久| 亚洲人午夜精品天堂一二香蕉| 欧美一区二区三区免费视频| 97视频在线观看播放| 久久大片网站| 国产精品久久久久久久av福利| 妺妺窝人体色www婷婷| 天堂在线视频免费观看| 在线观看成年人视频| 欧美日韩免费看片| 影视亚洲一区二区三区| 91视频com| 91麻豆精品国产91久久久久久 | 日本综合字幕| 久久久久久久久久久久久久久久久久| 国产在线精品免费av| 激情成人中文字幕| 久久精品国产亚洲| 日本午夜精品一区二区三区| 黄色片子免费看| 不卡av电影在线| 啪啪导航网站| 超碰97免费在线| 亚洲成人精品| 久久精品免费在线观看| 亚洲黄在线观看| 不卡视频一区二区三区| 黄色一级片免费的| japanese国产在线观看| sedog在线观看| 黄毛片在线观看| 欧美黄色一区| 亚洲男人的天堂av| 久久亚洲国产精品成人av秋霞| 牛人盗摄一区二区三区视频 | 18深夜视频在线观看| 在线视频1区2区| 午夜先锋成人动漫在线| 国产福利一区二区三区在线视频| 欧洲一区二区av| 欧美一区二三区| jizzjizzxxxx| 日本欧美www| 伊人精彩视频| 国产精品17p| 9l国产精品久久久久麻豆| 日韩电影大全免费观看2023年上 | 美国欧美日韩国产在线播放| 黑人与娇小精品av专区| 97免费中文视频在线观看| 国产a级黄色大片| 国产亚洲第一页| h片在线观看视频| 免费一级欧美在线观看视频| 美国毛片一区二区| 精品免费日韩av| 欧美综合激情| 国产日韩欧美在线观看视频| 天海翼在线播放| 午夜精品成人av| 国产在线视频精品一区| 亚洲第一中文字幕在线观看| 久久久久久久久久久久久9999| 蜜桃传媒一区二区亚洲av| 欧美人与动性xxxxbbbb| www.com.cn成人| 国产一区二区0| 亚洲精品一区中文字幕乱码| 亚洲午夜激情| 一区二区三区视频免费看| free性欧美1819hd| 欧美日韩另类图片| 国产精品久久久久桃色tv| 欧美国产亚洲精品久久久8v| 欧美黄色一级片视频| 91久久精品无码一区二区| 黄色av网站在线| 黄色亚洲大片免费在线观看| 欧美丝袜自拍制服另类| 国产99视频精品免费视频36| 最新黄色av网址| 国产女呦网站| 日韩欧美视频在线播放| 五月综合激情网| 2019国产精品视频| 免费黄色国产视频| 日本wwwwww| 欧美日韩在线网站| 日韩欧美极品在线观看| 国产高清一区视频| 国产福利视频网站| 桃乃木香奈av在线| 极品中文字幕一区| 日韩美女天天操| 99在线观看视频免费| 97人妻精品一区二区三区动漫| 国产在线看片| 国产精品羞羞答答xxdd| 日韩一区二区在线视频| 日本老熟妇毛茸茸| 亚洲欧美精品日韩欧美| 成人在线精品| 亚洲综合无码一区二区| 亚洲一区二区三区成人在线视频精品| 日韩精品电影一区二区三区| 欧美最顶级a∨艳星| 亚洲国内精品| 亚洲美女av在线| 欧美 国产 小说 另类| 午夜视频在线播放| 日本免费成人| 亚洲免费观看视频| 国产精品久久久久久久久久直播| 久草视频中文在线| 亚洲搞黄视频| 国产成人aaa| 国产精品久久久久久av下载红粉| 一色道久久88加勒比一| 宅男深夜视频| 日韩电影一二三区| 最近2019中文字幕大全第二页| 奇米视频7777| 色aⅴ色av色av偷拍| 亚洲久久久久| 日韩精品视频免费专区在线播放| 九色91popny| 在线观看免费p片视频网站地址| 欧美美女在线| 日韩欧美一区二区免费| 日本精品久久久久久久久久| 四虎影视最新网站入口在线观看| 国产欧美三级电影| 4438x成人网最大色成网站| 极品粉嫩国产18尤物| 国产真乱mangent| 成人aaaa| 亚洲欧美精品伊人久久| 一级全黄裸体片| bdsm精品捆绑chinese| 青青草国产成人av片免费| 超碰97人人做人人爱少妇| 熟女丰满老熟女熟妇| 中文字幕人妻一区二区三区视频 | 爱爱爱视频网站| 五月天婷婷视频| 丝袜美腿综合| 日韩美女一区二区三区| 亚洲xxx在线观看| 色偷偷777| 日韩高清在线不卡| 欧美在线激情视频| 国产精品成人aaaa在线| 俄罗斯一级**毛片在线播放| 亚洲欧美色图小说| 一区精品在线| 国产精品视频福利一区二区| 欧美精品一线| 欧美激情国产高清| 九九九免费视频| 91超碰在线| 欧美日韩另类字幕中文| 99在线精品免费视频| 黄色动漫网站| 男人的天堂成人在线| 久久久久久久久久久免费| 美女福利视频在线观看| 色在线中文字幕| 欧美性猛交xxxx乱大交极品| 黑森林福利视频导航| 美女视频黄a视频全免费观看| 日本aⅴ免费视频一区二区三区| 国产精品久久久久久久久久| 青娱乐在线免费视频| 亚洲va欧美va人人爽成人影院| 日韩精品一区二区三区老鸭窝| 国产伦精品一区二区三区妓女下载| 在线观看一级片| 国产亚洲综合色| 中国一级黄色录像| eeuss影院在线| 国产综合色在线| 极品尤物一区二区三区| 男人的天堂va| 黄色av一区| 国产成人福利网站| 亚洲精品一区二区三区蜜桃| 久久国产精品成人免费观看的软件| 久久精品视频亚洲| 在线观看中文字幕视频| 成人看片黄a免费看视频| 精品99999| 精品女人久久久| 国产精品久久久久久久久免费高清 | 欧美日韩影院| 国产精品高潮视频| av在线免费在线观看| 日韩欧美1区| 26uuu亚洲伊人春色| 性一交一乱一透一a级| 午夜欧美精品久久久久久久| 国产精品自产拍在线观看| 日本xxxxwww| 亚洲一区久久| 国产高清自拍一区| 国产成人va亚洲电影| 国产裸体歌舞团一区二区| 亚洲国产精品123| 福利电影导航| 最新热久久免费视频| 亚欧激情乱码久久久久久久久| 色欧美激情视频在线| 在线观看一区视频| 国产精品99久久久久久白浆小说| 国产综合视频在线| 国产精品久久久久久久免费软件| 亚洲最大av在线| 91野花视频| 9人人澡人人爽人人精品| 青青在线免费观看| 黄色的视频在线免费观看| 日韩欧美a级成人黄色| 蜜臀av一区二区三区有限公司| 深夜视频一区二区| 久久精品福利视频| 国产日韩欧美中文字幕| 亚洲麻豆视频| 久久久综合亚洲91久久98| 免费看黄视频网站| 一区二区三区在线免费观看| 超级砰砰砰97免费观看最新一期| 国产美女高潮在线观看| 亚洲国产精品va在线看黑人| 日本在线播放视频| 欧美一区高清| 久久草视频在线看| 美女被人操视频在线观看| 欧美日韩一区二区在线| 国产精品免费无码| 里番精品3d一二三区| 国产成人一区三区| 2022国产麻豆剧果冻传媒剧情| 久久这里只有精品首页| 一级片视频免费观看| 成人免费看黄| 久青草国产97香蕉在线视频| 午夜av免费观看| 国产精品正在播放| 蜜臀av午夜一区二区三区 | 免费黄色成年网站| 欧美国产丝袜视频| 久久久久亚洲AV成人网人人小说| 日本成人福利| 欧美高清不卡在线| 欧美成人高清手机在线视频| 欧美激情中文字幕| 疯狂揉花蒂控制高潮h| 成人春色在线观看免费网站| 国产日韩在线看| 4kfree性满足欧美hd18| 色综合一区二区三区| 久草视频在线资源| 亚洲乱亚洲高清| 国产夫妻自拍一区| 神马久久午夜| 97国产在线视频| 色多多视频网站|