娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年01月17日(星期五)

正在發(fā)生

2019年01月17日 | 2416開發(fā)記錄八: platform驅(qū)動(dòng)之LED(字符設(shè)備)

發(fā)布者:碼字徜徉 來源: eefocus關(guān)鍵字:2416開  platform  驅(qū)動(dòng)之LED 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

上一篇介紹了platform misc驅(qū)動(dòng)的寫法。因?yàn)閙isc設(shè)備是字符設(shè)備的一種,也不需要很多的函數(shù)來注冊(cè),因此作為練手。這一篇寫一個(gè)led的字符設(shè)備驅(qū)動(dòng)。你會(huì)發(fā)現(xiàn)platform驅(qū)動(dòng)只是在字符設(shè)備驅(qū)動(dòng)上又封裝了一下而已(個(gè)人理解)。


led設(shè)備


和上一篇的led misc驅(qū)動(dòng)設(shè)備差不多,但是多了一些自己的注釋。方便以后學(xué)習(xí)。makefile文件基本一致,這里就不發(fā)了。


//my2416PlatformLedDev2.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

/* 參考arch/arm/plat-s3c24xx/devs.c */



/*1. 根據(jù)芯片手冊(cè)來獲取資源*/

static struct resource led_resource[] = {

 [0] = {

  .start = S3C2410_GPBCON,//使用2416開發(fā)板的GPB1,

  .end   = S3C2410_GPBUP,//資源的起始地址,結(jié)束地址

  .flags = IORESOURCE_MEM,//flags可以為IORESOURCE_IO, IORESOURCE_MEM, IORESOURCE_IRQ, IORESOURCE_DMA等如當(dāng)flags為IORESOURCE_MEM時(shí),start、end分別表示該platform_device占據(jù)的內(nèi)存的開始地址和結(jié)束地址;當(dāng)flags為IORESOURCE_IRQ時(shí),start、end分別表示該platform_device使用的中斷號(hào)的開始值和結(jié)束值,如果只使用了1個(gè)中斷號(hào),開始和結(jié)束值相同。

 },

 //[1] = {

 // .start = 5,

 // .end   = 5,

 // .flags = IORESOURCE_IRQ,

 //},

};


void led_release(struct device *dev)


}


/*1.構(gòu)建平臺(tái)設(shè)備結(jié)構(gòu)體,將平臺(tái)資源加入進(jìn)來,需要注意的是platform_device 實(shí)質(zhì)上是經(jīng)過處理過的設(shè)備,在platform_device結(jié)構(gòu)體中存在一個(gè)設(shè)備結(jié)構(gòu)體,與之前的設(shè)備存在差別的是引入了設(shè)備資源。這些設(shè)備資源就能實(shí)現(xiàn)對(duì)設(shè)備寄存器,中斷等資源的訪問。*/

struct platform_device led_device = {

 .name    = "myplatformled2", /* 設(shè)備名,使用名為"myplatformled2"的平臺(tái)驅(qū)動(dòng) ,注冊(cè)后,會(huì)在/sys/device/platform目錄下創(chuàng)建一個(gè)以name命名的目錄,并且創(chuàng)建軟連接到/sys/bus/platform/device下。*/

 .id    = -1,/*設(shè)備id,一般為-1,如果是-1,表示同樣名字的設(shè)備只有一個(gè)舉個(gè)簡(jiǎn)單的例子,name/id是“serial/1”則它的bus_id就是serial.1  如果name/id是“serial/0”則它的bus_id就是serial.0 ,如果它的name/id是“serial/-1”則它的bus_id就是serial。 */

 .dev = {//結(jié)構(gòu)體中內(nèi)嵌的device結(jié)構(gòu)體。

  .release = led_release,

 },

 .num_resources   = ARRAY_SIZE(led_resource),/* 設(shè)備所使用各類資源數(shù)量 */

 .resource   = led_resource,//定義平臺(tái)設(shè)備的資源

};


/*2。把我們的設(shè)備資源掛在到虛擬總線的設(shè)備連表中去,

如果沒有定義上面的struct platform_device led_device,那么需要下面的init函數(shù)*/

int led_dev_init(void)

{

 platform_device_register(&led_device); //platform設(shè)備的初注冊(cè)  

 return 0;

}

/*如果沒有定義上面的struct platform_device led_device,那么需要使用platform_device_alloc()函數(shù)分配一個(gè)platform_device結(jié)構(gòu)體,然后使用platform_device_add_resources函數(shù)添加資源,最后使用platform_device_add函數(shù)*/


