Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Core Lingsi Sinlinx A64 linux writes LED through device tree

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/03 Report--

Development platform Lingsi Sinlinx A64

Memory: 1GB storage: 4GB

Detailed parameter https://m.tb.cn/h.3wMaSKm

Development board communication group 641395230

Quanzhi A64 device tree structure

# include / / this structure is used to describe every device and every device child node in the device tree

Struct device_node {const char * name; const char * type; phandle phandle; const char * full_name; struct property * properties; / / attribute struct property * deadprops; / * removed properties * / struct device_node * parent; / / device child object, point to the device object struct device_node * child; / / device object to which it belongs, and point to the child node struct device_node * sibling / / point to the next object at the same level. Struct device_node * next; / * next device of same type * / / should point to device_type is the same object struct device_node * allnext; / * next in list of all nodes * /.}

/ / the following function is used to obtain the device nodes and device child nodes in the device tree.

Extern struct device_node * of_find_node_by_name (struct device_node * from, const char * name)

/ / find the corresponding device node by name

Static inline int of_get_child_count (const struct device_node * np)

/ / get the number of child nodes of the specified device

Extern struct device_node * of_find_node_by_path (const char * path)

/ / obtain the device node through the path, which can be used to obtain the device child node

Extern struct device_node * of_find_node_by_type (struct device_node * from, const char * type); / / obtain the device node through the specified device_type

/ / the following function is used to obtain the attributes of a device node or device child node.

Static inline int of_property_read_u32 (const struct device_node * np, const char * propname, U32 * out_value) extern int of_property_read_u32_index (const struct device_node * np, const char * propname, U32 index, U32 * out_value); extern int of_property_read_u8_array (const struct device_node * np, const char * propname, U8 * out_values, size_t sz) Extern int of_property_read_u16_array (const struct device_node * np, const char * propname, U16 * out_values, size_t sz); extern int of_property_read_u32_array (const struct device_node * np, const char * propname, U32 * out_values, size_t sz); extern int of_property_read_u64 (const struct device_node * np, const char * propname, U64 * out_value) Extern int of_property_read_string (struct device_node * np, const char * propname, const char * * out_string)

First, add nodes and modify the dtsi file.

Vim / lichee/linux-3.10/arch/arm64/boot/dts/sun50iw1p1-pinctrl.dtsi

Driver code:

# include # define MY_DEVICE_NAME "my_led_device" / / get to the node in the device tree 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); / / read the GPIO configuration number and flag if (! gpio_is_valid (gpio)) of gpios from the device tree {/ / determine whether the GPIO number is valid or not, and valid gpio_request applies to occupy the GPIO. If there is an error in the initialization process, you need to call gpio_free to release the previously applied and successful 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); //关灯 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); //关灯 printk("led on\n"); } else { gpio_direction_output(gpio, 1); //关灯 printk("led off\n"); } return 1; } static const struct file_operations my_led_fops = { //step 1 :定义file_operations结构体 .open = my_open, .write = my_write, }; //step 1 : static struct class *led_class; static struct cdev *pcdev; //定义一个cdev指针 static dev_t n_dev; //第一个设备号(包含了主和次) static int __init led_device_init(void) {//step 2 :注册 int ret = -1; pcdev = cdev_alloc();//分配cdev结构空间 if(pcdev == NULL) { printk(KERN_EMERG" cdev_alloc error\n"); ret = -ENOMEM; /* 分配失败 */ return ret; } //2. 动态申请设备号 ret = alloc_chrdev_region(&n_dev, 0 , 2, MY_DEVICE_NAME); if(ret < 0 ) { //释放前面成功的资源 kfree(pcdev); /*释放cdev结构空间 */ printk(KERN_EMERG"alloc_chrdev_region error\n"); return ret; } cdev_init(pcdev, &my_led_fops); //初始化cdev结构 /* 建立cdev和file_operations之间的连接 */ /* 或这样初始化cdev结构 pcdev->

Owner = THIS_MODULE; pcdev- > ops = & my_led_fops; * / ret = cdev_add (pcdev, n_dev, 2); / / add a driver to the kernel and register the driver if (ret < 0) {/ / release the previous successful resource unregister_chrdev_region (n_dev, 2) / * release the previously applied reconciliation number * / kfree (pcdev); / * release the cdev structure space * / printk (KERN_EMERG "alloc_chrdev_region error\ n"); return ret } / * automatically create device nodes / 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: log out / / log out cdev structure cdev_del (pcdev); / / release device number unregister_chrdev_region (n_dev, 2) / * starting device number (primary and secondary) consecutive secondary number * / / release cdev structure space 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")

Reference article: https://blog.csdn.net/jklinux/article/details/82382066

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report