- 博客(24)
- 收藏
- 关注
原创 Linux内核——内核源码的探索+教你如何系统认识Linux内核源码树(推荐方式+推荐工具+推荐书目)
全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,该操作系统是由 Linus Torvalds于1991年10月5号首次发布, 它主要受到Minix和Unix思想的启发,是一个。严格地讲,Linux单指操作系统的内核,加上用户空间的应用程序之后,就成为Linux操作系统。
2024-08-25 14:54:23
978
原创 动态链接库——深入探讨C++程序中.so技术细节和实现方式及C程序中动静态库的区别(+工程分步骤编译库)
在开发中,动态链接库(DLL)和共享对象(Shared Object).so文件的使用成为提升程序灵活性和重用性的关键手段。如下相关工具,一种用于创建可移植共享库的工具。关于动态链接器的更多信息。一个跨平台的构建系统,简化了共享库的管理和构建。无论是提升程序的模块化程度,还是优化资源使用,动态链接都是一种强大的技术手段。
2024-08-25 11:50:48
1118
原创 ARM架构的BootLoader详解——对于Linux与Baremetal(裸机MCU)
BootLoader的启动方式基本如下:stage1程序(汇编)在内存之外的存储介质中对内存空间进行初始化后,再将stage2程序(C)加载到内存中执行。stage2。
2024-08-23 12:11:10
1521
3
原创 PWM驱动电机系列——PID控制 (各电机设备之间的驱动差异及区别)自动控制系统的性能指标
对于速度跟踪控制来说,增量式 PID 更加适合,因为它直接计算速度变化量。相比之下,位置式 PID 需要计算绝对速度误差,在速度跟踪控制中可能会产生超调和振荡等问题。
2024-08-23 11:28:45
885
原创 C的动态内存管理 free()和malloc()的简单实现——free()根据内存地址便知释放内存的空间大小(原理详解)
malloc 分配的内存是未初始化的,其中的字节内容是不确定的(可能是随机值)。如果内存分配失败,malloc 返回一个空指针 NULL,可以通过检查返回值来判断是否分配成功。calloc 分配的内存会被初始化为全0。calloc 在分配失败时会自动抛出错误(异常),可以使用异常处理机制来捕获和处理错误。realloc 当malloc函数或者calloc函数申请的空间或者数组的空间不够大或太大时就可以用realloc函数对空间的大小进行调整。
2024-08-21 11:25:22
865
原创 Linux设备驱动——字符设备的高阶驱动实现及关键要素之阻塞型I/O用法详解(休眠与唤醒机制)
指当进程/线程执行某个需求时,因为当下无法立即满足请求,而使其进程或线程阻塞。优点:在某些情况下,阻塞型 I/O 可以更有效地利用系统资源。在一些高负载场景下,可以避免频繁的上下文切换,降低系统开销。而且阻塞型I/O的编程模型通常比较直观和易于理解。代码顺序执行(算作一个同步过程),不需要太多复杂的逻辑来处理异步操作和事件回调。开发经验:(驱动程序应该(默认)阻塞型进程,将其置入休眠状态直到请求可继续)
2024-08-21 10:50:16
1100
原创 C指针汇总——藏在数组名与指针之间的异同及使用细节
数组指针是一个指针变量,占有内存中一个指针的存储空间;指针数组是多个指针变量,以数组的形式存储在内存中,占有多个指针的存储空间。注意。
2024-08-19 15:57:30
735
原创 Linux设备驱动——字符设备的基本驱动实现及关键要素(体系地认识文件与驱动)
字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,比如字符终端(/dev/console)和串口(/dev/ttys0),它们可以通过文件系统节点来访问,大多数字符设备是一个个只能顺序访问的数据通道。字符驱动设备程序适合于大多数简单的硬件设备,且比起块设备或网络驱动设备程序的架构相对简洁。在深入了解设备驱动程序时,从字符设备开始剖析可以更好地理解内核的工作过程。
2024-08-19 15:21:15
859
原创 Linux设备驱动——模块的构造、运行与设计 与众不同的hello world与点灯
编写一个Linux下的设备驱动,首先要准备好对应内核版本的内核源码树文件。该系列的全部文章都以嵌入式系统的ARM-Linux的环境进行阐述,并以交叉编译的方式在主机Ubuntu20.04系统上编译和ARM开发板上跑测 (E2000Q、H616、或者IMX6ULL看情况交叉着使用) 关于交叉编译的配置,以往的文章中有作介绍,这里不再赘述。驱动程序一般要执行两类任务1.模块中的某些函数作为系统调用的一部分而执行2.某些函数则负责中断处理。
2024-08-11 21:25:03
1252
原创 Linux设备驱动浅谈 利用Linux内核接口可以实现自定义模块机制
接触编程,大家应该都有这样一个疑惑,我们写的应用程序一执行,便在操作系统上工作,其原理是(当程序一执行,它便成为一个操作系统上的进程,然后由操作系统进行管理),那如果我们写的程序要让某些硬件设备工作呢,那又是如何工作的,这对于应用开发的人员而言,一般不作太深入的了解,但是在计算机体系中,它是不可或缺的一部分。在实际的项目开发中以Linux环境为多数,此图诠释了计算机软件层和硬件层的组成,本文将对下面这个结构不断拆解,最后回答这个问题——如何用程序让硬件设备工作。
2024-08-10 16:57:13
1164
原创 回溯函数(算法)杂谈 -----可主动控制撤回逻辑处理的递归函数
回溯,对接触了算法的人而言,并不陌生,其实严谨地说回溯函数就是递归函数,只不过在使用上,人们将它的一些细节抽离出来,进而演化出了所谓的回溯,在算法导论中,与其相关的被称为“回溯搜索算法”。回溯本质是递归的副产物,只要有递归调用就会有回溯。回溯法也经常和二叉树或N叉树遍历,深度优先搜索混在一起,因为这两种方式的简单实现都是用了递归(当然可以使用数据结构的栈模拟递归,来设计搜索遍历算法)。
2024-08-10 11:53:20
898
原创 函数指针与指针函数(浅谈) C也能实现面向对象编程思维的关键
函数指针的本质是一个指针,该指针的地址指向了一个函数,即指向函数的指针。函数的定义是存在于代码段,因此,每个函数在代码段中,也有着对应的入口地址,函数指针就是指向代码段中函数入口地址的指针。/*return_type 为返回类型,ptr为指针变量,代表的是指向目标函数的指针args为形参列表,*ptr即为函数。*/初始化方式a : b;//函数指针的定义//函数指针的另一种定义方式,不过不建议使用//也可以使用这种方式定义函数指针//函数指针初始化//函数指针的调用。
2024-08-06 20:19:10
944
原创 W25Q128 spi-flash HAL库驱动详解
W25Q128是华邦公司推出的一款容量为 128M-bit(1byte == 8bit,相当于 16M-byte)的 SPI 接口的 NOR Flash 芯片(NOR Flash:一种非易失性存储器,它可以在断电或掉电后仍然保持存储的数据,被广泛应用于长期数据存储。有容量大,可重复擦写、按“扇区/块”擦除的特性。Flash的物理特性:只能写0,不能写 1,写1靠擦除。这一特性对后续编程,实现控制非常重要相应的还有其他型号。
2024-08-06 15:03:43
1008
原创 编译报错 aarch64-none-linux-gnu-gcc: error: unrecognized argument in option ‘-mabi=apcs-gnu’ aarch64-non
交叉编译工具报错,大概意思是:架构不匹配我的交叉编译工具环境的配置为此时,arch环境变量,表示的是不同的计算机架构,此时为arm架构,但是工具链是arm64体系结构的。
2024-08-05 17:23:26
234
原创 0.96寸(128*64) OLED(SSD1306) 中英显示+任意图像显示
(现使用的比较多的是4线SPI控制和 I2C控制,接下来将以I2C控制为例子)
2024-08-05 14:13:22
471
原创 排序算法与字符串操作函数实现 ( 细节系统整理篇 )
( 与strcpy()函数不同的是,该函数不会检查任何终止字符(如'\0'),而总是精确的拷贝参数传入的字节数,当想拷贝一个整型数组/结构体/枚举常量等strcpy()函数无法拷贝的数据时,可以考虑使用memcpy()函数来完实现这一诉求,当然,想要使用memcpy()函数拷贝字符串也是可以的 )( 例如:比较字符串str1和str2 strcmp(str1,str2) 如果返回值小于 0,则表示 str1 < str2。若str2是str1的子串,则返回str2在str1的首次出现的地址;
2024-05-07 17:28:47
803
原创 warning: initialization of ‘int (*)(int, int)’ from incompatible pointer type ‘void (*)(int, int)’警告
这个报错的原因是类型不匹配。具体来说,代码中定义了一个函数指针变量,它的类型是 int(*)(int,int),但是在赋值时,右侧的函数类型是 void(*)(int,int),两个类型不匹配,导致编译器报错。
2024-04-30 17:13:06
198
1
原创 通信协议篇 ( 常用的协议快速入门)
IIC全称Inter-Integrated Circuit (集成电路总线) 是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备( 驱动FRAM、E2PROM、OLED等 )。IIC属于方式( 每个连接到总线上的设备都有唯一的地址,任何设备既可以作为主机也可以作为从机,但同一时刻只允许有一个主机。IIC 标准是一个具有冲突检测机制和仲裁机制的真正意义上的多主机总线,它能在多个主机同时请求控制总线时利用仲裁机制避免数据冲突并保护数据。( 特点: 简单性、有效性、 多主控)
2024-03-11 20:40:22
1650
原创 链表篇 (反转链表2 虚拟头节点的有无)
关于 链表内指定区间反转 中思路非常多,如果使用拆分链表的方法,那么可以细分考虑虚拟头结点的有无,(这里的虚拟头结点,不是说不存在的,它也是动态开辟的一块内存空间,只是在算法计算中不过多的关联,像哨兵一样,用于站岗!!!!!我们以这个例子开始讨论。
2024-02-27 17:41:29
441
原创 交叉编译-Makefile体系(快速入门)
(划重点: “ 伪目标 ”的取名不能和文件名重名,为了避免和文件重名的这种情况,可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”。但是当工程非常大的时候,手写Makefile也是非常麻烦的,如果换了个平台Makefile又要重新修改,因此更高级的一些构建系统或者工具工具像cmake、qmake、ninja和auto make就出现了,它们可以根据一些配置文件来自动化编译和链接软件项目。
2024-02-17 17:31:58
1496
1
原创 Linux系统编程整理之二(网络编程-快速入门篇)
将收到的第一个字节的数据当做高位来看待,这就要求发送端的发送的第一个字节应该是高位。而在发送端发送数据时,发送的第一个字节是该数字在内存中起始地址对应的字节。即多字节数值在发送前,在内存中数值应该以大端法存放。所以,网络协议指定了通讯字节序:大端,只有在多字节数据处理时才需要考虑字节序。运行在同一台计算机上的进程相互通信时,一般不用考虑字节序;计算机之间进行通讯时,需要将各自的字节序转换为网络字节序。
2024-01-27 14:04:17
1430
原创 jupyter notebook导入库失败No module named xxx但在conda环境中存在库
首先,打印当前库路径,是否在当前运行的 jupyter notebook 的 kernel中(一般是不在的),然后将需要的库路径(虚拟环境的库包),添加进当前运行的jupyter 的kernel路径下。% 运行shell的环境是当前jupyter notebook运行的虚拟环境比如kernel是pytorch,输入%pip list,就会显示当前虚拟环境安装的库。直接 改变运行的kernel (如果Change kernel 中只有一个原来的kernel,那就法一咯)
2024-01-26 21:50:34
491
原创 Linux系统编程整理之一(进程篇)
进程: 程序的一个执行实例(正在执行的程序)程序是静态的概念,例:将源文件通过编译链接后在当前路径下 生成的可执行文件 pro当程序运行起来了,系统中就多了一个进程,担当分配系统资源(CPU时间,内存)的实体(当我们运行程序的时候,相关文件就会从磁盘加载到内存,操作系统通过先描述,再组织的方法对文件进行管理,从而只让想要执行的程序加载到内存,一个加载到内存的程序称为进程)( 前台进程: 进程状态后跟’+’;后台进程: 进程状态后不跟’+’)
2024-01-22 10:43:42
1764
1
原创 Linux多线程编程函数整理
这里的线程二阻塞,不仅仅是等待cond变量发生改变,同时释放mutex锁 ,mutex锁释放后,线程一终于获得了mutex锁,得已继续运行,当线程一的if(i%3==0)的条件满足后,通过pthread_cond_signal() 发送信号,告诉等待cond的变量的线程(这个情景中是线程二),cond条件变量已经发生了改变。另外,某些应用,如线程池,pthread_cond_broadcast唤醒全部线程,但开发中通常只需要一部分线程去做执行任务,所以其它的线程需要继续阻塞等待。
2024-01-19 11:30:35
1727
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人