/*

struct platform_device *my_buttons_dev;  


static int __init platform_dev_init(void)  

{  

    int ret;  


    my_buttons_dev = platform_device_alloc("my_buttons", -1);     

    platform_device_add_resources(my_buttons_dev,key_resource,6);//添加資源  

    ret = platform_device_add(my_buttons_dev); //platform設(shè)備的注冊(cè)  

    if(ret)  

        platform_device_put(my_buttons_dev);  

    return ret;  

}   

*/


void led_dev_exit(void)

{

 platform_device_unregister(&led_device);

}


module_init(led_dev_init);

module_exit(led_dev_exit);


MODULE_LICENSE("GPL"); 




led驅(qū)動(dòng)

//my2416PlatformLedDriver2.c

#include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

#include

#include


#define DEVICE_NAME "myleds"

#define DRIVER_NAME "myleds2"http://加載驅(qū)動(dòng)之后會(huì)在/dev/目錄下發(fā)現(xiàn)myleds2,應(yīng)用程序可以使用


#define MYLED_SIZE 0x1000//全局內(nèi)存最大4K

#define MEM_CLEAR 0x1//清零全局內(nèi)存

#define MYLED_MAJOR 250 //預(yù)設(shè)的myled的主設(shè)備號(hào)


static int myled_major = MYLED_MAJOR;


struct class *myled_class;

static struct device *myledDevice=NULL;


struct myled_dev

{

   struct cdev cdev;//cdev結(jié)構(gòu)體

   //unsigned char mem[MYLED_SIZE];//全局內(nèi)存

};

struct myled_dev *myled_devp;//設(shè)備結(jié)構(gòu)體指針



#define LED_ON 0 //根據(jù)原理圖,0點(diǎn)亮led,1熄滅led

#define LED_OFF 1

 //定義GPIO管腳

 static unsigned long led_table [] =

  {

      S3C2410_GPB(1),  //不能是S3C2410_GPB5;  因?yàn)闆]有這樣定義,可以通過#define S3C2410_GPB5 S3C2410_GPB(5)

      //S3C2410_GPF(1),

      //S3C2410_GPF(2),

      //S3C2410_GPF(3),

 };

 //設(shè)置管腳模式

 static unsigned int led_cfg_table [] =

  {

      S3C2410_GPIO_OUTPUT, //隨內(nèi)核版本中定義類型的變化,在arch/arm/mach-sc2410/include/mach/Regs-gpio.h文件中定義

      //S3C2410_GPIO_OUTPUT,

      //S3C2410_GPIO_OUTPUT,

      //S3C2410_GPIO_OUTPUT,

 };

 static int my2416_leds_ioctl(struct file* filp, unsigned int cmd,unsigned long arg)

 {

   switch(cmd)

   {

      case LED_ON:

         s3c2410_gpio_setpin(S3C2410_GPB(1), LED_ON);

         break;

      case LED_OFF:

         //s3c2410_gpio_setpin(led_table[arg], !cmd);

         s3c2410_gpio_setpin(S3C2410_GPB(1), LED_OFF);

         break;

      default:

         printk("LED control:no cmd\n");

         printk("LED control are LED_ON or LED_OFF\n");

         return(-EINVAL);

   }

   return 0;

 }


//打開函數(shù)

static int my2416_led_open(struct inode *inode, struct file *file)  

{   

   int i;

   ////這里只定義了一個(gè)io口GPB1配置GPIO

   for (i = 0; i < 1; i++)

   {

       s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);

       s3c2410_gpio_setpin(led_table[i], 0);

   }

    return 0;  

}  

 //dev_fops操作指令集

 static struct file_operations my2416Led_fops =

 {

   .owner =THIS_MODULE, 

   .open    =   my2416_led_open,  

   //.release =   s3c24xx_buttons_close,  

   //.read    =   s3c24xx_buttons_read,  

   //.poll    =   s3c24xx_buttons_poll,  

   .unlocked_ioctl = my2416_leds_ioctl,//這里必須是unlocked_ioctl而不是ioctl。

 };

 /*//第三步:混雜設(shè)備定義

 static struct miscdevice my2416Ledmisc =

  {

      .minor = MISC_DYNAMIC_MINOR,

      .name = DEVICE_NAME,//加載驅(qū)動(dòng)之后會(huì)在/dev/目錄下發(fā)現(xiàn)myleds,應(yīng)用程序可以使用

      .fops = &my2416Led_fops,

 };

*/


static void Led_setup_cdev(struct myled_dev *dev,int index)

