奔跑的小刺猬
欲速则不达
展开
-
从零开始之应用发开、linux应用(三、应用调试之打印错误)
使用gdb调试,可以发现一些我们理解错误的逻辑问题,一般情况下我都是使用gdb进行调试的。但有时我们的应用程序很大,我们不知道哪里出的问题,即gdb调试不知道在哪里打断点(当然也可以单步或者自己定几个断点),这个时候就需要有别的方法来找到出错的大概位置。假设我们在程序中,对为初始化的指针赋值。或者对已经释放的内存进行了使用,很容易导致段错误。这里我以一个简单的例子为例来说明。...原创 2019-05-06 21:19:40 · 1531 阅读 · 0 评论 -
从零开始之应用发开、linux应用(二、应用调试之gdb)
Linux中包含一个很强大的调试工具GDB(GNU Debuger),可以用它来调试C和C++程序。什么是GDB?GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。与Window下的IDE不同,GDB是纯命令行执行的,并没有图形界面方法。问题:既然windows下有对用户友好的图形界面的调试工具了。那么为什么我们还需要回到命令行的模式呢?如果我们是在UNIX平台...原创 2019-05-05 22:01:54 · 1920 阅读 · 0 评论 -
从零开始之应用发开、linux应用(一、应用调试之strace)
strace是个功能强大的Linux调试分析诊断工具,可用于跟踪程序执行时进程系统调用(system call)和所接收的信号,尤其是针对源码不可读或源码无法再编译的程序。 在Linux系统中,用户程序运行在一个沙箱(sandbox)里,用户进程不能直接访问计算机硬件设备。当进程需要访问硬件设备(如读取磁盘文件或接收网络数据等)时,必须由用户态模式切换至内核态模式,通过系统调用访问...原创 2019-05-02 22:15:26 · 2029 阅读 · 0 评论 -
从零开始之驱动开发、linux驱动(七十一、电容触摸屏驱动)
一、电容式触摸屏检测原理基本原理是利用充电时间检测电容大小,从而通过检测出电容值的变化来获知触摸信号。电容屏的最上层是玻璃(不会像电阻屏那样形变),核心层部分也是由ITO材料构成的,这些导电材料在屏幕里构成了人眼看不见的静电网,静电网由多行X轴电极和多列Y轴电极构成,两个电极之间会形成电容。触摸屏工作时,X轴电极发出AC交流信号,而交流信号能穿过电容,即通过Y轴能感应出该信号,当交流电穿越时电...原创 2019-05-08 22:58:28 · 7513 阅读 · 6 评论 -
从零开始之驱动开发、linux驱动(七十、4.19内核nfs挂载只读问题的延伸)
之前移植的3.16.57版本的内核,使用2018年7月的busybox自己构建的这个根文件系统。使用3.16.57版本的内核用nfs挂载,这个根文件系统是一个可读可写的内核。但后面为了学习设备树,移植了4.19版本的内核,发现文件系统成了只读的文件系统。开始是怀疑我pc上了nfs服务器那里设置的有问题,后面用3.16.57版本内核验证了发现是ok的。那么只能怀疑4....原创 2019-05-02 21:32:35 · 1108 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十九、内核调试篇--内核卡死分析)
内核卡死有很多种可能,驱动程序因为逻辑问题,出现死循环 共享资源出现死锁 系统跑飞等一般情况下,系统跑飞内核会打印Oops信息。有了Oops信息,我们就可以通过上一节的方法来推断出出错位置。而死锁或者驱动程序死循环并不会打印Oops信息。这个时候需要我们自己打印出来,出错位置的寄存器( r0 ~ r15等)信息来反推出出错位置。因为这个时候卡住的位置基本已经是...原创 2019-05-01 19:43:50 · 1461 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十八、内核调试篇--Oops解析)
什么是Oops?从语言学的角度说,Oops应该是一个拟声词。当出了点小事故,或者做了比较尴尬的事之后,你可以说"Oops",翻译成中国话就叫做“哎呦”。“哎呦,对不起,对不起,我真不是故意打碎您的杯子的”。看,Oops就是这个意思。在Linux内核开发中的Oops是什么呢?其实,它和上面的解释也没什么本质的差别,只不过说话的主角变成了Linux。当某些比较致命的问题出现时,我们的Linux...原创 2019-05-01 15:42:15 · 1595 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十七、内核调试篇--printk使用)
printk的使用我们在内核,驱动调试的时候使用的非常多比如前面在调试usb驱动的时候#include <linux/init.h>#include <linux/usb/input.h>#include <linux/hid.h>static int usb_simple_probe(struct usb_interface *intf,...原创 2019-05-01 12:25:16 · 2625 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十六、内核调试篇--printk原理)
上一节我们已经看到了console的注册,prink的基础就是console,所以本节我们主要看内核中prink的实现。/** * printk - print a kernel message * @fmt: format string * * This is printk(). It can be called from any context. We want it t...原创 2019-04-30 21:59:20 · 3436 阅读 · 1 评论 -
从零开始之驱动发开、linux驱动(六十五、内核调试篇--串口驱动)
上一节我们分析了bootoader中传过来的cmdline中的命令是如何解析并执行的。同时也是对bootloader中传过来的console进行了记录。console也就是我们所说的控制台,可以是任何常见的输出设备,比如serial,比如framebuffer,比如网口。本节主要以最常见的串口为例说明。如果有搜索过内核代码,可以看到绝大多数的console都是串口设备。所...原创 2019-04-24 00:25:57 · 1500 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十四、内核调试篇--基础知识2[console的建立])
上一节我们分析的earlay的printk知识,本节主要分析一下在内核启动后的printk的知识。主要是通过下面函数实现的after_dashes = parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, ...原创 2019-04-21 23:50:38 · 839 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十三、内核调试篇--基础知识1[earlyprintk建立过程])
我们知道,内核中使用__section设置了很多的段属性,使用段属性可以很方便的对函数调用时间分层。比如我们之前常见的subsys_initcall,就要比module_init更早的执行,因为subsys_initcall在驱动中通常是bus和class,驱动程序调用执行需要class和bus已经创建才能执行驱动函数。关于这点我之前的博文已经有过分析。https://blog....原创 2019-04-21 18:09:44 · 805 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十二、PL330 DMA控制器驱动)
pl330 dma驱动比较复杂,最近没时间研究这个的细节。这个稳定暂留,后面补上。原创 2019-04-14 20:07:51 · 946 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十一、PL330 DMA控制器)
一、DMA介绍首先简单介绍下什么是DMAC(Direct Memory Access Controller),DMAC 是一个自适应先进的微控制器总线体系的控制器,它由ARM公司设计并基于PrimeCell技术标准,DMAC提供了一个AXI接口用来执行DMA传输,以及两个APB接口用来控制这个操作,DMAC在安全模式技术下用一个APB接口执行TrustZone技术,其他操作则在非安全模式下执行...原创 2019-04-14 00:02:01 · 1863 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(六十、ARM AMBA总线介绍)
AMBA片上总线AMBA总线:AMBA总线是ARM研发的(Advanced Microcontroller Bus Architecture)提供的一种特殊的机制,可以将RISC处理器集成在其他IP芯核和外设中,它是有效连接IP核的“数字胶”,并且是ARM复用策略的重要组件。它不是芯片与外设之间的接口,而是ARM内核与芯片上其他元件进行通信的接口。2.0版本AMBA标准定义了三组总线:...原创 2019-04-12 23:09:39 · 1596 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十九、linux4.19的IIC驱动的编写和使用3)
本节不需要编写驱动,直接可以使用i2c-dev中编写号的驱动,来进行使用。也就是说这是一个完全的应用程序。程序在后面的代码仓库。这里说一下原理。正常情况下,每一个adaptor,都会在i2c_dev_init函数调用时创建一个设备在/dev/i2c-x这要求一个前提,adaptor必须在,i2c_dev_init执行之前先执行。内核的策略就是adaptor使用...原创 2019-04-08 22:11:51 · 858 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十八、linux4.19的IIC驱动的编写和使用2)
下面说的这种方式其实和前面的很相似1.在设备树文件中,设备所在的i2c总线下面定义好设备&i2c0 { status = "okay"; eeprom@50 { compatible = "atmel,24c02"; reg = <0x50>; }; };驱动只需要增加一个of_ma...原创 2019-04-08 19:48:49 · 766 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十七、linux4.19的IIC驱动的编写和使用1)
第一点,配置内核支持i2cDevice Drivers ---> I2C support ---> <*> I2C device interface [*] Autoselect pertinent helper modules I2C Hardware Bus s...原创 2019-04-06 00:35:01 · 1153 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十六、linux4.19的IIC驱动adaptor的注册)
上一节我们看到下面这函数了。/** * i2c_add_adapter - declare i2c adapter, use dynamic bus number * @adapter: the adapter to add * Context: can sleep * * This routine is used to declare an I2C adapter whe...原创 2019-04-02 00:06:15 · 936 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十五、linux4.19的IIC驱动adaptor)
前面用了8节内容已经分析了2.6.35.7内核的iic驱动,可以发现,在linux中iic驱动还是稍微有些复杂的。在linux4.19内核中,其实百分之85~90还是和2.6内核的一样的。关于4.19的i2c,我大概会用两三节来进行分析,主要还是对硬件这个设备树引入后的变化分析。唯一不同的在于,linux内核引入设备树后,驱动层和硬件相关的内容都是通过设备树文件来指定。...原创 2019-04-01 00:06:09 · 1232 阅读 · 1 评论 -
从零开始之驱动发开、linux驱动(五十四、linux2.6下的IIC总结[8])
2.6.35.7内核的iic设备已经分析完毕了。我们这里做一下总结。首先linux下注册iic设备的方式是有五种的。这里我们对每一种的注册和顺序进行简单总结。这里我们的参考资料如下Documentation/i2c/instantiating-devices第一种方式:在mach-xxxx.c文件里面指定号设备名称,地址。static struct i2c...原创 2019-03-31 18:47:08 · 572 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十三、linux下的IIC设备驱动cdev[7])
i2c-dev.c文件完全可以被看作是一个I2C设备驱动, 不过, 它实现的i2c_client是虚拟、 临时的, 主要是为了便于从用户空间操作I2C外设。 i2c-dev.c针对每个I2C适配器生成一个主设备号为89的设备文件, 实现了i2c_driver的成员函数以及文件操作接口, 因此i2c-dev.c的主体是“i2c_driver成员函数+字符设备驱动”。#define I2C_...原创 2019-03-31 15:07:25 · 514 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十二、linux下的IIC设备驱动[6])
I2C设备驱动要使用i2c_driver和i2c_client数据结构并填充i2c_driver中的成员函数。 i2c_client一般被包含在设备的私有信息结构体中, 而i2c_driver则适合被定义为全局变量并初始化。这种驱动通常是相对稳定的驱动程序,通常不需要改动。下面给出内核中已被初始化的i2c_driver。static struct i2c_driver ...原创 2019-03-31 14:22:00 · 648 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十一、linux下的IIC总线的通讯方法[5])
我们需要为特定的I2C适配器实现通信方法, 主要是实现i2c_algorithm的functionality() 函数和master_xfer() 函数。functionality() 函数非常简单, 用于返回algorithm所支持的通信协议。linux中定义了一下方法/* To determine what functionality is present */#define...原创 2019-03-31 13:07:41 · 688 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(五十、linux下的IIC适配器的注册[4])
由于I2C总线控制器通常是在内存(寄存器)上的, 所以它本身也连接在platform总线上, 要通过platform_driver和platform_device的匹配来执行。 因此尽管I2C适配器给别人提供了总线, 它自己也被认为是接在platform总线上的一个客户。 Linux的总线、 设备和驱动模型实际上是一个树形结构, 每个节点虽然可能成为别人的总线控制器, 但是自己也被认为是从上一级总...原创 2019-03-31 00:18:19 · 640 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十九、linux下的IIC核心层的接口[3])
I2C核心中的主要函数如下:(1) 增加/删除i2c_adapterint i2c_add_adapter(struct i2c_adapter *adap);void i2c_del_adapter(struct i2c_adapter *adap);增加一个adadptor/** * i2c_add_adapter - declare i2c adapter, use...原创 2019-03-30 21:22:46 · 815 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十八、linux下的IIC核心层的建立[2])
I2C核心(drivers/i2c/i2c-core.c) 中提供了一组不依赖于硬件平台的接口函数, 这个文件一般不需要被工程师修改, 但是理解其中的主要函数非常关键, 因为I2C总线驱动和设备驱动之间以I2C核心作为纽带。首先看一下i2c核心层的创建函数。static int __init i2c_init(void);static void __exit i2c_exit(v...原创 2019-03-30 12:40:05 · 768 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十七、linux下的IIC框架【1】)
I2C总线仅仅使用SCL、 SDA这两根信号线就实现了设备之间的数据交互, 极大地简化了对硬件资源和PCB板布线空间的占用。 因此, I2C总线非常广泛地应用在EEPROM、 实时钟、 小型LCD等设备与CPU的接口中。如果在裸机情况下直接操作I2C,其实很简单,只要正确把握IIC的操作时序就可以了。https://blog.csdn.net/qq_16777851/article/d...原创 2019-03-30 11:31:19 · 1159 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十六、IIC协议原理)
IIC协议是一个板级异步双向的串行协议。只使用一根数据一根时钟两根线,通常频率都不会很高,通常我们使用在几百Khz,目前最高的器件能达到Mhz级别。IIC协议的缺点:数据线只有一根既要主机传输又要从机传输,所以传输速度很慢。主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。主器件同时也负责终止一次传输。主器件的每一次启动传...原创 2019-03-28 23:39:03 · 908 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十五、DM9000网卡驱动)
这里我们肯定不是要从零开始编写网卡驱动的。因为编写网卡驱动时,需要网络基础知识,特别是网络底层的知识,目前还没学。将来我可能选择在,网络,图像视屏,或USB这个三个方向,选择一个深入钻研。这里主要对一个真实的网卡的框架进行分析,底层和物理寄存器或网络协议相关的就略过。4.19版本的内核,平台设备这边,都是用的设备树。之前开的那个设备树专栏的学习已经有了效果,下...原创 2019-03-27 23:41:10 · 1599 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十四、虚拟网卡驱动)
网卡驱动的书写格式很简单1.申请一个网卡设备结构体2.设置这个结构体,硬件相关初始化3.注册这个网卡设备参考的韦东山老师的视屏,代码如下#include <linux/module.h>#include <linux/ioport.h>#include <linux/netdevice.h>#include <lin...原创 2019-03-22 00:03:16 · 1913 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十三、移植新的4.19版本的内核)
在kernel.org下载最新版本的内核,我下载的是linux-4.19版本的因为新的内核只支持设备树方式启动,所以打算开始学习设备树。本篇博文不分析任何设备树的东西,只做移植使用。先保证内核可以启动后再开一个专栏学习设备树。同时,19年准备回西安老家换份linux驱动相关的工作,如果看到这篇文章的西安公司有相关职位空缺,可以联系我邮箱。1152016254@qq.com...原创 2019-02-13 23:08:38 · 4015 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十二、移植新的4.x的内核)
最近一段时间一直在学习USB相关的知识,刚准备在之前的3.16.57移植的内核上学习写USB相关的驱动,发现这个版本的内核是一个过度的内核。3.x的内核是开始支持ARM的设备树,研究发现3.16.57的内核上,首先默认对S5PV210没支持设备树的。但是对和S5PV210共用的exyson类的USB却更改了之前的USB的驱动,导致对于S5PV210来说USB的驱动,没法用。3.8左右的...原创 2019-01-24 22:27:55 · 2186 阅读 · 2 评论 -
从零开始之驱动发开、linux驱动(四十一、Linux中旧的时钟管理体系)
老的时钟管理和新的时钟管理并无本质的差别。这里先列出新的新的common clock framework和老的区别,后面再分析老的实现。1.老的时钟框架没有区分各种时钟类型,新的框架把时钟分成了五个不同的时钟类型,固定频率的,分频的,开关类型的,多选一类型。2.老的时钟框架需要厂商自己提供ops函数,新的时钟框架因为已经抽象出了5种时钟,所以这五种时钟的ops内核框架都已经抽象出来实现...原创 2018-11-25 19:31:33 · 641 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(四十、Linux common clock framework(5)_使用举例)
前面三节分析的3.16.57内核中,三星的驱动中,恰好S5PV210的CPU没有使用Linux common clock framework来处理clk。所以,本文采用4.9.92的内核来分析S5PV210对前面第三节中时钟注册部分的使用。对于老的时钟框架,后面章节可能会用1到2部分说明一下。 首先是根据设备树传过来来的时钟资源的寄存器地址做地址映射,后面则就是使用设备树节点做大量的时钟...原创 2018-11-25 01:08:31 · 1766 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(三十九、Linux common clock framework(4)_总结)
前面三节参考蜗窝大神的文章分析了Linux common clock framework的主要实现细节,本篇则是对前三篇从全局的一个整合说明。 common clock framework主要维护着四条链表static HLIST_HEAD(clk_root_list);static HLIST_HEAD(clk_orphan_list);static LIST_HEAD(clk...原创 2018-11-24 15:07:22 · 515 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(三十八、Linux common clock framework(3)_实现逻辑分析)
1. 前言前面两篇clock framework的分析文章,分别从clock consumer和clock provider的角度,介绍了Linux kernel怎么管理系统的clock资源,以及device driver怎么使用clock资源。本文将深入到clock framework的内部,分析相关的实现逻辑。注:本文使用的kernel版本为linux-3.16.57。虽然最新版本的k...原创 2018-11-21 20:22:43 · 866 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(三十七、linux中common clock framework[2]_provider)
因为设备树这里还没学习,所以这一节属于provider章节的完全由蜗窝大神的文章来看。我在暂时只分析一些我知道的,同时对设备树这部分的原理和知识也也会尽快学习,补充这篇文章。http://www.wowotech.net/pm_subsystem/clock_provider.html 下面就列出这几种时钟的描述 固定速率 比如晶振 门时钟 和...原创 2018-11-20 22:36:40 · 849 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(三十六、linux中common clock framework[1]_consoumer)
部分内容来自下面几位博主的文章,如有侵权,联系我删除。http://www.wowotech.net/pm_subsystem/clk_overview.htmlhttps://blog.csdn.net/cc289123557/article/details/80098586 时钟管理模块是linux系统为统一管理各硬件的时钟而实现管理框架,负责所有模块的时钟调节和电源管理。时钟...原创 2018-11-17 17:42:59 · 2060 阅读 · 0 评论 -
从零开始之驱动发开、linux驱动(三十五、利用EXPORT_SYMBOL导出符表原理)
Linux内核头文件提供了一个方便的方法用来管理符号的对模块外部的可见性,因此减少了命名空间的污染(命名空间的名称可能会与内核其他地方定义的名称冲突),并且适当信息隐藏。 如果你的模块需要输出符号给其他模块使用,应当使用下面的宏定义:EXPORT_SYMBOL(name);EXPORT_SYMBOL_GPL(name);这两个宏均用于将给定的符号导出到模块外. GPL版本的宏定义只能使...原创 2018-11-10 20:37:07 · 2539 阅读 · 0 评论