华清嵌入式培训
嵌入式培训
lzs_blog
嵌入式
展开
-
85.Linux--设备树(下)
上一节我们已经对设备树有了一定的了解。那么我们这次通过一些实例进行一下巩固。首先我们回忆一下整个的发展过程。一.回顾设备树发展过程任何的字符设备驱动的编写,Linux已经为我们打好了框架,我们只要像做完形填空一样填写进去就可以了。(字符设备驱动框架) 通过这个框架,我们可以很容易编写我们的驱动代码,但是,当我们用这个框架非常熟练的时候,我们就会发现虽然这个方法很简单,但是非常不容易扩展,当我们有很多很多相似设备的时候,如果我们都是按照这个框架来完成,那就要写很多遍这个流程,...原创 2020-11-06 15:27:36 · 369 阅读 · 0 评论 -
84. linux--设备树(上)
我们在编译的时候,会发现要编译一下设备树文件,那么为什么要多此一举加这个文件?这个文件有什么作用呢??一.设备树的由来(驱动框架的演进)总体来讲,产品的开发越来越简单,架构越来越复杂,开发工作量减少。原始架构依然很重要,里面的知识并没有被淘汰,只是被封装和继承了。Linux 2.6版本,封装了原始架构,更加抽象,引入了设备驱动模型(sysfs)。使做产品更省事,实现了应用程序与驱动程序的分离其实从驱动程序的演进过程我们就会发现,设备树的引入是一种必然。为什么要使用..原创 2020-11-05 14:48:14 · 679 阅读 · 1 评论 -
82.Linux--IIC总线驱动框架(上)
我们的嵌入式中,外设经常通过IIC总线进行设备连接gsenor: 重力传感器,eeprom: 存储设备等,但是在linux中基于平台总线抽象出了IIC总线模型,逻辑实现上变的复杂,但是我们在使用上就变的简单了,我们需要理解linux中的IIC总线框架。一.IIC 总线驱动框架I2C驱动有4个重要的东西,I2C总线、I2C驱动、I2C设备、I2C设备器I2C总线:维护着两个链表(I2C驱动、I2C设备),管理I2C设备和I2C驱动的匹配和删除等 I2C驱动:对应的就是I2C设备的驱动程.原创 2020-11-03 15:32:07 · 373 阅读 · 0 评论 -
linux I2C总线驱动框架
本文为转载,只为方便复习,如有侵权请联系我。1、i2c子系统软件框架 应用 ------------------------------------------ i2c driver:从设备驱动层 需要和应用层进行交互 封包数据,不知道数据是如何写入到硬件 ------------------------------------------ i2c 核心层:维护i2c 总线,包括i2c driver, i2c clie转载 2020-10-28 16:05:21 · 409 阅读 · 0 评论 -
81.linux-输入子系统实现原理
我们为什么要用输入子系统?我们为什么要分析输入子系统源码??之前的学习中我们也知道了字符设备驱动的编写方法,嵌入式系统中有很多不同类型的输入系统,触摸屏,键盘等,难道我们都要按照流程编写一遍吗?当然不是我们肯定是想把可复用的部分抽象出来,只改变差异化的东西,输入子系统就帮我们做了这个工作,并提供了API,这样的好处肯定是简化我们的工作量啊,好多的代码都可以省略掉了。但是不好之处就是在不了解输入子系统框架的情况下,代码理解上有些困难,不了解它是怎么实现的。目的:a,学会如何分析内核中子系统的代码,原创 2020-10-28 15:40:16 · 315 阅读 · 0 评论 -
80.输入子系统下--驱动多个按键
一. input dev结构体在上一节中我们通过输入子系统的方式实现了按键驱动的编写。1.input dev我们在应用层中:通过ret = read(fd, &event, sizeof(struct input_event));读到统一的数据包。在驱动中:input_event(inputdev, EV_KEY, KEY_POWER, 0); input_sync(inputdev);//上报数据结束进行数据上报。驱动的初始化中: inpu...原创 2020-09-15 16:47:11 · 1111 阅读 · 2 评论 -
79.输入子系统(上)
一. 输入子系统的引入1.为什么要使用输入子系统?在之前的学习中我们学习了平台总线,在设备驱动层中,将硬件相关易变的数据与稳定算法进行分离(device(中断/地址)和driver(操作逻辑)),例如对外设串口,gpio的操作都是一样的,只是地址不一样。在这样的分离机制上,我们很容易进行平台的迁移,比如现在我们换个板卡只需要更改对应的设备树文件就可以了。但是在之前的代码编写过程中,我们也发现了假如有多个输入设备需要驱动的时候,a, gt811 注册设备号,创建设备文件,硬件初始化,...原创 2020-09-15 11:53:02 · 374 阅读 · 0 评论 -
78.高级驱动学习方法
回顾一下之前的字符设备驱动编程: 1,实现入口函数 xxx_init()和卸载函数 xxx_exit() 2,申请设备号 register_chrdev_region (与内核相关) 3,注册字符设备驱动 cdev_alloc、cdev_init、 cdev_add (与内核相关) 4,利用udev/mdev机制创建设备文件(节点) class_create, device_create (与内核相关) 5,硬件部分初始化 io资源映射 ioremap,内核提供gpio库函数原创 2020-09-14 20:47:52 · 287 阅读 · 0 评论 -
77.平台总线
上一节我们通过代码实现了设备驱动模型,这节我们所说的平台总线就属于模型中的一种,实现思路与驱动模型是一致的。在设备驱动模型的基础上添加上了一些新的内容,已及特定的功能。一. 平台总线模型: 为什么会有平台总线: 用于平台升级:三星: 2410, 2440, 6410, s5pc100 s5pv210 4412 硬件平台升级的时候,部分的模块的控制方式,基本上是类似的 ...原创 2020-09-14 15:07:51 · 238 阅读 · 0 评论 -
76.设备驱动模型
一. 设备驱动模型由来先复习下字符设备的编写步骤1,实现入口函数 xxx_init()和卸载函数 xxx_exit()2,申请设备号 register_chrdev (与内核相关)3,利用udev/mdev机制创建设备文件(节点) class_create, device_create (与内核相关)4,硬件部分初始化 io资源映射 ioremap,内核提供gpio库函数 (与硬件相关) 注册中断(与硬件相关)5,构建 file_operation结构 (与内核相关) 6,实现操...原创 2020-09-14 11:31:40 · 434 阅读 · 0 评论 -
75.中断下半部
在之前的程序中我们在中断驱动中,使用了阻塞,非阻塞,多路复用,异步信号等,中断驱动代码也正常的使用,中断部分的知识也算是完成了,但是当我们的程序正常执行过程中,我们中断到来会打断正常执行的程序,我们的中断处理任务肯定不能执行太长时间,否则就影响任务的正常执行了,但是在有的操作中,我们在中断中的执行时间就需要很长,这个时候就需要中断下半部。一.tasklet实现tasklet模型: struct tasklet_struct { struct ...原创 2020-09-13 17:34:52 · 228 阅读 · 0 评论 -
74.异步通知在驱动中的应用
异步信号通知: 当有数据到时候,驱动会发送信号(SIGIO)给应用,就可以异步去读写数据,不用主动去读写。之前的几种方式都需要应用去主动检测状态来确认是否有事件发生。一. 异步信号的应用方法 a,应用--处理信号,主要是读写数据void catch_signale(int signo) { if(signo == SIGIO) {...原创 2020-09-13 10:32:54 · 212 阅读 · 0 评论 -
73.多路复用POLL在驱动中的应用
之前在网络的进程开发中,我们有学习过多路复用,这次我们将select,poll应用到我们的按键驱动中。主要应用于单线程,单进程中同时读取多个设备或文件的情况。具体可以复习下“42.Linux网络编程--IO多路复用”章节。一 .POLL的函数实现 函数 int poll(struct pollfd *fds, nfds_t nfds, int timeout); 参数 参数1: 表示多个文件描述符集合 ..原创 2020-09-13 08:49:11 · 226 阅读 · 0 评论 -
72.linux驱动中断--非阻塞模式和阻塞模式(下)
在上一节中我们完成了按键中断的编写,进行编译,然后在终端下装载驱动,并执行应用程序,这里功能已经实现了但是有个问题,通过ps,然后top命令查看一下资源占用情况,发现key的这个程序的资源占用非常的高。其实也不难发现,我们的应用程序一直在循环的读取,当然占用高。也侧面的说明我们的程序是有问题的。那么我们怎么降低资源的占用??也很容易想到,没数据了就休眠去,让出资源。一.通过等待队列的方法实现阻塞如上图所示,没有数据的时候就进入休眠,有数据的时候在进行唤醒,继续进行调度。说到阻塞,我们原创 2020-09-12 21:07:36 · 488 阅读 · 0 评论 -
71.linux驱动--中断(中)
上一节我们只是能够正常的触发中断,但是程序并不知道我们是按下还是抬起,并且作为字符驱动也没有最基本的open read等函数,应用层是无法操作我们的按键驱动的,那么我们在上节的基础上进行完善。一. 实现字符设备驱动的框架 1,设定一个全局的设备对象(struct key_desc) key_dev = kzalloc(sizeof(struct key_desc), GFP_KERNEL);2,申请主设备号 key_dev->dev_...原创 2020-09-10 23:19:47 · 239 阅读 · 0 评论 -
70.linux驱动--中断
在之前的单片机入门的时候也是hello world,然后led,然后按键中断。下面我们要开始中中断部分的学习。,在之前的裸机开发中,我们已经了解了中断的开发步骤,在内核中使用按键触发中断,会变的更容易一些,因为内核已经帮我们完成了很多工作,我们只需要理解整个调用及修改过程。soc中有很多的中断,我们通过中断号进行区分是哪个中断,然后写对应的中断处理函数。如何获取中断号?1, 宏定义(中断相关的头文件) IRQ_EINT...原创 2020-09-10 21:30:20 · 535 阅读 · 0 评论 -
69.ARM裸机开发--中断(补充)
一. ARM中断硬件层面:中断也属于异常的一种,我们平时开发常用的就是定时器中断,按键外部中断等。初始化过程就是要过五关斩六将,获得许可之后才能到达最后的cpu核。二.中断过程软件层面1. 中断初始化 a. 管脚初始化 b. 中断控制器初始化2.中断向量表 a.中断发生后,硬件自动跳转 b. 现场保护 c. 调用中断处理3.中断处理 a. 根据中断号做相应处理 b. 清中断标志 c. 现场恢复...原创 2020-09-08 23:32:47 · 579 阅读 · 0 评论 -
68.ARM裸机开发--USART操作(补充)
一.设备间通讯单线 双线 uart (全双工 异步) 双线 i2c (半双工 同步) 三线 spi (全双工 同步) 并行通讯 多根数据线 地址线,如内存二.串口通讯协议三. 串口内部机制四.串口编程1.初始化 管脚设置为UART模式 串口协议设置(奇偶校验为,数据位等) 串口波特率设置2.发送字符 发送状态判断 发送3.接收字符后环回 接收状...原创 2020-09-08 22:23:32 · 399 阅读 · 0 评论 -
67.ARM裸机开发--LED控制(补充)
一.ARM裸机开发步骤1. 看电路图 a. 找到我要控制的设备 b. 找到设备在CPU侧的控制管脚(如GPX2_7)2. 看芯片手册 (先看相关的中文文档,熟悉设备,再看手册) a. 搜索电路图里对应控制管脚的名称(如GPX2) b. 看目录找到对应的控制模块(如:6 General Purpose Input/Output (GPIO) Control) c. 看该模块的overview 了解该模块的大概功能 d. 看控制寄存器(REGI...原创 2020-09-08 21:37:12 · 434 阅读 · 0 评论 -
66.字符设备驱动
上一节写了一个最简单的驱动,了解了驱动编写,编译及应用的方法,那么我们linux中真正的驱动是什么样的?有哪几种驱动?一. linux驱动分类字符设备 : 以字节/字符为单位(字符流)读写的设备,数据量小,不能随机读取数据。(LCD,鼠标,LED,按键,串口等)应用层通过文件IO进行操作块设备 : 以块为单位读写的设备。(硬盘 flash SD卡)网络设备 : 用于网络通讯设备。(socket 设备)我还是更喜欢看下面的这个图,思路上更清晰。...原创 2020-09-07 21:39:42 · 473 阅读 · 1 评论 -
64.驱动开发环境搭建下
在开始驱动的开发之前,发现还是操作上有一些不方便。我们需要在linux命令行中进行操作,linux经常会休眠还要输密码还是比较麻烦的,同时windows向linux传文件也是很不方便的。此时我们通过MobaXterm软件,通过ssh的方式进行linux的控制,通过tftp进行文件的传输。一.ssh tftp服务安装通过命令发现linux@linux-virtual-machine:/mydrivers$ ssh localhostssh: connect to host localhos原创 2020-08-31 23:27:58 · 332 阅读 · 0 评论 -
65.最简单的linux驱动框架--hello word
驱动开发环境搭建好了,下面就可以开发驱动了,但是怎么开始第一个驱动呢,我们开发其他软件的时候都是习惯先编写个hello world,这个驱动我们也从这个开始最简单的驱动开始,开启驱动的大门。一.编写驱动代码 1,用什么工具去写---source insight(看代码的工具) 环境搭建\烧录镜像和工具\si_linux3.14-ori.tgz 解压到内核源码的顶层目录: ...原创 2020-08-26 23:08:12 · 475 阅读 · 0 评论 -
63.驱动开发环境搭建
在之前的学习中我们已经进行了环境的搭建,接下来我们从0到1开发驱动的角度,对环境搭建进行下复习,并且梳理下整个流程。(下面主要为学习过程笔记)1. ubuntu中配置编译环境 设置交叉工具链: tar -xvf gcc-4.6.4.tar.xz -C ~/Linux_4412/toolchain(路径自己选) 设置环境变量: vim ~/.bashrc 最后面添加(永久的方式) exp...原创 2020-08-26 21:05:11 · 366 阅读 · 0 评论 -
62.根文件系统制作
一.根文件系统基本概念1. 尽管内核是 Linux 的核心,但文件却是用户与操作系统交互所采用的主要工具,linux中一切皆文件2. 什么是根文件系统??根文件系统(root filesystem)是存放运行、维护系统所必须的各种工具软件、库文件、脚本、配置文件和其他特殊文件的地方,也可以安装各种软件包。(类似于仓库)3. 根文件系统主要目录结构: 目录 内容 /bin 可执行程序 /dev...原创 2020-08-12 23:25:55 · 367 阅读 · 0 评论 -
61.linux 第三方驱动移植
在以往的思路里,我们想要实现一个功能,要进行驱动移植,这个时候其他人正好写完了这个驱动,我们直接将第三方的驱动移植到我们的内核中就可以正常使用了,此时别人的驱动写的很完善了,我不关注里面的实现,直接用到我的系统中,这种方法叫黑盒移植。一.黑盒移植编译驱动进内核以一个灯的驱动为例,fs4412_led_drv.c1.选择驱动存放目录我们打开我们之前移植好的内核,因为它属于字符设备驱动放在drivers/char目录下,此时我们就可以直接make了吗?这层的makefile肯定是找不到这个文原创 2020-08-12 23:07:19 · 945 阅读 · 0 评论 -
60.网卡移植-设备树详细分析
上节在内核配置的时候,我们完成了对网卡驱动的移植,在菜单操作后,我们又对设备树进行了板卡相关的一些代码配置,那么那些代码是什么含义,我们又怎么根据自己的板卡进行修改呢??首先我们要知道什么是设备树,为什么要又设备树。在之前的内核版本的时候是没有设备树的,在内核源码中,存在大量对板级细节信息描述的代码,对内核而言绝大多数纯属垃圾冗余代码,我们维护的时候也不好维护。设备树通过bootloader将硬件资源传给内核,使得内核和硬件资源描述相对独立(也就是说*.dtb文件由Bootloader读入内存,原创 2020-08-12 22:59:48 · 2262 阅读 · 0 评论 -
59.linux 内核移植
这节进行一个linux内核的移植。一.内核源码的下载内核源码官网https://www.kernel.org/进入官网点击 红框 下载我们这里选用linux3.14版本,移植的思路是相同的。二.内核的配置编译1.现在我们有官方源码了,通过共享文件夹传入到linux虚拟机中。cp windows_file/linux-3.14.tar.xz ~/mytest2.Linux系统中解压 ( tar -xvf linux-3.14.tar.xz 注意不能在与w...原创 2020-08-06 00:31:15 · 339 阅读 · 0 评论 -
58.linux 内核 编译及调试
一.linux内核基本概念1. linux 内核 和 linux 操作系统的区别 linux 内核 : 通常指的是由官网下载下来的源码 编译出来的 uImage 或者 zImage 镜像 启动中包含的由 硬件抽象层、文件系统、进程调度、网络管理、驱动管理、内存管理(多任务)等功能。 通常我们使用的 linux 系统 是指: 像 Ubuntu 等操作系统。 包含linux 内核, 工具集,各种第三方库, ...原创 2020-08-03 22:34:04 · 601 阅读 · 0 评论 -
57.bootloader 学习
在说bootloader之前我们在复习一下板卡的启动流程。一.板卡启动流程(查看串口打印信息可以很好的跟踪启动过程)1. 上电启动bootloader 硬件基本初始化 自搬移到内存 搬移内核到内存 传递内核启动参数(parmer_struct 或taglist)2. 加载内核 a. 自解压内核 decompess //arch/arm/boot/compressed/head.S b. 运行内核汇编部分 head.S 入口 s...原创 2020-08-03 21:54:47 · 982 阅读 · 0 评论 -
56.Linux环境搭建--开发板端
上节完成了平台端的环境搭建,我们的开发板端也要安装相应的服务。一.首先说一下我们开发板的启动流程:bootloader 初始化硬件,然后加载内核 kernel 然后挂接根文件系统,然后启动我们的应用程序。二.当然第一步是要下载我们的bootloader,可以使用j-link等进行烧写(不同板卡烧写方式不同),一般我们使用SD卡的方式进行烧写,SD卡需要制作成启动卡,制作方法可以百度。将我们的bootloader放入SD卡中,关闭开发板电源,将拨码开关SW1调至(1000)(SD启动.原创 2020-07-01 22:48:00 · 784 阅读 · 0 评论 -
55.Linux环境搭建--软件及相关服务安装
终于到了我们的系统移植的阶段,在此过程中,我们尽可能的不深入到细节中,完成快速移植。在移植之前我们必须要先搭建好我们的环境,这样在之后的移植及开发中会快很多。一.下载安装必要的软件我们在开发linux的时候肯定有很多好用的软件来辅助我们开发,这里推荐几个个人认为比较好用的软件。1. xmind 思维导图软件linux庞大的体系,知识分支众多,在学习过程中很容易迷失,通过这个软件不断的总结知识,并且各个分支的重要程度及学习进度可以一目了然,对学习复杂的知识体系有很大的帮助。2...原创 2020-06-10 21:33:20 · 513 阅读 · 0 评论 -
54.ARM 异常处理
一.什么异常?异常我们可以笼统的理解为中断,它的范围更宽泛一点,复位啊,外部中断啊,都属于异常。都是向cpu请求打断正常的程序流程,进入特定程序的一种机制。二. ARM中的7种异常种类 优先级 异常 异常模式 描述 用途 1(最高) 复位异常(reset) SVC(特权模式) 复位电平有效时,产生复位异常,..原创 2020-05-28 23:14:07 · 521 阅读 · 0 评论 -
53.ARM汇编指令
为什么要学习汇编,这里就不说了,反正就是重要。一.常用的汇编指令二.汇编指令实例说了那么多的指令感觉蒙圈了,其实看下例子我们就知道怎么用了,我们完全可以将C语言代码,全部使用汇编来进行实现。...原创 2020-05-27 13:43:13 · 1627 阅读 · 0 评论 -
52.一文带你理解ARM程序的编译及执行过程
一.我们的的程序是如何被芯片识别的?有时我们会想,我们使用c语言或者更高级的语言写好代码,这些类似英文字母的东西芯片是怎么识别并且按照我们的想法执行的?上图是一个ARM芯片基本的硬件组成,我们的程序肯定是存放在FLASH上。我们一般的项目开发中,在启动文件中或者特定场景下为了更高的效率一般使用汇编文件,其他的逻辑实现一般使用c语言进行开发,也就是像上图一样汇编文件执行完毕后,跳到c文件中开始执行。C代码通过以下过程,生成最终的二进制机器码,存入FLASH中。(1)预处理.i文件(..原创 2020-05-27 13:20:03 · 3871 阅读 · 0 评论 -
51.Linux裸机开发--ARM基础概念及汇编环境搭建
之前学习了Linux的应用层开发,下面要开始linux的底层开发,当然最开始我们不是学习bootloader,也不是内核移植,而是开始ARM的裸机开发,那么我们老说ARM,那ARM是什么?目前比较火的,美国封锁我们的华为,ARM公司又和华为有什么关系?一.ARM基础概念详细的内容可以看一下我之前整理的博客:https://blog.csdn.net/lzs940320/article/details/90021068下面只对一些关键的知识进行一个复习总结。二.环境搭建及启动文件编写及原创 2020-05-26 16:02:10 · 906 阅读 · 0 评论 -
50.在线词典项目1--需求分析及软件框架搭建
1引言1.1编写目的经过一段时间的学习,终于要开始一个实战项目了,这个项目目的就是为了回顾之前的知识,主要用到了网络编程客户端及并发服务器的实现,父子进程,信号,sql数据库等,我们先详细理解需求然后对框架及相关进行梳理,思路清晰后,再开始编程。1.2开发环境 开发环境 版本 linux gcc工具链 LIB sqlite3 1.3项目需求基于网络编程...原创 2020-05-19 16:33:15 · 2890 阅读 · 1 评论 -
49.SQLite 数据库 编程
在嵌入式设备的开发中,sqlite数据库是非常常用的,虽然听着很高大上,但是实际开发难度不是很大,主要对它的函数要使用熟练。那么它到底是一个什么东西?一. 数据库基本概念数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合。说的好难理解,其实就是个类似excel一样的东西,方便我们增删改查数据。二. 常用的数据库大型数据库Oracle关系数据库(甲骨文产品的市场占有率高)。IBM 的DB2(第一个具备网上功能的多媒体关系数据库管理系统,跨平台性强)中型数据.原创 2020-05-14 17:59:09 · 1076 阅读 · 0 评论 -
48.Linux网络编程--Unix 域套接字
一.Unix域套接字的产生原因及特性1.产生原因:在之前的学习中我们学习了网络套接字,实现了不同主机间的进程通讯,同时为了保证数据传输的可靠性,网络套接字中增加了许多校验,应答,序列号等机制,但是假如我们想要实现本机两个进程间通讯的话,使用同样的方法行不行??当然行,但是大材小用了,本来本地进程间通讯就比较可靠,不用这么麻烦,为了提高效率,出现了Unix域套接字。2.特性UNIX域套接字用于在同一台计算机上运行的进程之间的通信。 UNIX域套接字提供流和数据报两种接口。UNIX域数据报服.原创 2020-05-13 14:51:05 · 925 阅读 · 0 评论 -
47.Linux网络编程-- 广播,组播
一 .广播编程1.前面介绍的数据包发送方式只有一个接受方,称为单播2.如果同时发给局域网中的所有主机,称为广播3.只有用户数据报(使用UDP协议)套接字才能广播4.广播地址以192.168.1.0 (255.255.255.0) 网段为例,最大的主机地址192.168.1.255代表该网段的广播地址发到该地址的数据包被所有的主机接收255.255.255.255在所有网段中都代表广播地址5.广播的发送:6.广播的接收实例:udp 客户端#inclu.原创 2020-05-13 11:10:10 · 539 阅读 · 0 评论 -
46.Linux网络编程--网络超时优化
一.超时引用必要性在网络通信中,很多操作会使得进程阻塞例如TCP套接字中的recv/accept/connectUDP套接字中的recvfrom你也不能一直阻塞着不干活啊,避免进程在没有数据时无限制地阻塞,所以引入超时检测。当设定的时间到时,进程从原操作返回继续运行。二.设置超时的三种方法:1.设置socket的属性 SO_RCVTIMEO,我们上面讲的改属性例:设置接收超时:struct timeval tout;tout.tv_sec = 5;t...原创 2020-05-13 09:58:25 · 370 阅读 · 0 评论