{

    int err, devno = MKDEV(myled_major,index);

    /*初始化cdev,并將相關(guān)的文件操作添加進(jìn)來*/

    cdev_init(&dev->cdev, &my2416Led_fops);

    dev->cdev.owner = THIS_MODULE;

    //dev->cdev.ops   = &my2416Led_fops;

    /*注冊(cè)字符設(shè)備*/

    err = cdev_add(&dev->cdev, devno, 1);


    if (err)

        printk("Error %d\n", err);

    else

        printk("have finish add\n");

}

/*3。實(shí)現(xiàn)probe函數(shù)*/

static int led_probe(struct platform_device *pdev)

{

   int result;


   printk("led_probe\n");

   /*創(chuàng)建一個(gè)設(shè)備號(hào)*/

   dev_t devno=MKDEV(myled_major,0);


   /*注冊(cè)一個(gè)設(shè)備號(hào)*/

   /*如果定義了主設(shè)備號(hào)采用靜態(tài)申請(qǐng)的方式*/

   if(myled_major)

   {

      result=register_chrdev_region(devno,1,DEVICE_NAME);

   }

   else//動(dòng)態(tài)申請(qǐng)?jiān)O(shè)備號(hào)

   {

      result= alloc_chrdev_region(&devno,0,1,DEVICE_NAME);

      myled_major=MAJOR(devno);

   }

   if(result<0)

   {

      printk (DEVICE_NAME " can't register\n");  

      return result;

   }


   printk("led devno\n");



   //動(dòng)態(tài)申請(qǐng)?jiān)O(shè)備結(jié)構(gòu)體內(nèi)存

   myled_devp=kmalloc(sizeof(struct myled_dev), GFP_KERNEL);

   if(!myled_devp)//申請(qǐng)失敗

   {

      printk("kmalloc faile\n");

      result=-ENOMEM;

      goto fail_malloc;

   }

   printk("kmalloc succeed\n");

  /*清除空間*/

   memset(myled_devp,0,sizeof(struct myled_dev));


   /*創(chuàng)建一個(gè)設(shè)備*/

   Led_setup_cdev(myled_devp,0);


   //class_create和device_create函數(shù)是為了自動(dòng)在/dev下創(chuàng)建DRIVER_NAME設(shè)備文件。

   //創(chuàng)建一個(gè)類,這個(gè)類存放于sysfs下面

   myled_class=class_create(THIS_MODULE,DRIVER_NAME);

   if(IS_ERR(myled_class))

   {

    result = PTR_ERR(myled_class);

    printk("class create failed\n");

    goto class_create_fail;

   }

   //在/dev目錄下創(chuàng)建相應(yīng)的設(shè)備節(jié)點(diǎn)

   //加載驅(qū)動(dòng)之后會(huì)在/dev/目錄下發(fā)現(xiàn)myleds2,應(yīng)用程序可以使用

   myledDevice = device_create(myled_class,NULL,devno,NULL,DRIVER_NAME);


   if(IS_ERR(myledDevice))

   {

    result = PTR_ERR(myledDevice);

    printk("device_create faile\n");

    goto device_create_faile;

   }

/*

   cdev_init(&(myled_dev.cdev),&my2416Led_fops);

   myled_dev.cdev.owner = THIS_MODULE;

   ret = cdev_add(&(myled_dev.cdev),devno,1);    

   if(ret)

   {

       printk("Add device error\n");

       return ret;

   }

   printk (DEVICE_NAME " Initialized \n");

   return 0;

*/

fail_malloc:

   unregister_chrdev_region(devno,1);//釋放設(shè)備號(hào) 

class_create_fail:

   unregister_chrdev_region(MKDEV(myled_major, 0), 1);//釋放設(shè)備號(hào)  

device_create_faile:

   class_destroy(myled_class);/*注銷創(chuàng)建的設(shè)備類*/

   return result;


}


int led_remove(struct platform_device *dev)

{

   /*注銷設(shè)備*/

   device_destroy(myled_class,MKDEV(myled_major, 0));

    /*注銷創(chuàng)建的設(shè)備類*/

   class_destroy(myled_class);

    /*字符設(shè)備注銷*/

   cdev_del(&myled_devp->cdev);//注銷cdev

   kfree(myled_devp);/*釋放設(shè)備結(jié)構(gòu)體內(nèi)存*/

   unregister_chrdev_region(MKDEV(myled_major, 0), 1);//釋放設(shè)備號(hào)

   printk(DEVICE_NAME " exit\n");


   return 0;

}


/*1。平臺(tái)驅(qū)動(dòng)定義*/ 

static struct platform_driver led_driver = {

