自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(34)
  • 收藏
  • 关注

转载 Makefile 语法学习

Makefile 语法学习① 为什么需要 Makefile高效地编译程序修改源文件或头文件,只需要重新编译牵涉到的文件,就可以重新生成 APP②Makefile语法一个简单的 Makefile 文件包含一系列的“规则”,其样式如下:目标(target)…: 依赖(prerequiries)…命令(command)`如果“依赖文件”比“目标文件”更加新,那么执行“命令”来重新生成“目标文件”。命令被执行的 2 个条件:依赖文件比目标文件新,或是 目标文件还没生成。先介绍 Makefile

2021-07-29 23:12:52 399

转载 Linux I2C总线应用编程

Linux I2C总线应用编程1-1、I2C硬件框架①在一个SOC内部,有一个或多个I2C控制器(master)②在一个I2C控制器上,可以有一个或多个I2C设备(slave)③I2C总线只需要两条线:SCL(串行时钟线)、SDA(串行数据线)④在I2C总线的SCL、SDA线上,都有上拉电阻1-2、 I2C软件框架以I2C接口的存储设备AT24C02为例:APP:①提出要求:把字符串"www.100ask.net"写入AT24C02地址16开始的地方②它是大爷,不关心底层实现的细节

2021-07-26 23:12:34 466

转载 串口使用简介

1、 串口的作用UART:通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),简称串口。①调试:移植u-boot、内核、应用程序时,主要使用串口查看打印信息②外接各种模块2、串口参数①波特率:一般选波特率都会有9600,19200,115200等选项。其实意思就是每秒传输这么多个比特位数(bit)。②起始位:先发出一个逻辑”0”的信号,表示传输数据的开始。③数据位:可以是5~8位逻辑”0”或”1”。如ASCII码(7位),扩展BCD码

2021-07-24 13:02:03 5778

转载 Linux多线程编程

Linux多线程编程1-1、为什么要使用多线程要做2件事,一件需要阻塞等待,另一件需要实时进行。①例如播放器:一边在屏幕上播放视频,一边在等待用户的按键操作。如果使用单线程的话,程序必须一会查询有无按键,一会播放视频。查询按键太久,就会导致视频播放卡顿;视频播放太久,就无法及时响应用户的操作。并且查询按键和播放视频的代码混杂在一起,代码丑陋。如果使用多线程,线程1单独处理按键,线程2单独处理播放,可以完美解决上述问题。②实际项目中例如汽车仪表的车速,车速的输入既有Pulse输入,也有CAN信

2021-07-22 22:59:59 395

转载 mmap编程

mmap编程应用程序和驱动程序之间传递数据时,可以通过 read、write 函数进行。这涉及在用户态 buffer 和内核态 buffer 之间传数据,如下图所示:应用程序不能直接读写驱动程序中的 buffer,需要在用户态 buffer 和内核态 buffer 之间进行一次数据拷贝。这种方式在数据量比较小时没什么问题;但是数据量比较大时效率就太低了。比如更新 LCD 显示时,如果每次都让 APP 传递一帧数据给内核,假设 LCD 采用 102460032bpp 的格式,一帧数据就有10246

2021-07-21 22:37:10 161

转载 中断的线程化处理

中断的线程化处理复杂、耗时的事情,尽量使用内核线程来处理。上节视频介绍的工作队列用起来挺简单,但是它有一个缺点:工作队列中有多个 work,前一个 work 没处理完会影响后面的 work。解决方法有很多种,比如干脆自己创建一个内核线程,不跟别的 work 凑在一块了。对于中断处理,还有另一种方法:threaded irq,线程化的中断处理。中断的处理仍然可以认为分为上半部、下半部。上半部用来处理紧急的事情,下半部用一个内核线程来处理,这个内核线程专用于这个中断。你可以只提供 thread_fn,

2021-07-21 22:34:15 577

转载 内核的工作队列

工作队列前面讲的定时器、下半部 tasklet,它们都是在中断上下文中执行,它们无法休眠。当要处理更复杂的事情时,往往更耗时。这些更耗时的工作放在定时器或是下半部中,会使得系统很卡;并且循环等待某件事情完成也太浪费 CPU 资源了。如果使用线程来处理这些耗时的工作,那就可以解决系统卡顿的问题:因为线程可以休眠。在内核中,我们并不需要自己去创建线程,可以使用“工作队列”(workqueue)。内核初始化工作队列是,就为它创建了内核线程。以后我们要使用“工作队列”,只需要把“工作”放入“工作队列中”

2021-07-21 22:32:04 408

转载 中断的下半部tasklet

中断分为上半部、下半部。中断的处理有几个原则:① 不能嵌套;(上半部禁止)② 越快越好。在处理当前中断时,即使发生了其他中断,其他中断也不会得到处理,所以中断的处理要越快越好。但是某些中断要做的事情稍微耗时,这时可以把中断拆分为上半部、下半部。在上半部处理紧急的事情,在上半部的处理过程中,中断是被禁止的;在下半部处理耗时的事情,在下半部的处理过程中,中断是使能的。中断下半部使用结构体 tasklet_struct 来表示,它在内核源码 include\linux\interrupt.h 中定义

2021-07-21 22:27:59 169

转载 Linux 定时器

Linux 定时器所谓定时器,就是闹钟,时间到后你就要做某些事。有 2 个要素:时间、做事,换成程序员的话就是:超时时间、函数。在内核中使用定时器很简单,涉及这些函数(参考内核源码 include\linux\timer.h):① setup_timer(timer, fn, data):设置定时器,主要是初始化 timer_list 结构体,设置其中的函数、参数。② void add_timer(struct timer_list *timer):向内核添加定时器。timer->exp

2021-07-21 19:56:45 1694

转载 阻塞与非阻塞

阻塞与非阻塞所谓阻塞,就是等待某件事情发生。比如调用 read 读取按键时,如果没有按键数据则 read 函数不会返回,它会让线程休眠等待。比如,使用 poll 时,如果传入的超时时间不为 0,这种访问方法也是阻塞的。说明小于超时时间的时候,就是休眠状态,也就是阻塞的。使用 poll 时,可以设置超时时间为 0,这样即使没有数据它也会立刻返回,这就是非阻塞方式。能不能让 read 函数既能工作于阻塞方式,也可以工作于非阻塞方式?->可以!APP 调用 open 函数时,传入 O_NONBL

2021-07-21 19:48:04 157

转载 异步通知处理

异步通知处理1、使用场景使用休眠-唤醒、POLL 机制时,都需要休眠等待某个事件发生时,它们的差别在于后者可以指定休眠的时长。如果 APP 不想休眠怎么办?也有类似的方法:驱动程序有数据时主动通知 APP,APP 收到信号后执行信息处理函数。2、使用流程驱动程序怎么通知 APP:发信号,这只有 3 个字,却可以引发很多问题:① 谁发:驱动程序发② 发什么:信号③ 发什么信号:SIGIO④ 怎么发:内核里提供有函数⑤ 发给谁:APP,APP 要把自己告诉驱动⑥ APP 收到后做什么

2021-07-20 22:43:47 267

转载 POLL机制

POLL机制1、使用场景使用休眠-唤醒的方式等待某个事件发生时,有一个缺点:等待的时间可能很久。我们可以加上一个超时时间,这时就可以使用 poll 机制。① APP 不知道驱动程序中是否有数据,可以先调用 poll 函数查询一下,poll 函数可以传入超时时间;② APP 进入内核态,调用到驱动程序的 poll 函数,如果有数据的话立刻返回;③ 如果发现没有数据时就休眠一段时间;④ 当有数据时,比如当按下按键时,驱动程序的中断服务程序被调用,它会记录数据、唤醒 APP;⑤ 一直没有数据,当超

2021-07-20 22:12:38 971

转载 环形缓冲区

环形缓冲区背景:双芯片平台开发时,数据的传递是通过SPI通信,数据的接收采用两组Buf进行储存,第一组Buf是用于接收数据,解码,校验;第二组Buf是等待第一组接收完毕后,公开使用。好处在于新旧数据区分开来,且接收的数据有拆包、校验的处理。这里没有采用这种Buf存储,只是使用了环形缓冲区来接收Buf,如下:...

2021-07-19 23:32:42 89

转载 休眠与唤醒

休眠与唤醒1、使用场景当应用程序必须等待某个事件发生,比如必须等待按键被按下时,可以使用“休眠-唤醒”机制:

2021-07-19 23:31:54 795

转载 Linux按键中断实例

Linux按键中断实例①从设备树获得 GPIOof_gpio_countof_get_gpio_flags②从 GPIO 获得中断号gpio_to_irq③申请中断request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)④中断处理函数自己编辑...

2021-07-14 22:58:45 711

转载 Linux中断

Linux 中断arm对中断的处理过程:①初始化a.设置中断源,让它可以产生中断b.设置中断控制器(可以屏蔽某个中断,优先级)c.使能中断②执行其它正常程序③产生中断:例如按下按键 -> 中断控制器 -> CPU④CPU每执行完一条指令都会检查有无中断产生⑤CPU发现中断产生,开始处理。对于不同的中断,跳去不同的地址执行程序在地址上, 只是一条跳转指令,跳去执行某个函数,中断向量③④⑤都是硬件去做的⑥这些函数做什么事情?a.保存现场(各种寄存器,push入栈)b.处

2021-07-14 22:50:18 265

转载 Linux之进程和线程的通俗易懂的解释

发现有篇文章解释的很好,适合小白,转载给大家看看。https://linus.blog.youkuaiyun.com/article/details/106435394如有侵权请告知删除~

2021-07-14 21:29:21 106

转载 pinctl和GPIO子系统

pinctl和GPIO子系统不管什么外设驱动,GPIO 驱动基本都是必须的,而 pinctrl 和 gpio 子系统又是 GPIO 驱动必须使用的。想让 pinA、B 用于 GPIO,需要设置 IOMUX 让它们连接到 GPIO 模块;想让 pinA、B 用于 I2C,需要设置 IOMUX 让它们连接到 I2C 模块。pinctrl 子系统重点是设置 PIN(有的 SOC 叫做 PAD)的复用和电气属性,如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话,那么接下来就要用到 gp

2021-07-13 19:45:25 323

原创 指针数组的问题

指针数组:本质上还是数组,只是数组的成员是指针类型的,上述的a[0]仅代表了指针数组中的第一个成员。实际上用法与普通的指针一样一般定义为: char *p[10]。数组指针:本质上是指针,代表的是指向有10个元素的数组的首地址的指针。一般定义为: char (*p)[10]数组指针指向的是一维数组,上面的例子使用的二维数组是为了验证指针++后,应该是跨过了5个成员的地址范围,指向了第二组数组b[1][5]。由上又引出了数组b[5],表示数组的首地址和数组第一个成员的首地址的问题也就是“&a

2021-07-12 23:12:37 154

转载 Linux 并发与竞争

Linux 并发与竞争值得一谈,本章与前公司裸机开发的项目中,需要考虑的共用内存的干涉的问题类似,主要针对全局变量在多个中断Level中都会进行读写操作时,需要进行排他处理。需要分析上层任务和下层任务的读写关系,决定是否需要有排他处理的操作,一般采用的排他处理是中断禁止/许可。以Cortex -A7为例,中断禁止的方式为CPSR的bit6和bit7置1。另外,需要考虑以下问题:①中断禁止的区间,是否过长,过长是否会影响到下个中断的执行,原则上禁止延迟两个中断的执行时间,若超过认为是NG。②中断禁止的L

2021-07-06 22:53:48 232

转载 platform 设备驱动

platform 设备驱动背景 : Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路,在这个思路下诞生了我们将来最常打交道的platform 设备驱动,也叫做平台设备驱动。1、Linux驱动的分离与分层①分离驱动程序占用了 Linux内核代码量的大头,如果不对驱动程序加以管理,任由重复的代码肆意增加,那么用不了多久Linux 内核的文件数量就庞大到无法接受的地步。比如I2C,会采用如下的结构:是将主机驱动和设备驱动分隔开来,在实际的驱动开发中,一般 I2C 主机

2021-07-06 22:43:08 1094

转载 添加设备树节点,驱动读取设备树信息

添加设备树节点,驱动读取设备树信息1、设备树常用 OF 操作函数①查找节点的 OF 函数设备都是以节点的形式“挂”到设备树上的,因此要想获取这个设备的其他属性信息,必须先获取到这个设备的节点。Linux 内核使用 device_node 结构体来描述一个节点。struct device_node { const char *name; /* 节点名字 */ const char *type; /* 设备类型 */ phandle phandle; const char *full_name;

2021-07-02 20:15:14 1157

转载 设备树的语法

设备树的语法1、DTS 文件布局(layout):/dts-v1/; // 表示版本/ { [property definitions] [child nodes]};2、node 的格式设备树中的基本单元,被称为“node”,其格式为:[label:] node-name[@unit-address] { [properties definitions] [child nodes]};label 是标号,可以省略。label 的作用是为了方便地引用 node,比如:

2021-06-29 22:49:54 831

转载 关于Linux设备树的概念

关于Linux设备树的概念什么是设备树?设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(DeviceTree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如CPU 数量、 内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备。在以前的 Linux 内核中 ARM 架构并没有采用设备树。在没有设备树的时候 Linux 是如何描述 ARM 架构中的板级信息呢?在 Linux 内核源码中大量的

2021-06-29 21:05:22 114

转载 Linux驱动学习-新字符设备驱动

Linux驱动学习-新字符设备驱动之前学习的是使用register_chrdev函数注册字符设备,使用unregister_dev注销字符设备,驱动模块加载成功以后还需要手动使用 mknod 命令创建设备节点。在新的字符设备驱动已经不再使用这两个函数,而是使用Linux内核推荐的新字符设备驱动API函数。1、新字符设备驱动原理①分配和释放设备号使用 register_chrdev 函数注册字符设备的时候只需要给定一个主设备号即可,但是这样会带来两个问题:①、需要我们事先确定好哪些主设备号没有使

2021-06-28 22:48:47 206

转载 Linux 驱动开发_LED寄存器

Linux 驱动开发_LED寄存器1、地址映射MMU 全称叫做 MemoryManage Unit,也就是内存管理单元。MMU 主要完成的功能如下:①、完成虚拟空间到物理空间的映射。②、内存保护,设置存储器的访问权限,设置虚拟存储空间的缓冲特性。对于 32 位的处理器来说,虚拟地址范围是 2^32=4GB如果开发板有512的RAM空间,这就是物理地址①、ioremap 函数ioremap 函 数 用 于 获 取 指 定 物 理 地 址 空 间 对 应 的 虚 拟 地 址 空 间SW_M

2021-06-24 21:45:41 135

原创 Linux驱动测试APP程序编写

Linux驱动测试APP程序编写1、open、read、write 和 close 这四个函数。①、open 函数int open(const char *pathname, int flags)pathname:要打开的设备或者文件名。flags:文件打开模式,以下三种模式必选其一:O_RDONLY 只读模式O_WRONLY 只写模式O_RDWR 读写模式返回值:如果文件打开成功的话返回文件的文件描述符。在 Ubuntu 中输入“man 2 open”即可查看 open 函数的详细内容

2021-06-23 00:08:14 459

转载 ARM Linux 驱动开发学习-入门

Linux驱动开发简介1、Linux 中的三大类驱动:字符设备驱动、块设备驱动和网络设备驱动。字符设备驱动:从最简单的点灯到 I2C、SPI、音频等都属于字符设备驱动的类型。块设备驱动:存储器设备的驱动,比如 EMMC、NAND、SD 卡和 U 盘等存储设备,因为这些存储设备的特点是以存储块为基础,因此叫做块设备。网络设备驱动:就是网络驱动,不管是有线的还是无线的,都属于网络设备驱动的范畴。一个设备可以属于多种设备驱动类型,比如 USB WIFI,其使用 USB 接口,所以属于字符设备,但是其又

2021-06-21 22:40:02 571

转载 关于linux系统移植学习的简单总结(3) - 根文件系统

3、根文件系统根文件系统简介根文件系统一般也叫做 rootfs。百度百科:根文件系统首先是内核启动时所 mount(挂载)的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。百度百科上说内核代码镜像文件保存在根文件系统中,但是我们嵌入式 Linux 并没有将内核代码镜像保存在根文件系统中,而是保存到了其他地方。比如 NAND Flash 的指定存储地址、EMMC 专用分区中。根文件系统是

2021-06-16 22:22:41 267

转载 关于linux系统移植学习的简单总结(2) - Linux Kernel

2、Linux KernelLinux 官网为 https://www.kernel.orgLinux kernel 编译#!/bin/shmake ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distcleanmake ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfigmake ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuco

2021-06-16 22:07:44 145

转载 关于linux系统移植学习的简单总结(1) -U-boot

以 U-Boot、Linux kernel 和 rootfs 这三者一起构成了一个完整的 Linux 系统。U-bootuboot 的全称是 Universal Boot Loader。Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段bootloader程序。这段bootloader程序会先初始化DDR等外设,然后将Linux内核从flash(NAND,NOR FLASH,SD,MMC 等)拷贝到 DDR 中,最后启动 Linux 内核。1&

2021-06-16 21:59:41 524

转载 U-boot 顶层Makefile 学习(2)

U-boot 顶层Makefile 学习(1)U-boot顶层Makefile9、设置目标架构,交叉编译器和配置文件在编译Uboot的时候需要设置架构和交叉编译器,例如"make ARCH=arm CRPOSS_COMPILE=arm-linux-gnueabihf-",就是用于设置ARCH和CROSS_COMPILE。Line 250 判定主机架构和命令行输入的架构是否相同,如果相同,交叉编译器设置为空。(感觉不重要,因为下面会对其进行重复赋值)。为了避免每次编译都要输入"ARCH=arm

2021-04-28 20:53:05 227

转载 U-boot 顶层Makefile 学习(1)

U-boot 顶层Makefile 学习(1) 毕业两年,一直从事MCU相关的嵌入式开发,没有涉及SOC等带操作系统的相关技术,因不满足现状,人生还长,重新学习,充实自我。Makefile可以说是学习路上的难点之一,刚开始看视频学习时,很难跟得上讲师的步伐,虽然讲的很详细,但是由于没有Makefile基础,理解较为困难。建议自主学习,思考后再看视频,能收获的更多。U-boot顶层Makefile1、版本号字面意思,分别对应版本号、补丁版本号、子版本号、附加版本号、名字。2、MAKEFLAGS

2021-04-27 19:38:12 322

原创 关于寄存器多个位赋值时的位操作

@关于寄存器多个位赋值时的位操作背景:配置NXP公司IMX6ULL的ARM PLL的倍频时,需要配置CCM_ANALOG_PLL_ARMn寄存器,如下图:其中【DIV_SELECT】6:0bit位是配置ARM PLL的主频,预计配置696MHZ,实际配置值为011 1010(计算非本章节重点,不在此处说明)。误区:CCM_ANALOG-PLL_ARM |= (0111010 <<0) ;这里虽然仅对6:0bit进行了或操作,不影响其他bit位的值,但最终达不到预期的结果。原因:

2021-03-03 21:58:40 941 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除