![](https://img-blog.csdnimg.cn/4f666698c7ce4d518219447023d3a33c.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
驱动开发
文章平均质量分 88
驱动开发实例
苦梨甜
嵌入式全栈ing
展开
-
pinctrl_desc结构体注册
首先,pinctrl_register_one_pin 函数用于注册单个引脚,它分配内存并初始化引脚描述符,然后将其插入到引脚描述符树中。其次,pinctrl_register_pins 函数用于注册一组引脚,它遍历引脚描述符数组并调用 pinctrl_register_one_pin 函数来逐个注册引脚。接着,函数会注册所有的引脚,调用 pinctrl_register_pins 函数进行引脚的注册。如果注册过程中发生错误,则会打印错误信息,释放已注册的引脚描述符,并跳转到错误处理标签 out_err。原创 2023-08-07 12:59:35 · 568 阅读 · 0 评论 -
pinctrl设备树节点映射详细分析imx_dt_node_to_map
这是一个名为 imx_dt_node_to_map 的函数,用于将设备树中的节点映射为引脚控制器的配置映射。以下是该函数的详细分析:首先,函数从引脚控制器设备结构体 pctldev 中获取指向 imx_pinctrl 结构体的指针 ipctl,以及指向 imx_pinctrl_soc_info 结构体的指针 info。函数查找节点 np 所属的引脚组,通过调用 imx_pinctrl_find_group_by_name 函数来查找。如果找不到组,则会打印错误信息并返回错误码 -EINVAL。原创 2023-08-07 12:57:49 · 1146 阅读 · 0 评论 -
pinctrl_desc函数操作集实现
它通过传入的引脚 ID,在 imx_pinctrl_soc_info 结构体中查找对应的寄存器配置信息,并将传入的配置值写入配置寄存器。对于每个具有配置的引脚,将配置映射的类型设置为 PIN_MAP_TYPE_CONFIGS_PIN,引脚名设置为引脚的名称,配置数组设置为引脚的配置,配置数量设置为 1。首先,函数从引脚控制器设备结构体 pctldev 中获取指向 imx_pinctrl 结构体的指针 ipctl,以及指向 imx_pinctrl_soc_info 结构体的指针 info。原创 2023-08-07 12:44:21 · 682 阅读 · 0 评论 -
pinctrl_desc函数操作集
这些函数指针定义了与引脚配置相关的操作,并提供了对引脚配置的获取、设置和调试显示功能的支持。gpio_set_direction: 由于控制器可能需要根据GPIO配置为输入或输出来进行不同的配置,因此可以实现方向选择器函数作为需要引脚复用的GPIO控制器的支持。初始化 imx_pinctrl_desc时得知函数操作集为imx_pctrl_ops,imx_pmx_ops,imx_pinconf_ops。pin_config_config_dbg_show: 调试时显示驱动程序的引脚配置参数。原创 2023-08-07 12:37:50 · 417 阅读 · 0 评论 -
pinctrl设备及其结构体
pinctrl_info 是一个指向 struct imx_pinctrl_soc_info 的指针,用于存储与设备匹配时需要使用的数据。这行代码使用 of_match_device 函数在设备树匹配数组 imx6ul_pinctrl_of_match 中查找与当前设备匹配的项。这行代码将匹配项中的 data 字段赋值给 pinctrl_info,并进行类型转换,使其指向 struct imx_pinctrl_soc_info 类型的数据。:指向引脚描述符数组的指针,描述了由该引脚控制器处理的所有引脚。原创 2023-07-24 17:46:13 · 240 阅读 · 0 评论 -
pinctrl 配置信息详解
这就是宏 MX6UL_PAD_UART1_RTS_B GPIO1_IO19 的含义,看的比较仔细的同学应该会发现并没有 conf_reg 寄存器的值,config_reg 寄存器是设置一个 PIN 的电气特性的,这么重要的寄存器怎么没有值呢?, 在 这 里 就 相 当 于 设 置IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B 寄存器为 0x5,也即是设置 UART1_RTS_B 这个 PIN 复用为GPIO1_IO19。原创 2023-07-24 17:42:27 · 510 阅读 · 0 评论 -
将虚拟机dmesg日志内容通过串口输出到windows下文件中
设置ubuntu让它从串口0输出printk信息。原创 2023-05-14 21:28:57 · 993 阅读 · 0 评论 -
内核链表分析
依此类推,每次插入的新节点都是紧挨着 header_task 表尾,而插入的第一个节点 my_first_task 排在了第一位, my_second_task 排在了第二位,可得出:先插入的节点排在前面,后插入的节点排在后面, “先进先出,后进后出” ,这不正是队列的特点吗(First in First out)!获取下一个宿主结构的地址。我们真正更关心的是包含 list_head 这个结构体字段的宿主结构体,因为只有定位到了宿主结构体的起始地址,我们才能对对宿主结构体中的其它有意义的字段进行操作。原创 2023-03-10 19:41:08 · 816 阅读 · 0 评论 -
Linux驱动操作地址(寄存器)的一些方式
让程序跳转到绝对地址是0x100000去执行。对绝对地址0x100000赋值操作。使用typedef可以更直观。原创 2023-03-08 10:14:35 · 1375 阅读 · 0 评论 -
Linux开发环境配置详细过程--正点原子阿尔法开发板
编辑->虚拟网络编辑器设置->更改设置->添加网络VMnet0并设置为桥接模式->保存后还原默认设置。上述设置后Ubuntu中会有两个网卡的信息,一个用来让Ubuntu上网,另一个用于为开发板提供网络。配置ens38网卡信息与前面虚拟网络编辑器中NAT模式的网卡信息在同一子网下。编辑虚拟机设置->添加->网络适配器->设置添加的网络适配器为NAT模式。设置开发板为sd卡启动,上电启动uboot,进入uboot命令模式。如图所示,网卡ens38让虚拟机上网,ens33为开发板提供网络。重新加载网络配置文件。原创 2023-03-06 21:46:03 · 2177 阅读 · 0 评论 -
点灯大师--IMX.6ULL阿尔法开发板点灯的步骤和五种方式
找到 GPIO1_IO03 的复用寄存器“IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03”的地址为0X020E0068,然后设置此寄存器,将 GPIO1_IO03 这个 IO 复用为 GPIO 功能,也就是 ALT5。找到 GPIO1_IO03 的配置寄存器“IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03”的地址为0X020E02F4,根据实际使用情况,配置此寄存器。某个引脚,或是某组预设的引脚,都有 8 个可选的模式(alternate (ALT)MUX_MODE)。原创 2023-03-08 10:06:17 · 1068 阅读 · 0 评论 -
用户空间与内核空间通信方式
get_user和put_user相对于copy_from_user和copy_to_user,这两个函数主要用来完成一些简单类型变量(char、int、long等)的拷贝任务,对于一些复合类型的变量,如数据结构或者数组类型,get_user和put_user函数则无法胜任:函数内部将对ptr所指向的对象长度进行检查,大部分平台只支持长度为1,2,4的变量。get_user将用户空间ptr指向的数据拷贝到内核空间的变量x中,函数如果成功则返回0,否则返回-EFAULT。原创 2023-03-06 22:04:56 · 392 阅读 · 0 评论 -
字符设备驱动编程②(cdev结构)
我们接着讲,我们使用正点原子提供的字符设备驱动的模板来进行讲解。相信大家应该都已经知道代码的意思,我们来分析函数之间的调用关系。/* 注册字符设备驱动 *//* 1 、创建设备号 */ if(newchrled.major) {/* 定义了设备号 */} else {/* 没有定义设备号 *//* 申请设备号 *//* 获取分配号的主设备号 */原创 2022-11-14 20:32:21 · 322 阅读 · 0 评论 -
字符设备驱动编程①
前面有学习过模块化编程,及其字符设备的编写,现在我们深入学习一下字符设备驱动编程,了解字符设备编程所用函数之间的调用关系。原创 2022-11-14 17:08:50 · 378 阅读 · 0 评论 -
pinctrl和gpio子系统
原始字符设备驱动,patform框架,设备树这三种方法来点亮led灯的原理都是配置gpio寄存器。但在实际开发中,需要用到的引脚非常多。都是用前面讲到的方法不显示,麻烦。实际开发中我们常用pinctrl和gpio子系统来进行GPIO驱动开发。原创 2022-11-12 12:01:46 · 678 阅读 · 0 评论 -
platform设备驱动
编写字符设备驱动基本上都要实现以下内容:1.实现入口函数xxx_init()和卸载函数xxx_exit()2.申请设备号register_chrdev(与内核有关)3.注册字符设备驱动cdev_alloc cdev_init cdev_add(与内核有关)4.利用udev/mdev机制创建设备文件(节点),class_create,device_create(与内核有关)5.硬件部分初始化io资源映射ioremap,内核提供gpio库函数(与硬件相关)原创 2022-11-11 19:34:20 · 558 阅读 · 0 评论 -
输入子系统一(输入子系统工作原理)
分析: evdev.c中evdev_connect()— 属于input handler层。总结: 如果将数据上报,最终是调用handler中events()或者event()//将input dev加入到链表input_dev_list。//找到一个没有被使用的次设备号, 从64开始, 65,66。应用程序中调用了输入子系统的代码,数据是如何传递给用户层的?1,按键/keyboard: 产生键值,实际是一个数字。input handler 层:evdev.c。// 拿到evdev,肯定要拿到缓冲区。原创 2022-11-04 17:21:23 · 823 阅读 · 0 评论 -
字符设备的编写二
上一篇文章介绍了一下字符设备编写的步骤,仅此而已,想要真正掌握字符设备编写,需要对其包含的数据结构有所掌握,这才是重要的。字符设备就暂时学习到这,后面将继续为大家分享。原创 2022-10-31 13:55:20 · 112 阅读 · 0 评论 -
字符设备的编写一
字符设备是Linux驱动中三大设备之一,字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少要实现open、close、read和write的系统调用。字符终端(/dev/console)和串口(/dev/ttyS0以及类似备)就是两个字符设备,它们能很好的说明“流”这种抽象概念。字符设备可以通过文件节点来访问,比如/dev/tty1和/dev/lp0等。原创 2022-10-31 13:17:52 · 506 阅读 · 0 评论 -
platform_get_resource=NULL内核源码分析
of_translateone返回1of_translate_address回OFBAD_ADDRofaddresstoresource返回EINVALofaddresstoresource返回EINVAL所以numreg为0,通过代码的分折,当有ranges属性的时,但是属性值为0,则不对地址进行转,所以在设备节点中添加ranges属性即可。原创 2023-05-11 20:34:39 · 1283 阅读 · 0 评论 -
device_node转换成platform_device
设备树替换了平台总线模型当中对硬件资源描述的device部分。所以设备树也是对硬件资源进行描述的文件。在平台总线模型中,device部分是用platform_device结构体来描述硬件资源的。所以内核最终会将内核认识的device_node树转换platform_device。但是并不是所有的节点都会被转换成platform_device,只有满足要求的才会转换成platform_device,原创 2023-05-11 20:32:03 · 756 阅读 · 0 评论 -
dtb展开成device_node
early_init_dt_scan函数中调用early_init_dt_scan(phys_to_virt(dt_phys)),用于扫描设备树(Device Tree)of_find_matching_node_and_match 函数通过 of_device_id 匹配表来查找指定的节点,函数原。of_property_count_elems_of_size 函数用于获取属性中元素的数量,比如 reg 属性值是一个。的内存映射,只是在采用设备树以后,大部分的驱动都使用 of_iomap 函数了。原创 2023-05-11 20:30:29 · 929 阅读 · 0 评论 -
开发中proc文件系统的简单使用
在Linux系统中, “/proc”文件系统十分有用, 它被内核用于向用户导出信息。“/proc”文件系统是一个虚拟文件系统, 通过它可以在Linux内核空间和用户空间之间进行通信。在/proc文件系统中, 我们可以将对虚拟文件的读写作为与内核中实体进行通信的一种手段, 与普通文件不同的是, 这些虚拟文件的内容都是动态创建的。“/proc”下的绝大多数文件是只读的, 以显示内核信息为主。原创 2023-05-09 13:46:18 · 1398 阅读 · 0 评论 -
Linux性能监控与调优工具
除了保证程序的正确性以外, 在项目开发中往往还关心性能和稳定性。这时候, 我们往往要对内核、应用程序或整个系统进行性能优化。在性能优化中常用的手段如下。原创 2023-05-09 13:11:49 · 790 阅读 · 0 评论 -
dump_stack分析函数调用关系实例及其实现
在内核态使用的都是 svc mode 的堆栈,那如何把不同线程的堆栈分开呢,实际上内核针对不同线程会分配不同的堆栈地址,而堆栈地址都被存在 task_struct中,这样每次线程调度时就可以把相应的地址设置给 SP 寄存器,由此实现不同内核线程堆栈的切换。kstack_end 是判断是否到达栈底的函数,一个线程堆栈大小为 THREAD_SIZE,SP 寄存器存储的是栈顶,由此可以找到对应的栈底,如果没有到堆栈底部,则每次持续打印出相关的函数调用列表。所以可知使用的是finit_module。原创 2023-05-08 15:08:48 · 1166 阅读 · 0 评论 -
Linux移植5.4版本内核:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(5.4版本内核)
nxp出厂Linux源码移植成功后的Linux源码NXP 提供的 Linux 源码肯定是可以在自己的 I.MX6ULL EVK 开发板上运行下去的,所以我们肯定是以 I.MX6ULL EVK 开发板为参考,然后将 Linux 内核移植到 I.MX6U-ALPHA 开发板上的。下载内核下载地址解压。原创 2023-04-12 18:50:30 · 1445 阅读 · 3 评论 -
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)
参考原子教程移植后依旧有错误,需要按下列内容修改设备树!!!!nxp出厂Linux源码移植成功后的Linux源码NXP 提供的 Linux 源码肯定是可以在自己的 I.MX6ULL EVK 开发板上运行下去的,所以我们肯定是以 I.MX6ULL EVK 开发板为参考,然后将 Linux 内核移植到 I.MX6U-ALPHA 开发板上的。原创 2023-04-10 19:31:28 · 1510 阅读 · 0 评论 -
uboot移植到IMX6ULL平台详细过程
I.MX6UL/ULL 内部有个以太网 MAC 外设,也就是 ENET,需要外接一个 PHY 芯片来实现网络通信功能,也就是内部 MAC+外部 PHY 芯片的方案。大家可能听过 DM9000 这个网络芯片,在一些没有内部 MAC 的 CPU 中,比如三星的 2440, 4412 等,就会采用 DM9000 来实现联网功能。DM9000 提供了一个类似 SRAM 的访问接口,主控 CPU 通过这个接口即可与DM9000 进行通信, DM9000 就是一个 MAC+PHY 芯片。原创 2023-04-07 15:23:09 · 1020 阅读 · 0 评论 -
总线驱动--SPI驱动
SPI 主机驱动就是 SOC 的 SPI 控制器驱动,类似 I2C 驱动里面的适配器驱动。 Linux 内核使用 spi_master 表示 SPI 主机驱动, spi_master 是个结构体,定义在 include/linux/spi/spi.h 文件中,内容如下:transfer 函数,和 i2c_algorithm 中的 master_xfer 函数一样,控制器数据传输函数。transfer_one_message 函数,也用于 SPI 数据发送,用于发送一个 spi_message,SPI原创 2023-04-05 21:14:48 · 934 阅读 · 0 评论 -
总线驱动---IIC驱动
Linux的I2C体系结构分为3个组成部分。(1)I2C核心I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(即Algorithm)上层的与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等,如图15.1所示。(2)I2C总线驱动I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部。I2C总线驱动主要包含I2C适配器数据结构i2c_adapter、I2C适配器的Algorithm数据结构i2c_algorithm和原创 2023-04-04 15:22:28 · 1531 阅读 · 0 评论 -
C语言中宏的一些高级用法举例
_mptr是成员 b 的首地址, 现在 减去成员 b 在结构体里面的偏移值,算出来的是不是这个结构体的首地址呀。而宏展开(函函数),是在编译时进行的,展开时是不分配内存,也没有返回值,也没有值传递。(5)宏替换只占用编译时间,不占用运行时间而函数调用占用的是运行时间(分配内存,传递参数,执行函数体)。(2) 用获取的变量类型,定义了一个指针变量 __mptr ,并且将成员变量 b 的首地址赋值给它。(1)函数调用时,先求出实参表达式的值,然后带入形参带参数的宏只进行简单的字符替换;原创 2023-04-04 14:58:06 · 1171 阅读 · 0 评论 -
通过sysfs文件系统接口来改变内核模块中的变量值(一)--通过fasync实现
下面用一个具体的例子来展示设备驱动程序如何实现fasync方法,以及应用程序如何得到来自设备驱动程序的异步通知。这个例了同时也展示了sysfs文件系统在驱动程序中的用法,以及通过Linux设各模型来创建设备节点及其他一些特性(这个看起来很简单的内核模块其实体现了设备驱动程序中一些比较重要且典型的特征)。原创 2023-03-14 19:42:16 · 210 阅读 · 0 评论 -
通过sysfs文件系统接口来改变内核模块中的变量值(二)
给出一个完整的源码来展示如何创建、初始化并向系统中添加一个对象,以及如何通过sysfs文件系统接口在用户空间和内核空间进行沟通,另一个有趣的事情是它通过/sbin/hotplug机制来通知用户空间某一个kobject状态的变化。在这个例子中,我们将用自己编译的一个应用程序取代系统的/sbin/hotplug,该应用程序会打出一些环境变量,记在/var/log/messages文件中。原创 2023-03-17 13:24:47 · 176 阅读 · 0 评论 -
交叉编译环境搭建
ARM 裸机、 Uboot 移植、 Linux 移植这些都需要在 Ubuntu 下进行编译,编译就需要编译器,交叉编译器就是:1、它肯定是一个GCC 编译器。2、这个GCC 编译器是运行在X86 架构的 PC 上的。3、这个 GCC 编译器是编译 ARM 架构代码的,也就是编译出来的可执行文件是在 ARM 芯片上运行的交叉编译器有很多种,我们使用 Linaro 出品的交叉编译器。原创 2023-03-26 12:57:33 · 2370 阅读 · 0 评论 -
按键消抖的两种方法--中断延迟工作与定时器
按键由于物理特性,按下瞬间会多次置为 1/0,俗称抖动。所以我们需要给一个合理的延时,来判断是否按下按钮,为了实现这个延时我们可以使用中断延迟工作和定时器来实现,下面是具体实现的方法。原创 2023-03-23 19:02:07 · 1798 阅读 · 1 评论