 .probe  = led_probe,     /* 平臺(tái)總線下增加一個(gè)平臺(tái)設(shè)備時(shí),調(diào)用枚舉函數(shù) */

 .remove  = led_remove,    /* 平臺(tái)總線下去掉一個(gè)平臺(tái)設(shè)備時(shí),調(diào)用remove函數(shù) */

 .driver  = {

  .name = "myplatformled2",       /* 能支持名為"myplatformled2"的平臺(tái)設(shè)備 */

  .owner = THIS_MODULE,

 },

};


/*2。注冊(cè),把我們的驅(qū)動(dòng)加入到平臺(tái)設(shè)備驅(qū)動(dòng)連表中去*/

static int led_drv_init(void)

{

   int ret;

   /*平臺(tái)驅(qū)動(dòng)注冊(cè)*/ 

   ret=platform_driver_register(&led_driver);

   return ret;

}


static void __exit led_drv_exit(void)

 {

    /*平臺(tái)驅(qū)動(dòng)注銷*/ 

    platform_driver_unregister(&led_driver);

 }


module_init(led_drv_init);

module_exit(led_drv_exit);


MODULE_LICENSE("GPL"); 



說明

具體不多說了,就是驅(qū)動(dòng)這里調(diào)用了class_create為該設(shè)備創(chuàng)建一個(gè)class,再為每個(gè)設(shè)備調(diào)用 class_device_create創(chuàng)建對(duì)應(yīng)的設(shè)備,這樣就可以在/dev目錄下看到自己的設(shè)備了。這里是myleds2,而不是myleds。為什么呢?后面再說吧。


關(guān)鍵字:2416開  platform  驅(qū)動(dòng)之LED 引用地址:2416開發(fā)記錄八: platform驅(qū)動(dòng)之LED(字符設(shè)備)

上一篇:2416開發(fā)記錄七: platform驅(qū)動(dòng)之LED(misc)
下一篇:2416開發(fā)記錄九:實(shí)現(xiàn)設(shè)備節(jié)點(diǎn)的自動(dòng)創(chuàng)建

推薦閱讀

中國儲(chǔ)能網(wǎng)訊:自2016年2月“互聯(lián)網(wǎng)+智慧能源”(能源互聯(lián)網(wǎng))的指導(dǎo)意見出臺(tái)以來,能源互聯(lián)網(wǎng)產(chǎn)業(yè)歷經(jīng)兩年的發(fā)展,其關(guān)鍵技術(shù)、商業(yè)模式、工程項(xiàng)目已經(jīng)初具規(guī)模。在時(shí)間剛剛邁入2018年之際,本文對(duì)2017年能源互聯(lián)網(wǎng)發(fā)展的亮點(diǎn)進(jìn)行總結(jié),同時(shí)淺議能源互聯(lián)網(wǎng)在2018年以及未來若干年內(nèi)的發(fā)展趨勢(shì)。 能源互聯(lián)網(wǎng) 2017年五大亮點(diǎn) 經(jīng)歷了2016年的概念推廣和...
1、LG 發(fā)布全球首款可卷曲OLED電視 LG Signature OLED TV R.去年的 CES 上,LG 首次展示 Signature OLED TV R 模型時(shí)便引發(fā)了大范圍關(guān)注和期待。從產(chǎn)品正式發(fā)布至今各方的評(píng)價(jià)來看,一年的等待并沒有落空。這款 64 英寸可卷曲的OLED 電視完全顛覆了傳統(tǒng)電視的外形,屏幕能夠根據(jù)空間自由造型,不受墻壁或線路的限制,不想看到電視時(shí)便可...
我們已經(jīng)得到了很多關(guān)于今年iPhone 12的傳聞,預(yù)計(jì)其設(shè)計(jì)采用類似于iPhone 4或當(dāng)前iPad Pro的硬朗設(shè)計(jì);后置飛行時(shí)間傳感器可改善AR性能和人像模式;支持更快的5G;內(nèi)置6 GB RAM;以及采用5nm工藝的A14處理器。 5納米制程對(duì)手機(jī)意味著什么?一項(xiàng)新分析表明,這可能意味著iPho...
高通今年將推出一款“驍龍870”旗艦芯片,其定位稍遜于驍龍888,但擁有比驍龍865更強(qiáng)勁的性能。近日,知名爆料人@數(shù)碼閑聊站曝光了驍龍870的跑分信息。驍龍870跑分曝光從跑分?jǐn)?shù)據(jù)可以看出,驍龍870的Geekbench跑分單核成績(jī)?yōu)?034、多核成績(jī)?yōu)?513,相比于驍龍865的成績(jī)高出很多,甚至直逼當(dāng)代旗艦驍龍888。消息稱,今年有將有多款搭載這款芯片的手機(jī)推出,...

