- 博客(47)
- 收藏
- 关注
原创 动态加载驱动模块
1,修改Kconfig之前config下为布尔bool类型,非1即0,现在需要将模块改成tristate(三态)2,make menuconfig,发现从原来的方括号[]变为尖括号<>,将对应模块配置成 M3,修改Makefileobj- +=xxx.o一共有三种情况-y:把xxx.c编译进内核,即静态编译进内核镜像-m:把xxx.c编译成独立模块,即编译为独立.ko模块-$(CONFIG_xxx):条件编译,根据配置项决定编译方式(Kconfig中)
2026-02-08 19:39:41
659
原创 设备驱动编译
设备驱动:操作硬件的程序(使硬件工作),是软硬件之间的桥梁字符设备驱动:数据按字节流访问(顺序性访问) 90%以上的设备都是字符设备块设备驱动:数据的访问可以是随机的,一般是存储设备网络设备驱动:集成复杂的协议栈,无设备号,按名字维护驱动和硬件之间存在对应关系。
2026-02-08 19:38:53
631
原创 linux内核编译
1,安装tftp服务并配置服务目录拷贝zImage和xxx.dtb到tftp服务目录下2,安装nfs服务并配置服务目录拷贝rootfs.tar.bz2到nfs服务目录下解压,解压命令:sudo tar -xvf 文件名。
2026-02-02 22:42:33
575
原创 Linux系统编程——sqlite数据库
与文件相比,数据库是一种专业的存储数据的结构,其中包含一系列算法用来查找等操作,所以一般来说少量数据用文件存储,大量数据用数据库存储。3,查询满足条件的数据:select * from 表名 where 列名 条件...;2,查询指定列数据:select 列名1, 列名2...列名n from 表名;回调函数如果没有给返回值,则会返回随机值,但是callback函数要求成功必须返回0,系统要使用。3,从数据库中查询数据,查到几条,回调函数就会被执行几次。适用的关系运算符:>,<,>=,<=,=,!
2026-02-01 19:15:33
508
原创 嵌入式——时序IIC
IIC,或者I2C,年“I方C”,集成电路总线,是同步串行半双工通信总线方式。该总线允许同时连接多个设备(芯片),每个芯片在总线上有特定的地址SDA:数据线SCL:时钟线两个信号线都是双向的,在硬件电路设计上,是必须要接上拉电阻,因为这是一种双开漏的通信模式,引脚只能主动拉低电平,无法主动输出高电平,需要上拉电阻来提供稳定的高电平,同时实现多设备 “线与” 通信逻辑。
2026-02-01 15:35:26
747
原创 嵌入式——时钟与定时器
clock control,任何一个外设启动之前,都要想想时钟启动了没时钟源:晶振,提供一个最基础的基准节拍,时钟通过升频降频等操作,通过不同的时钟门分别传递时钟信号配置时钟所需器件1,PLL(Phase Fractional Dividers)锁相环电路作用:进行升频。有一个倍频系数Y,假设时钟源晶振是24(MHZ),那经过PLL后则会输出24*N (MHZ)2,prescaler预分频器作用:进行降频。有一个分频系数,与PLL相反,则输出24/N。
2026-02-01 15:27:15
363
原创 嵌入式——UART
嵌入式系统中的通信是指的是两个或两个以上的主机之间的数据交互,主机指的是在通信中主动发起、控制整个通信过程的设备或模块,例如芯片,单片机。
2026-02-01 15:26:19
347
原创 imx6驱动
1,bootloader,一个裸机程序,为linux启动准备环境,引导linux启动1)初始化CPU(工作模式)2)初始化异常向量表3)初始化堆栈4)关闭中断5)关看门狗(定时复位)6)关Cache7)关闭MMU(虚拟地址→物理地址)8)初始化内存9)初始化相关设备(串口、网卡)10)集成相关协议11)搬移内核到内存,向内核传参(控制台、根文件系统类型及位置)12)启动内核13)从此bootloader不再控制CPU,CPU控制权移交给内核。
2026-01-31 20:06:22
661
原创 嵌入式——交叉编译
(1)使用arm-linux-gnueabihf-gcc只汇编不链接(2)使用arm-linux-gnueabihf-ld链接代码到特定地址(得到可执行,可连接程序linux executable linkable file)(3)使用arm-linux-gnueabihf-objcopy 格式转换(4)使用arm-linux-gnueabihf-objdump 反汇编(此处只是为了阅读代码,非必要步骤)-c:只汇编不连接-g:去掉调试信息-Ttext:指定安装位置-O:指定输出文件格式。
2026-01-25 20:30:16
805
原创 嵌入式——I.MX6ULL裸机环境配置
核心板接口:左:8GB的eMMC中间:SOC(I.MX6ULL)右下:512M的RAM核心板之下这一整块作为底板由正点原子设计,SOC由恩智浦生产,SOC中CortexA7的内核由ARM公司设计。
2026-01-25 20:30:04
577
原创 嵌入式——汇编语言
学习arm汇编的主要目的是为了编写arm启动代码,启动代码启动以后,引导程序到c语言环境下运行。换句话说启动代码的目的是为了在处理器复位以后搭建c语言最基本的需求。因此启动代码的主要任务有:1、初始化异常向量表;2、初始化各工作模式的栈指针寄存器;3、开启arm内核中断允许;4、将工作模式设置为user模式;5、完成上述工作后,引导程序进入c语言主函数执行;因此汇编指令的学习主要是围绕这几个目的展开,主要学习跟上述目的相关的指令。
2026-01-18 22:07:19
937
原创 嵌入式——ARM体系结构
嵌入式:以应用为中心,以计算机技术为基础,软硬件可剪裁的专用计算机系统。根据用户需求(功耗,体积,环境,稳定性,可靠性等等)计算机系统:1,软件系统:应用软件+系统软件2,硬件系统1)运算器2)控制器(和运算器组成CPU)3)存储器4)输入设备5)输出设备注:五个基本组成中最基本的设备是运算器、控制器和存储器SOC(片上系统):kearnal(内核),UART,GPIO,PWM,磁盘控制器...以下为嵌入式核心架构示意图kearnal架构:X86,ARM等等。
2026-01-18 20:37:37
913
原创 嵌入式——DS18B20
参数指标测量范围:-55℃~125℃工作电压:3V~5.5V精度:±0.5℃分辨率(对温度变化的敏感程度/精度):9、10、11、12位(默认)以采集到1℃为例,则实际温度值分别对应0.5,0.25,0.125,0.0625℃,这是因为在传感器内部将温度拆成了分辨率位数份,所以实际得出的温度值应该有所对应。
2026-01-15 19:44:31
849
原创 嵌入式51单片机——串口
Unversial Aysnc Recevier Transmiter,通用异步收发器,与外接设备进行异步通信方式,是硬件电路中的一种接口UART有一套自己通信的规则、协议,是异步、全双工、串行通信协议。
2026-01-14 22:21:12
1017
原创 嵌入式51单片机——中断
Genral Purpose Input Output:通用输入输出,是与外界交互最基本的形式,可以独立的将引脚配置为输入/输出模式输出模式:控制引脚输出高电平/低电平(给定控制信号)1,开漏输出2,推挽输出3,复用开漏4,复用推挽输入模式:检测引脚的电平(接收外部信号)1,上拉输入:在引脚外部接了一个上拉电阻(引脚空闲状态高电平)2,下拉输入:在引脚外部接了一个下拉电阻(引脚空闲状态低电平)3,浮空输入:引脚空闲状态电平不确定4,模拟输入(主要用于ADC)注:51单片机没有这些模式。
2026-01-14 08:55:14
1077
原创 Linux系统编程——TCP并发模型
TCP要实现一对多需要用到TCP并发服务器,而服务器分为两种1,单循环服务器:服务端同一时刻只能处理一个客户端任务2,并发服务器:服务端同一时刻可以处理多个客户端的任务,例如UDPTCP服务端并发模型1,多进程:资源开销大,安全性高2,多线程:资源开销小,相同资源环境下并发量大3,线程池:为了解决多进程或者多线程,再服务器运行过程中频繁你创建和销毁带来的时间消耗问题,基于生产者和消费者编程模型,以及任务队列等,实现的一套多线程框架4,IO多路复用。
2025-12-31 16:28:57
79
原创 Linux系统操作编程——http
万维网是一个大规模的、联机式的信息储藏所 ,实现从一个站点链接到另一个站点万维网服务器后台标记万维网数据方式:url:统一资源定位符万维网客户端与万维网服务器的通信方式:HTTP:超文本传输协议万维网客户端展示请求数据的方式:HTML:超文本标记语言。
2025-08-25 20:47:13
502
原创 Linux系统编程——传输层网络协议
UDP:传输层,用户数据报协议网络编程模型B/S模型:browser/server(浏览器/服务器)1,客户端为公用的客户端(浏览器)2,一般只做服务器开发3,客户端要加载的数据均来自服务器C/S模型:client/server(客户端/服务端)1,客户端是一个专用的客户端2,服务器和客户端都需开发3,客户端可保存资源,本地加载,无需所有数据都请求服务器。
2025-08-24 17:42:35
1162
原创 Linux操作系统编程——网络
目的:不同主机进程间通信需要解决的问题:1,主机与主机之间物理层面必须互联互通2,进程与进程之间在软件层面必须互联互通交换机:短距离网络通信,实现局域网内通信局域网:短距离的数据传输路由器:负责路由,即路径选择,将数据上传至广域网内的路由器广域网:多个路由器组成的数据转发集合中心。可以实现远距离数据传输IP地址:计算机的软件地址,用来标识计算机设备同一局域网中不可能出现IP地址相同的设备MAC地址:计算机的硬件地址(固定)网络的端口号:标记同一主机上的不同网络进程。
2025-08-22 22:29:46
1079
原创 Linux操作系统编程——进程间的通信
由于进程间空间独立,无法直接通信,所以需要IPC机制实现通信同一主机进程间通信1,古老的通信方式:无名管道;有名管道;信号2,IPC对象通信system v:共享内存(效率最高);消息队列;信号量集(信号灯)不同主机之间的通信:socket通信;网络通信通信类型单工:数据传输是完全单向的,通信双方严格分工,一方固定为发送端(只能发不能收),另一方固定为接收端(只能收不能发),传输方向不可改变,例如广播。
2025-08-19 22:09:27
853
原创 Linux操作系统软件编程——多进程
正在运行的程序,其运行过程中需要消耗内存和CPUmain.c(程序)(硬盘)-----a.out(程序)(硬盘)-------./a/out(进程)(内存)
2025-08-14 21:02:30
1097
原创 Linux操作系统应用编程——文件IO
前面已经说了,012自动占了三个文件标识符位置,所以若要向终端写入数据时,则不需要额外打开,只需要将fd位置改为1即可,而此时终端为输出设备,判断输入输出的对象是内存,从内存中出来为输出,存入内存中是输入。与标准IO的区别在于,标准IO操作的是文件流指针FILE*,文件IO操作的是文件描述符,而且这个文件流指针FILE指向一个复杂的结构体,结构体中含有文件描述符。对于部分大文件,需要反复读取,如果字节数不是缓冲区字节数的整数倍,则会造成越界访问,出现乱码,所以可通过write读写read的返回值。
2025-08-13 20:23:33
809
原创 Linux操作系统应用软件编程——标准IO
由于fgets最多读取一行数据,所以需要用到循环,直到读到文件末尾,但是该函数无法完全做到复制图片,会造成数据丢失,因为图片属于二进制文件,并不会写入0,因为在文本文件中,0等价于‘0’,而在二进制文件中,0等价于‘\0’从h开始,向后偏移10个,到d的位置,输入A,然后指针自动向后移,指向A之后,输入D,文件末尾从D之后开始,向前偏移5个,到o的位置,输入B,然后指向B之后的r,输入C。4)-,普通文件(包括但不限于xxx.c,xxx.h,xxx.txt,xxx.jpg,a.out)
2025-08-12 21:36:58
1370
原创 数据结构——哈希表、树、gdb调试、时间复杂度
这里以名字与电话来作为结构体成员,结构体当作哈希表数组元素静态创建,就是在创建之前树已经规定好了,并不像之前链表一类,来一个结点插一个结点先一个个取出data[]中的元素,所以ind++,如果c=‘#’,则表示该结点没有后继结点,并令根节点为空结点,函数终止,如果不是,则申请结点空间,在申请的结构体空间中装入数据,并以其左右结点为新的根节点再次引用该函数,直到叶子节点,并将叶子节点制空。整体为函数的递归,因为树的每一个子树都是二叉树,结构相同。
2025-08-10 18:11:02
1322
原创 数据结构——栈、队列
第一个函数为判断是否为空栈。先调用堆区空间,然后判断给的指针是否为空,接着给新的结点初始化,判断是否为空栈,如果是空栈,则栈顶和栈底指向同一个结点,如果不是,则需要将旧栈底结点指向新结点,并将栈底指向新结点。需要注意的是,没有尾插法,因为栈是先进后出,不能尾插。
2025-08-07 21:13:26
574
原创 数据结构——双向链表及makefile
在一项工程中,需要不仅仅是一个源文件,而是同时编译多个文件,这就需要makefile对工程进行编译和管理makefile:用来管理代码的编译和连接通过make工具解释makefile语法规则:目标文件:依赖文件(a.out:main.c)编译方法(gcc)
2025-08-06 21:19:38
1240
原创 数据结构——单向链表部分操作及valgrind安装
很多时候,由于忽略了对堆区空间的释放,会造成内存泄漏,所以在Ubuntu下linux有一个内存探测工具:valgrind步骤:1,虚拟机,设置,网络适配器,桥接模式,确定2,编辑,虚拟网络编译器,更改设置,VMnet0(没有就创一个),桥接到PC正在上网的网卡上,应用,确定3,配置网络文件:sudo vim/etc/network/interfaces,打开之后会有一串代码,只保留以下部分,剩下的用#注释掉4,重启网络服务:sudo/etc/init.d/networking restart。
2025-08-04 20:18:21
570
原创 数据结构——单向链表
数据结构:用来组织和存储数据程序 = 数据结构 + 算法数据与数据之间的关系(1)逻辑结构:数据元素与元素之间的关系集合:元素与元素之间平等的关系线性结构:数据元素之间存在一对一的关系(顺序表、链表、队列、栈,内存是一种线性的存储结构)树形结构:数据元素之间存在一对多的关系(二叉树)图形结构:数据元素之间存在多对多的关系(网状结构)(2)物理结构:数据元素在计算机内存中的存储方式顺序结构:在内存中选用一段连续的内存空间进行存储1,数据访问方便(O(1))
2025-08-03 19:22:04
2237
原创 C语言结构体、共用体与位运算
形式:struct 结构体名 {成员表列};其中成员表列形式为:类型名 成员名,结构体名第一个字母最好大写struct是关键字,不可省略,而且末尾必须加上分号接下来以学生的学号姓名成绩组成结构体为例int id;char n[20];}s1,s2;int main()
2025-08-03 15:55:08
959
原创 C语言——指针3
(1)指针与指针之间只能做减法运算(2) 指针变量加(减)一个整数,是将该变量指向的地址偏移一个基类型(3)指针变量的赋值(4)指针变量可以有空值,即不指向任何地址,例int *p = NULL。
2025-08-01 21:45:50
1163
原创 C语言——指针2,str类型函数的拆解
在进一步讨论之前我们需要了解一下const关键字,以strcpy为例,如果按照仿写的Strcpy("hello", "world"),则系统会崩溃,而以C语言库中的strcpy(“hello”, “world”),则会报错,崩溃的原因是字符串常量不可更改,而错误的原因是strcpy形参的类型并非char *,而是const char *,这种关键字会大大提高C语言的实用性。在此之前需要分清楚数组指针和指针数组,前者指的是指针,指向一整个数组的指针,后者指的是数组,其里面装的全是指针。
2025-07-29 21:09:12
700
原创 C语言——指针1
int *p = a,但是此时,*p++(访问下一个元素)是合法的,*a++却是不合法的,因为虽然两个值都是数组首元素,但是p是指针变量,a对于编译器来说是一个地址值常量。当&和*连用时,会产生“抵消”效果,所以第一、二、三行分别用了%d、%p、%p,对于第三行, 由于指针也有储存空间,所以指针自然而然也有地址,但是对于第四行会报错,这是因为,由于运算符自右向左,会先进行*i,而*后面应该是个地址,所以会报错。其中,i=1000为直接访问,而通过指针的*p=1000则为间接访问,*p就是i。
2025-07-28 20:50:11
1283
原创 C语言函数
当开始运行f1时,需要调用f1,而为了防止调用函数f1后无法回到main函数中,需要把main的地址保存下来,即入栈,所以此时在栈的最底层则是main的位置,此过程也被称为保护现场,而同理,f1和f2也接连入栈,于是在出栈时,顺序便是f2,f1,main,此过程也被称为恢复现场。综上,在c语言运行之前,必须开辟出来栈的空间,即栈区。为保证函数调用的正常运行,计算器会开辟新空间,记录调用前函数的位置,与缓存区空间的队列先进先出的特点不同,其特点为先进后出,即入栈和出栈。先输出10,再输出20,最后输出30。
2025-07-24 20:57:04
831
原创 C语言二维数组以及函数起头
形式:int a[2][2] = {{1,2}, {3,4}} int a[][2] = {1,2,3,4} char s[][10] = {"hello", "world"}注:第一个方括号[]内可以省略,编译器会自动排布,但是第二个不可以省略与一维数组和字符型数组相同,不足时补0,超出则会越界访问,同样的,第一个元素为a[0][0]。
2025-07-23 20:41:35
252
1
原创 C语言字符数组
与整型类似,只是数据类型从整型变为字符型,例:char a[10];与整型不同的是,int a[10]能存10个元素,但是char a[10]只能存9个元素,因为a[9]位置需要字符\0作为结束标志,所以在存字符串时,数组需要有字节数+1个位置。
2025-07-22 20:42:16
352
原创 C语言一维数组
方式:类型说明符 数组名[表达式]例:int a[10] int n = 10, a[n]以上均可以表示定义了一个整型数组,数组名为a,且此数组有10个元素,每个元素都是整型数组可以被初始化,例:int a[2] = {1,2},如果花括号里的数不够,则剩余的全是0,若是超出数组范围,则会越界访问,只有方括号[]内为常数时才可以初始化,且常数可以省略,编译器会自动匹配长度注意:数组内第一个元素为a[0],而最后一个元素为a[9]
2025-07-21 21:32:48
879
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