日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

全志linux led驱动程序,芯灵思Sinlinx A64 linux通过设备树写LED驱动(附参考代码,未测试)...

發(fā)布時間:2025/3/21 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 全志linux led驱动程序,芯灵思Sinlinx A64 linux通过设备树写LED驱动(附参考代码,未测试)... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MY_DEVICE_NAME "my_LED_device"

// 獲取到設(shè)備樹中到節(jié)點

static int gpio = -1;

int get_irqno_from_node(void)

{

struct gpio_config config;

struct device_node *np = of_find_node_by_path("/leds");

IF(np){

printk("find node ok\n");

}

else{

printk("find node failed\n");

}

gpio = of_get_named_gpio_flags(nd, "gpios", i, (enum of_gpio_flags *)&config);// 從設(shè)備樹中讀取gpios的GPIO配置編號和標志

if(!gpio_is_valid(gpio)){

//判斷該 GPIO 編號是否有效,有效gpio_request 則申請占用該 GPIO。如果初始化過程出錯,需要調(diào)用 gpio_free 來釋放之前申請過且成功的 GPIO

printk("gpio isn't valid\n");

return -1;

}

if(gpio_request(gpio, "leds") < 0)

printk("gpio request failed %d\n", gpio);

gpio_direction_output(gpio, 1); //關(guān)燈

return 0;

}

static int my_open (struct inode *node, struct file *filp)

{

if(gpio)

{

printk("open ok\n");

}

else

{

return -EINVAL;

}

return 0;

}

static ssize_t my_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)

{

unsigned char val;

copy_from_user(&val, buf, 1);

printk(" gpl_dat address? ?0x%x\n",gpl_dat);

if (val)

{

gpio_direction_output(gpio, 0); //關(guān)燈

printk("led on\n");

}

else

{

gpio_direction_output(gpio, 1); //關(guān)燈

printk("led off\n");

}

return 1;

}

static const struct file_operations my_led_fops = {

//step 1 :定義file_operations結(jié)構(gòu)體

.open = my_open,

.write = my_write,

};

//step 1 :

static struct class *led_class;

static struct cdev *pcdev;? ?? ?//定義一個cdev指針

static dev_t n_dev;? ?? ?? ?? ?//第一個設(shè)備號(包含了主和次)

static int __init led_device_init(void)

{//step 2 :注冊

int ret = -1;

pcdev = cdev_alloc();//分配cdev結(jié)構(gòu)空間

if(pcdev == NULL) {

printk(KERN_EMERG" cdev_alloc??error\n");

ret = -ENOMEM;? ?/* 分配失敗 */

return ret;

}

//2. 動態(tài)申請設(shè)備號

ret = alloc_chrdev_region(&n_dev, 0 , 2, MY_DEVICE_NAME);

if(ret < 0 ) {

//釋放前面成功的資源

kfree(pcdev);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?/*釋放cdev結(jié)構(gòu)空間 */

printk(KERN_EMERG"alloc_chrdev_region??error\n");

return ret;

}

cdev_init(pcdev, &my_led_fops);? ???//初始化cdev結(jié)構(gòu)? ?? ?? ???/* 建立cdev和file_operations之間的連接 */

/*

或這樣初始化cdev結(jié)構(gòu)

pcdev->owner = THIS_MODULE;

pcdev->ops = &my_led_fops;

*/

ret = cdev_add(pcdev, n_dev, 2) ;// 向內(nèi)核里面添加一個驅(qū)動,注冊驅(qū)動

if(ret < 0 ) {

//釋放前面成功的資源

unregister_chrdev_region(n_dev,??2);? ?? ? /*??釋放前面申請的調(diào)和號*/

kfree(pcdev);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? /* 釋放cdev結(jié)構(gòu)空間 */

printk(KERN_EMERG"alloc_chrdev_region??error\n");

return ret;

}

/*自動創(chuàng)建設(shè)備節(jié)點/dev/SinlinxA64_LED*/

led_class = class_create(THIS_MODULE, "myled");

device_create(led_class, NULL, n_dev, NULL, "SinlinxA64_LED");

get_irqno_from_node();

printk(KERN_EMERG"cdev ok\n");

return 0;

}

static void __exit led_device_exit(void)

{? ? //step 2 :注銷

//注銷cdev結(jié)構(gòu)

cdev_del(pcdev);

//釋放設(shè)備號

unregister_chrdev_region(n_dev, 2); /*起始設(shè)備號(主、次) 連續(xù)的次設(shè)備號數(shù)量*/

//釋放cdev結(jié)構(gòu)空間

kfree(pcdev);

device_destroy(led_class, n_dev);

class_destroy(led_class);

gpio_free(gpio);

printk(KERN_EMERG"cdev_del ok\n");

}

module_init(led_device_init);

module_exit(led_device_exit);

MODULE_LICENSE("GPL");

總結(jié)

以上是生活随笔為你收集整理的全志linux led驱动程序,芯灵思Sinlinx A64 linux通过设备树写LED驱动(附参考代码,未测试)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。