史海拾趣

問答坊 | AI 解惑

arm資料

ARM應(yīng)用系統(tǒng)開發(fā)詳解——基于S3C4510B的…

查看全部問答∨

問個(gè)變壓器問題~

1。變壓器的電壓比是5:4,但是應(yīng)用時(shí)輸出電壓遠(yuǎn)遠(yuǎn)達(dá)不到這個(gè)值,實(shí)際輸出電壓比理論值要低差不多20V。比如說:我輸入個(gè)AC 220V 50Hz的電壓(量了,是正確的),輸出電壓理論值應(yīng)該為 220*0.8=196V,但實(shí)際輸出電壓才173V。整個(gè)電路電流在15mA以內(nèi) ...…

查看全部問答∨

xilinx usb 下載線

Xilinx platform cable usb(Xilinx 下載線) 1.目標(biāo)器件VCC兼容 1.5V--5V 2.可配置所有Xilinx器件 3.支持iMPACT 和ChipScope 4.支持JTAG和Slave Serial配置模式 5.目標(biāo)器件下載時(shí)鐘可選,最高可達(dá)24 MHz 6.LED狀態(tài)指示燈指示目標(biāo)器件電 ...…

查看全部問答∨

eboot中的main.c中的InitLDI_LTV350和Write_LDI_LTV350起什么作用的?

SMDK2450 FMD版的: InitDisplay里的代碼: #elif (BSP_TYPE == BSP_SMDK2450) void Delay(void) {     volatile int i;     for(i=0 ; i < 1000 ; i++)     {     } } static void InitDisplay(void) ...…

查看全部問答∨

關(guān)于USB驅(qū)動(dòng)的問題

想在PXA270板子上使用內(nèi)置USB設(shè)備,涉及驅(qū)動(dòng)結(jié)構(gòu) USBFN<--->USBD|HCD 如果我想用外接USB設(shè)備,就要涉及USB ROOT HUB的驅(qū)動(dòng), 請(qǐng)問USB ROOT HUB驅(qū)動(dòng)是在上述結(jié)構(gòu)的什么位置? USBFN里面對(duì)內(nèi)置和外置USB設(shè)備處理有沒有不同? 小弟初學(xué),表述 ...…

查看全部問答∨

簡(jiǎn)單但你卻不一定能說得通的JTAG接口

JTAG接口        1JTAG(Joint Test Action Group;聯(lián)合測(cè)試行動(dòng)小組)是一種國際標(biāo)準(zhǔn)測(cè)試協(xié)議(IEEE 1149.1兼容),主要用于芯片內(nèi)部測(cè)試。現(xiàn)在多數(shù)的高級(jí)器件都支持JTAG協(xié)議,如DSP、FPGA器件等。標(biāo)準(zhǔn)的JTAG接口是4 ...…

查看全部問答∨

瑞嵌NXPLPC11XX文件詳解

對(duì)NXPLPC11XX.H文件的解釋…

查看全部問答∨

關(guān)于STM32的JTAG口

請(qǐng)問如果把JTAG端口全部禁止后是不是就不能下載和仿真了呢? 如果JTAG口鎖定了如何解除鎖定呢?…

查看全部問答∨

f2818中sprintf()函數(shù)可用嗎?

char buff[40]; sprintf(buff, \\"%f\\", 5.252); 我想用sprintf()函數(shù)實(shí)現(xiàn)浮點(diǎn)數(shù)的顯示,程序編譯沒問題,我單步調(diào)試中發(fā)現(xiàn)buff數(shù)組的值沒有被更新!! 同時(shí)我也試了ltoa()函數(shù),也同樣不起作用!! 是不是庫函數(shù)都可用??   &nb ...…

查看全部問答∨
小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 霍邱县| 习水县| 什邡市| 襄樊市| 平潭县| 盐池县| 凤庆县| 乌拉特中旗| 韶山市| 阿克苏市| 呼玛县| 合山市| 大厂| 安丘市| 黎城县| 延寿县| 越西县| 馆陶县| 太仓市| 恩平市| 丽江市| 和政县| 碌曲县| 修文县| 卫辉市| 赤壁市| 麻城市| 徐闻县| 双城市| 玉树县| 贵定县| 綦江县| 涪陵区| 阳新县| 即墨市| 蒙城县| 离岛区| 凯里市| 揭阳市| 天全县| 咸丰县|