linux开发讲课
文章平均质量分 78
嵌入式开发1
这个作者很懒,什么都没留下…
展开
-
Linux开发讲课31---Linux开发环境下的Arm gcc交叉编译介绍
为了让这个流程变得简单,开发者们为不同的芯片开发了不同的编译器,比如针对 Arm 平台的 arm-linux-gcc,针对 mips 平台的 mips-linux-gnu-gcc,这些编译器都是基于 GCC 针对具体的架构指令集进行对应配置,所以它们在运行的时候就就会生成和该目标平台对应的可执行文件。程序最后运行的环境变了,比如你的开发板是基于 Arm 的——程序在 X86 上编辑,编译,最终运行在另一个和 X86 完全不同的架构的 Arm 芯片上。带 [] 的是可选部分。原创 2024-07-06 21:50:02 · 885 阅读 · 0 评论 -
Linux开发讲课33---线程实现与线程控制步骤简析
当信号量sem 的值大于或等于0时,该进程(或线程)具有公共资源的访问权限;这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源就被收回。由于线程共享进程的资源和地址空间,因此在对这些资源进行操作时,必须考虑到线程间资源访问的惟一性问题,这里主要介绍 POSIX 中线程同步的方法,主要有互斥锁和信号量的方式。要注意的是,由于线程共享了进程的资源和地址空间,因此,任何线程对系统资源的操作都会给其他线程带来影响,因此,多线程中的同步就是非常重要的问题了。原创 2024-07-06 22:38:05 · 764 阅读 · 0 评论 -
Linux开发讲课36--- ARM中的进程
为什么引入进程的概念? 从理论角度看,是对正在运行的程序过程的抽象; 从实现角度看,是一种数据结构,目的在于清晰地刻画动态系统的内在规律,有效管理和调度进入计算机系统主存储器运行的程序。 什么是进程? 狭义定义:进程就是一段程序的执行过程。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。 进程有怎么样的特征? 动态性:进程的实质是程序在多道程序系统中的一次原创 2024-07-12 23:31:34 · 539 阅读 · 0 评论 -
Linux开发讲课32---宏定义与volatile有何功能
(unsigned int *)0xC000A001:表示取出地址(unsigned int *)0xC000A001指向的内存空间里的内容。(unsigned int *)0xC000A001:数值0xC000A001经过(unsigned int *)强制转换成:表示地址。或 GPIOALT &= (~(0x3 << 8));等号右边:表示取出地址(unsigned int *)0xC000A001里面的值(数据)等号左边:地址(unsigned int *)0xC000A001指向的内存空间。原创 2024-07-06 21:51:38 · 549 阅读 · 0 评论 -
Linux开发讲课34---文件描述符
内核空间是虚拟地址空间的一部分,想死磕的读者请猛击《C语言内存精讲》,不想纠缠细节的读者可以这样理解:进程启动后要占用内存,其中一部分内存分配给了文件描述符表。控制块,PCB 内部有一个文件描述符表(File descriptor table),记录着当前进程所有可用的文件描述符,也即当前进程所有打开的文件。文件描述符表每个进程都有一个,打开文件表和 i-node 表整个系统只有一个,它们三者之间的关系如下图所示。通过文件描述符,可以找到文件指针,从而进入打开文件表。原创 2024-07-10 20:18:06 · 1954 阅读 · 0 评论 -
Linux开发讲课30---基于ARM体系的内核启动解析
* 禁用抢占的情况下调用cpu_idle */ cpu_startup_entry(CPUHP_ONLINE);内核启动有两种方式,压缩格式或不压缩格式,压缩模式所不同的就是其入口位于arch//boot/compressed/head.S,为与该路径下的代码主要负责执行执行前期的初始化为解压内核做准备。/*创建init进程,第一个用户空间进程我们 *需要首先生成init,以便它获得pid 1,但是 *init任务最终将要创建kthread,如果在创建 *kthreadd之前对其进行调度,则OOPS。原创 2024-07-04 21:16:19 · 1355 阅读 · 0 评论 -
Linux开发讲课35--- 文件I/O
总之,如果需要强制刷新内核缓冲区,那么在设计应用程序时就应该考虑是否可以使用大尺寸的write()缓冲区,或者调研fsync或fdatasync时谨慎行事,而不是打开文件时就使用O_sync标志。原创 2024-07-11 21:37:13 · 1790 阅读 · 0 评论 -
Linux开发讲课22---I2C读写 EEPROM 实验(含代码)
在 I2C 通讯的很多过程,都需要检测事件,当检测到某事件后才能继续下一步的操作,但有时通讯错误或者 I2C 总线被占用,我们不能无休止地等待下去,所以我们设定每个事件检测 都有等待的时间上限,若超过这个时间,我们就调用 I2C_TIMEOUT_UserCallback 函数输出调试信息(或可以自己加其它操作),并终止 I2C通讯。EEPROM 芯片中还有一个 WP 引脚,具有写保护功能,当该引脚电平为高时,禁止写入数据,当引脚为低电平时,可写入数据,我们直接接地,不使用写保护功能。原创 2024-06-29 19:33:44 · 797 阅读 · 0 评论 -
Linux开发讲课19--- SPI原理
在一主多从模式下,每个从设备都有一条独立的CS信号线,如果要和特定的从机进行通讯,可以将相应的CS(下图使用NSS表示)信号线拉低。SPI接口为收发为双全工串行方式传输,收发同步,主设备发出一位给从设备时,从设备也发出一位给主设备。SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是MOSI(主出从入)、MISO(主入从出)、SCLK(时钟)、CS(片选)。CPOL=1,空闲时为高电平。原创 2024-06-29 18:24:28 · 267 阅读 · 0 评论 -
Linux开发讲课26---PCIe
每通道数据传输速率从PCIe 5.0的32 GT/s翻番至64 GT/s,PCIe 6.0*16通道的带宽高达256 GB/s,除了带宽和效率的提升外,PCIe 6.0还具有更低的延迟,是PCIe技术的又一大飞跃。PCIe连接开始链路训练过程并进入配置阶段,在该阶段中,由于通道长度变化而导致数据中的任何偏差都能得到校准,PCIe链路的宽度、链路速率、链路翻转和链路极性也在此阶段确定。然而在某些主板设计中,尤其是那些具有长通道链路的主板,这种信号质量无法实现,可能需要另外的信号调节。原创 2024-06-29 23:31:40 · 980 阅读 · 0 评论 -
Linux开发讲课20--- QSPI
因此,QSPI 还提供了间接模式,间接模式下,需要指定每一次数据传输过程的每一个细节:如指令阶段的参数是什么,地址阶段的具体地址值是多少等,虽然复杂,但给了我们充分通过 QSPI 访问 QSPI Flash 的方法,例如,当我们希望写修改 QSPI Flash 中的数据时,就可以使用间接写模式,将数据阶段的传输方向由 QSPI Flash 到 Host 转变为 Host 到 QSPI Flash,而在直接模式下,数据阶段只能是由 QSPI Flash 到 Host。写使能和写失能,只需要指令阶段;原创 2024-06-29 18:34:48 · 958 阅读 · 0 评论 -
Linux开发讲课27---USB驱动介绍
Linux内核支持两种主要类型的USB驱动程序:USB主机(Host)驱动程序和USB设备(device)驱动。主机驱动程序控制插入其中的USB设备,而USB设备驱动程序控制该设备如何作为一个USB设备和主机通信(注重的是方式)。原创 2024-06-30 00:07:46 · 1284 阅读 · 0 评论 -
Linux开发讲课23---UART
原创 2024-06-29 19:45:00 · 77 阅读 · 0 评论 -
Linux开发讲课24---GPIO(以单片机举例)
这里需要注意的是,当GPIO工作在模拟模式下时,不论输入还是输出,都只使用到I/O引脚;当GPIO配置为输出、复用模式时会使用到输出驱动器,输出信号从输出数据寄存器或片上外设送至到输出驱动器,由输出类型寄存器配置双MOS管的工作以及输出速度寄存器配置输出控制的工作,以实现输出驱动器的驱动功能,最终通过I/O引脚输出,如图。当需要输出高电平时,P-MOS管不工作,N-MOS管关闭,引脚不输出任何电平,呈现高阻态,要想使其能够输出高电平,还需要通过外接上拉电阻的方式才能输出,输出电压就是上拉电阻的电源电压;原创 2024-06-29 20:10:54 · 697 阅读 · 0 评论 -
Linux开发讲课28---USB驱动实例
设备描述符包含了设备遵循的 USB 的版本号、设备类、设备子类、制造商、产品编号等信息,主机会通过控制传输的方式获取这个设备描述符,通过这个设备描述符就能知道当前是什么设备了。当USB设备插入系统之后,根据硬件设计的特性,会被USB主机控制器第一时间知道,然后主机控制器就会问当前插入的设备是什么设备。中断传输的经典代表是USB鼠标和USB键盘,这里说的中断不是真正硬件发出的中断,而是一种轮询机制,。USB电子扫码枪的驱动与USB键盘驱动通用,只是数据包的大小是64字节,匹配的类型也是使用键盘的类型。原创 2024-06-30 00:23:58 · 1182 阅读 · 0 评论 -
Linux开发讲课21--- I2C
若配置的方向传输位为“写数据”方向, 即第一幅图的情况, 广播完地址,接收到应答信号后, 主机开始正式向从机传输数据(DATA),数据包的大小为 8 位,主机每发送完一个字 节数据,都要等待从机的应答信号(ACK),重复这个过程,可以向从机传输 N 个数据,这个 N 没有大小限制。当主机接收到这些数据后,会产生“EV7”事件, SR1 寄存器的 RXNE 被置 1,表示接收数据寄存器非空,我们读取该寄存器后,可对 数据寄存器清空,以便接收下一次数据。(4) 发送非应答信号后,产生停止信号§,结束传输。原创 2024-06-29 19:22:15 · 872 阅读 · 0 评论 -
Linux开发讲课25---GPIO(和单片机、ARM上的引脚是一个概念?)
很多模块的功能管脚,严格意义上来讲也是IO,比如CANH,CANL,所以这里为了避免混淆,就将没有定义成模块功能管脚 的那些单片机管脚定义成General Purpose的IO了,以示区别。比如定义成SPI模块的管脚,那就按照具体芯片的规定,或者定义成MOSI, 或者定义成MISO,或者定义成SCLK,这些不是任意的。数据寄存器的每一位是和GPIO的硬件引脚对应的,而数据的传递方向是通过控制寄存器设置的,通过控制寄存器可以设 置每一位引脚的数据流向。当定义成GPIO时,可以定义成高阻,输入,或者输出。原创 2024-06-29 20:13:11 · 177 阅读 · 0 评论 -
Linux开发讲课29---Linux USB 设备驱动模型
对于控制传输、批量传输、中断传输,有 3 个同步函数可以用来直接发起传输。这些函数内部会创建、填充、提交一个 URB("usb request block"),并等待它完成或超时。使用 URB 进行传输时,它是异步方式:需要先分配、构造、提交一个 URB("usb request block"),当传输完成后,它的回调函数被调用。这个 buffer 可以是一般的 buffer,也可以是 DMA Buffer。构造好 URB 后,需要提交到 USB 系统里,才能启动传输。原创 2024-06-30 00:32:54 · 1100 阅读 · 0 评论 -
Linux开发讲课14--- CPU100%该如何处理
CPU占用率突然飙升是技术人员常遇到的一个棘手问题,它是一个与具体技术无关的普遍挑战。这个问题可以很简单,也可以相当复杂。有时候,只是一个死循环在作祟。有时候,是死锁导致的。有时候,代码中有不必要的同步块。有时候,是大量计算密集型任务在运行。有时候,是线程数过多引起的。有时候,是频繁的上下文切换。有时候,是内存不足的问题。有时候,是频繁的垃圾回收。有时候,是内存泄漏导致的。等等。导致CPU占用率飙升的问题多种多样,不同系统中的不同场景,其原因可能各不相同。原创 2024-06-26 20:53:10 · 736 阅读 · 0 评论 -
Linux开发讲课16--- 【内存管理】页表映射基础知识
Linux内核中封装了很多宏来处理页表pte_val(pte)) //pte是否存在#define pte_present(pte) (pte_isset((pte), L_PTE_PRESENT)) //present比特位#define pte_valid(pte) (pte_isset((pte), L_PTE_VALID)) //pte是否有效#define pte_write(pte) (pte_isclear((pte), L_PTE_RDONLY)) //pte是否可写。转载 2024-06-26 21:08:07 · 963 阅读 · 0 评论 -
Linux开发讲课13--- SPI、I2C、UART三种串行总线协议的区别
异步传输的实现比较容易,由于每个信息都加上了“同步”信息,因此计时的漂移不会产生大的积累,但却产生了较多的开销。在数据输出过程中,CPU把要输出的字符(并行地)送入“数据输出寄存器”,“数据输出寄存器”的内容传输到“发送移位寄存器”,然后由“发送移位寄存器”移位,把数据1位1位地送到外设。如果用通用IO口模拟SPI总线,必须要有一个输出口(SDO),一个输入口(SDI),另一个口则视实现的设备类型而定,如果要实现主从设备,则需输入输出口,若只实现主设备,则需输出口即可,若只实现从设备,则只需输入口即可。原创 2024-06-23 20:06:53 · 904 阅读 · 0 评论 -
Linux开发讲课17--- 在shell脚本中,如何将一个命令存储在一个变量中
是一个非常容易引发错误的内置命令,在没有警告用户可能存在不可预料的解析行为风险的情况下,不应推荐使用它。对于带有管道或重定向的组合命令最推荐的方式是将其封装到一个函数里,然后在需要时直接调用即可。命令时需要非常小心,因为它可以使得代码可读性较差并且容易引入安全漏洞。将一个命令保存到一个变量中,以便稍后再使用(不是命令的输出,而是命令本身)。如何将这样(带有管道/多个命令)的命令存储在变量中以供以后使用?然而,当尝试一些更复杂的东西时,它失败了。命令的坑吗,可以在评论区留言交流一下。里面命令的末尾加上分号。原创 2024-06-29 11:29:00 · 291 阅读 · 0 评论 -
Linux开发讲课12--- /proc 目录
proc 目录是一个强大的工具,可以让系统管理员、开发人员和用户深入了解系统和进程的详细信息。由于其动态和内存驻留的特性,访问 /proc 目录中的信息通常是高效且即时的。原创 2024-06-23 19:57:54 · 373 阅读 · 0 评论 -
Linux开发讲课18--- “>file 2>&1“ 和 “2>&1 >file“ 的区别
在 Bash 脚本和命令行操作中,输出重定向是一项基本且强大的功能。它允许用户控制命令的输出流,将数据从一个地方转移到另一个地方,实现更加灵活和高效的工作流程。本文旨在记录 Bash 中几种常见的输出重定向方法,包括:-.2. 基本概念文件描述符(File Descriptor, FD)是 Unix 和 Unix-like 操作系统中的基本概念,用于表示一个进程打开的文件、管道、套接字或其他输入/输出资源。每个进程都有一个文件描述符表,管理其所有打开的文件。原创 2024-06-29 12:15:02 · 1190 阅读 · 0 评论 -
Linux开发讲课11--- Linux Systemd
systemd是Linux系统的一套基本构建模块。它提供了一个系统和服务管理器,作为PID 1运行并启动系统的其余部分。systemd提供积极的并行化功能,使用套接字和D-Bus激活来启动服务,提供按需启动守护进程,使用Linux控制组跟踪进程,维护挂载和自动挂载点,并实现一个精心设计的基于事务依赖的服务控制逻辑。systemd支持SysV和LSB初始化脚本,可以替代sysvinit。原创 2024-06-23 16:34:58 · 809 阅读 · 0 评论 -
Linux开发讲课8--- linux的5种IO模型
信号驱动IO是在调用sigaction时候建立一个SIGIO的信号联系,当内核准备好数据之后再通过SIGIO信号通知线程,此fd准备就绪,当线程收到可读信号后,此时再向内核发起recvfrom读取数据的请求,因为信号驱动IO的模型下,应用线程在发出信号监控后即可返回,不会阻塞,所以一个应用线程也可以同时监控多个fd。内核收到请求后会建立一个信号联系,当数据准备就绪,内核会主动把数据从内核复制到用户空间,等所有操作都完成之后,内核会发起一个通知告诉应用。应用进程向内核发起recvfrom读取数据。原创 2024-06-21 21:18:17 · 1318 阅读 · 0 评论 -
Linux开发讲课9--- Linux的IPC机制-内存映射(Memory Mapping)
内存映射是一种将文件或其他内存区域映射到进程的虚拟地址空间的技术,它通过建立映射关系、利用系统调用和虚拟内存管理,实现了高效的数据访问。内存映射是一种强大的技术,它通过将文件内容映射到进程的虚拟地址空间,简化了文件的读写操作,提高了数据处理的效率和便捷性。虚拟内存的管理:在内存映射中,所谓的内存实际上是指虚拟内存。与虚拟内存的区别:虽然内存映射与虚拟内存都涉及到虚拟地址空间的概念,但内存映射特指将文件内容映射到内存的过程,而虚拟内存则是指操作系统用来管理物理内存和提供更大地址空间的一种技术。原创 2024-06-22 21:47:41 · 1198 阅读 · 1 评论 -
Linux开发讲课7---Linux sysfs文件系统
Sysfs通过文件和目录的方式组织信息,其中每个文件或目录对应于系统中的一个设备、驱动程序或者其他内核对象。当内核中的设备、驱动程序等对象被创建时,相应的Kobject也会被创建,然后通过Sysfs将其信息暴露给用户空间。Sysfs通常被挂载在/sys目录下,它提供了一种方便的方式,让用户空间的程序可以动态地获取和管理系统中的设备信息,而无需直接访问内核数据结构。(2)创建sysfs文件。其中attr表示将要创建的文件(属性),而show和store分别表示对应的sysfs文件在读和写操作时的回调函数。原创 2024-06-21 20:56:56 · 1235 阅读 · 0 评论 -
Linux开发讲课15--- ARM嵌入式系统为什么要做内存对齐
全局变量value.v初始值是0, 程序开多线程,对全局变量value.v进行多次~位取反操作,直觉上最后结果value.v的位结果不是全0就是全1,但是最后value.v的位结果居然是一半1一半0, 这就是由于cross cache line 操作是非原子性的,导致一个线程对value.v前半部分取反的时候,另外的线程对后半部分在另一个cache line同时取反,然后前一个线程再对另一个cache line的value.v后半部分取反,导致和直觉不一致。原创 2024-06-26 21:00:21 · 1102 阅读 · 0 评论 -
Linux开发讲课10--- Linux软中断
中断是系统用来响应硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的中断处理程序来响应设备的请求。你可能要问了,为什么要有中断呢?我可以举个生活中的例子,让你感受一下中断的魅力。比如说你订了一份外卖,但是不确定外卖什么时候送到,也没有别的方法了解外卖的进度,但是,配送员送外卖是不等人的,到了你这儿没人取的话,就直接走人了。所以你只能苦苦等着,时不时去门口看看外卖送到没,而不能干其他事情。原创 2024-06-22 21:51:06 · 956 阅读 · 0 评论 -
Linux开发讲课16--- 【内存管理】页表映射基础知识2
Linux内核的内存管理已经适配了X86的页表项,我们可以通过软件适配的办法来解决这个问题。一套页表是为了迎合ARM硬件的真实页表,另一套页表是为了迎合Linux真实的页表。对于PTE页表来说,一下子就多出了一套页表,一套页表256表项,每个表项占用4字节。历史原因:Linux最初是基于x86的体系结构设计的,因此Linux内核很多的头文件的定义都是基于x86的,特别是关于PTE页表项里面的很多比特位的定义。这一套方案的话,相当于每个PGD页表项有8字节,包含指向两套PTE页表项的entry。原创 2024-06-26 21:09:46 · 269 阅读 · 0 评论 -
Linux开发讲课3---第一个驱动程序
编写一个最简单的驱动原创 2024-06-03 20:23:53 · 318 阅读 · 0 评论 -
Linux开发讲课4---Linux设备驱动简介
1-编写 Linux 设备驱动要求工程师具有良好的硬件基础,懂得 SRAM、Flash、 SDRAM、磁盘的读写方式,UART、I2C、USB 等设备的接口,轮询、中断、 DMA 的原理,PCI 总线的工作方式以及 CPU 的内存管理单元(MMU)等。3-编写 Linux 设备驱动要求工程师具有一定的 Linux 内核基础,虽然并不要求 工程师对内核各个部分有深入的研究,但至少要了解设备驱动与内核的接 口,尤其是对于块设备、网络设备、Flash 设备、串口设备等复杂设备。原创 2024-06-04 20:54:09 · 826 阅读 · 0 评论 -
Linux开发讲课5---Linux内核模块简介
模块许可证(LICENSE)声明描述内核模块的许可权限,如果不声明 LICENSE, 模块被加载时,将收到内核被污染 (kernel tainted)的警告。内核模块中用于输出的函数是内核空间的printk(),而非用户空间的print(),printk()和print()用法相似,但前者可定义输出级别。当通过 insmod 或 modprobe 命令加载内核模块时,模块的加载函数会自动被内核 执行,完成本模块的相关初始化工作。模块参数是模块被加载的时候可以被传递给它的值,它本身对应模块内部的全局 变量。原创 2024-06-05 20:52:09 · 1229 阅读 · 0 评论 -
Linux开发讲课6---Linux 文件系统与设备文件系统
主设备号是与驱动对应的概念,同一类设备一般使用相同的主设备号,不同类的 设备一般使用不同的主设备号(但是也不排除在同一主设备号下包含有一定差异的设 备)。需要注意 的是,LANANA 给出的设备号标准并不是硬性规定,在具体的设备驱动程序中,尽 管一般会遵循 LANANA,但是也可以有例外。第五位表示其 他人的权限。Linux 系统中虚拟文件系统、磁盘文件(存放于 RamDisk、Flash、 ROM、SD 卡、U 盘等文件系统中的文件也属于磁盘文件)及一般的设备文件与设备 驱动程序之间的关系。原创 2024-06-06 20:41:28 · 902 阅读 · 0 评论 -
Linux开发讲课2---shell脚本的用法和编写讲解
( 2 ) 永 久 性 修 改 - - - 》 在配 置 文 件 : v i m / . b a s h r c - - - 》 e x p o r t P A T H = 当 前 该 文 件 的 绝 对 路 径 : PATH 当换个终端就不会识别!第三: \转义: 转义字符: \t \b \n ----》 会去掉紧跟着的shell元字符的含义。原创 2024-06-02 13:58:32 · 740 阅读 · 0 评论 -
AD9026芯片开发实录2-初始化流程
ad9026初始化流程原创 2024-05-27 22:22:41 · 399 阅读 · 0 评论 -
AD9026芯片开发实录1-芯片介绍
AD9026芯片介绍原创 2024-05-26 20:20:19 · 1388 阅读 · 0 评论 -
Linux开发讲课1---添加shell脚本定时任务
linux shell脚本原创 2024-05-31 22:20:35 · 194 阅读 · 0 评论