- 博客(57)
- 收藏
- 关注
原创 ARM-11-Mailbox 线程间通信机制
每个线程的消息队列使用「带哨兵头节点」的单向链表实现,mail_head 永远指向哨兵,mail_tail 指向最后一个有效节点(队列空时也指向哨兵)。工程优化:用 pthread_cond_wait() 条件变量,没消息时线程「睡觉」,有消息时再「唤醒」,CPU 不空转。用 pthread_cond_wait() 条件变量,没消息时线程挂起,有消息时 signal 唤醒,避免 CPU 空转。为线程分配链表节点,初始化消息队列(哨兵节点),pthread_create 启动线程,头插法加入全局链表。
2026-04-22 21:04:06
431
原创 ARM-10-SQLite3 库移植笔记
ubuntu 主机│├── 1. 下载 SQLite3 源码├── 5. 交叉编译测试程序││ 通过 NFS▼ARM 开发板└── 8. ./sqlite_test → 看到输出即移植成功交叉编译必须同时指定-I头文件路径和-L库路径开发板上若有旧版动态库,必须先删除再拷贝新的开发板库目录/lib和/usr/lib均可放置动态库。
2026-04-22 20:59:51
323
原创 ARM-驱动-10自定义通信协议
TCP 是流式传输,没有"消息边界"的概念。发送方发了3个包,接收方可能一次收到1个,也可能一次收到3个拼在一起,这就是经典的粘包问题。发送方发送:[帧1: 7字节] [帧2: 7字节] [帧3: 8字节]接收方可能收到:情况A:[帧1+帧2+帧3 共22字节] ← 粘包情况B:[帧1前3字节] + [帧1后4字节+帧2] ← 半包情况C:正好每次一帧 ← 理想情况,实际很少解决方案:设计自定义协议,用帧头 + 长度 + 帧尾标记每帧的边界,接收方按协议解析,无论怎么粘包都能正确还原。
2026-04-17 18:49:43
486
原创 ARM-驱动-08-LM75(I2C)和 ADXL345(SPI)
内核注册驱动时会用 name 与设备树 compatible 做字符串比较,name 为 NULL 则传入空指针,触发 string_compare 崩溃。:可在驱动层完成解析,向应用层直接返回摄氏度数值,减少应用层的解析负担,符合"驱动封装硬件细节"原则。根据实际设备修改 printk 中的设备名称字符串,便于调试时区分日志来源。,底层通信必须封装为独立函数。这是内核"分层抽象"的核心要求。表示 CS0),二者含义完全不同。
2026-04-16 20:49:12
491
原创 ARM-驱动-09-LCD FrameBuffer
0x56000000/dev/fb0mmapLinux 的内存保护机制禁止应用层直接访问物理地址,Frame Buffer 就是内核提供的合法通道。
2026-04-16 20:33:07
492
原创 ARM-驱动-06-中断底半部 + ioctl + 原子操作与锁
场景推荐中断上下文(ISR / tasklet / softirq)只能用自旋锁进程上下文,临界区极短自旋锁进程上下文,临界区可能阻塞互斥锁多读少写读写锁(rwlock)单个整型计数器原子操作(最轻量)#define MAGIC_NUM 'x' // 魔数:选一个不常用的 ASCII 字符0// 命令编号12。
2026-04-14 20:57:00
481
原创 ARM-05-Platform + DTS + GPIO子系统 + 中断 + 等待队列 + 错误处理
位置h.dtspt.dts根节点下无pt_key新增pt_key节点&iomuxc下无新增pt_key中断声明无interrupts。
2026-04-13 13:47:25
390
原创 ARM-04-驱动-Misc ,Platform ,DTS
Misc一行注册,省掉 4 步繁琐流程,适合快速原型。Platform:设备资源和驱动逻辑分离,换板子只改 device.c,同一 driver 服务多个设备。DTS:把硬件信息彻底搬出内核代码,放进独立 .dts 文件,同一内核镜像配不同 DTB 跑不同板子。
2026-04-10 21:09:37
439
原创 ARM-驱动-03 Linux 字符设备驱动开发
在内核源码根目录生成索引 ctags -R # vim 中使用 Ctrl+ ] # 跳转到光标下符号的定义 Ctrl+o # 返回跳转前的位置 # 有多个定义时,输入数字选择跳转目标改动旧写法新写法设备号分配手动写死动态申请初始化顺序cdev_add 在 alloc 之前(错误)先 alloc → 再 init → 再 add创建设备节点手动执行mknod自动生成错误处理缺失或不完整goto错误链,逆序释放。
2026-04-10 09:26:51
551
原创 ARM-驱动-01Linux系统移植
ubuntu 开发主机│├── 交叉编译内核(zImage + dtb)→ 放入 TFTP 目录├── 交叉编译应用程序 → 放入 NFS 目录├── 配置 NFS 服务(共享 rootfs)└── 配置 TFTP 服务(提供内核下载)││ 有线网络▼ARM 开发板├── uboot 通过 TFTP 下载内核 → bootz 启动├── 内核通过 NFS 挂载 rootfs└── 用户通过 NFS 目录开发调试应用程序。
2026-04-08 19:57:03
451
原创 ARM-驱动-02-Linux 内核开发环境搭建与编译
网络失败排查:检查 IP 是否与服务器同网段、子网掩码是否匹配。代表一个数据包,无错误提示即为成功。— 所有配置项的汇总,由工具自动生成。— 定义配置选项(菜单结构)号表示数据包传输,每个。— 根据配置决定是否编译。切换,提升开发效率。
2026-04-08 19:41:18
434
原创 ARM-12-I.MX6U LCD
DOTCLK 模式就是 RGB 接口,适合直接驱动带 RGB 信号线的 LCD 屏幕(24根数据线 + 控制信号),I.MX6U 开发板搭载的 ATK4384 就是 RGB 接口的屏幕。在 LCD 中,这段时间是给屏幕内部 IC 的反应时间,让其识别换行/换帧信号,锁定有效像素数据。:把硬件参数和显存地址封装在一起,上层图形库只操作这个结构体,不关心底层寄存器,提高代码复用性和可移植性,这是驱动设计的重要思想。:液晶显示器,只是输出设备,不含触摸功能(触摸由单独的触摸控制器实现)。把电压值显示到屏幕上。
2026-04-02 19:24:22
477
原创 ARM-10-I.MX6U ADC
软件触发模式下,向 HC[n] 写入通道号就会立刻启动一次转换,这就是"写通道号 = 触发转换"。:读取 R[0] 这个动作会自动清除 HS 中的 COCO0 标志,为下次转换做准备。在部分芯片为无效值或 16 位模式,读数需用 0xFFF 掩码取低 12 位。,最大分辨率 4096 个刻度(0~4095),参考电压一般为 3.3V。:I.MX6ULL 的 ADC 最高支持 12 位,MODE 设为。:模数转换器,把连续的模拟电压信号转换成离散的数字值。,不能配置为普通 GPIO。
2026-04-01 19:33:02
422
原创 ARM-09-I.MX6U-I2C
线与”= 任何一方输出低电平,总线就是低电平;只有全部输出高电平,总线才是高电平。主从设备都可以拉低总线实现多主仲裁:谁先拉低谁赢I2C 引脚必须配置为开漏输出(OD),外部需要上拉电阻SION 位必须置1,使 SDA/SCL 引脚同时作为输入(用于采样)IIF 标志位需要软件清零,每次传输前后都要处理读操作第一个字节无效,触发读后要丢弃第一次虚读的结果最后一个字节必须回复 NACK,否则从机不知道何时停止发完起始位后检查 IAL,判断是否发生仲裁丢失波特率不能随意设置。
2026-03-30 20:03:45
506
原创 ARM-08-I.MX6U UART 串口
串口是单片机和嵌入式 Linux 开发中最常用的外设,可用于:I.MX6U 共有 8 个 UART,主要特性:这里选择 UART1:2. 配置三个 UART 控制寄存器UARTx_UCR1 位 名称 说明 bit14 ADBR 自动波特率检测使能位:0=关闭,1=使能 bit0 UARTEN UART 使能位:0=关闭,1=使能 UARTx_UCR2
2026-03-30 09:06:38
465
原创 ARM-07-i.MX6ULL-EPIT定时器和GPT
这张图是 → 多路选择器选时钟(可选关闭、IPG 时钟、32K 时钟、高速时钟) → 12 位预分频器(分频系数 1~4096) → 32 位计数器(从加载寄存器值开始向下计数) → 与比较寄存器值匹配时触发比较器 → 比较触发中断(ITIF/ITIE)和输出引脚(EPITn_OUT) → 计数到 0 时自动从加载寄存器重载,继续计数:时钟 → 分频 → 计数 → 比较 → 中断/输出 → 重载循环:定时中断、PWM 生成、精确延时。。
2026-03-27 19:41:02
686
原创 ARM-06-i.MX6ULL时钟系统配置
i.MX6ULL 的时钟系统由多个 PLL(锁相环)和分频器组成,通过寄存器配置来选择时钟源和分频比,最终为 ARM 内核、总线和各外设提供所需的工作频率。[时钟源] ──→ [PLL] ──→ [预分频器] ──→ [分频器] ──→ [外设时钟]第三步:设置 CCM_CACRR — ARM_PODF 2分频。第二步:设置 CCM_ANALOG_PLL_ARMn。ARM 内核时钟由 PLL1 提供。是固定频率,软件无法更改,需优先完成配置。二、ARM 内核时钟配置(PLL1)1.4 需要配置的寄存器。
2026-03-26 21:21:11
535
原创 ARM-05-i.MX6ULL中断配置
第一步:设置异常向量表基地址(VBAR)__set_VBAR是一个封装了 ARM 协处理器指令 MCR 的函数,作用是设置 VBAR(Vector Base Address Register,异常向量表基地址寄存器)。地址在lds里面,是0x87800000.第二步:初始化GIC所以中断初始化函数写成下面这样子:2.按键中断初始化第一步:配置引脚功能和方向,因为键盘初始化上次设置过了 所以直接搬过来。
2026-03-25 21:36:25
523
原创 C语言复习笔记
chmod一、C语言关键字局部变量:值在函数调用间保持。全局变量/函数:只在本文件可见,防命名冲突。声明外部变量/函数,跨文件使用。只读,值不能改。禁止编译器优化,用于硬件寄存器,保证每次都真读写。
2026-03-23 20:47:35
67
原创 ARM-04-i.MX6ULL蜂鸣器
问题原则外设不工作先查时钟使能程序异常退出先查栈初始化引脚无响应先查IOMUX 复用代码难维护使用结构体映射 + 模块化。
2026-03-23 20:34:44
447
原创 ARM-03-i.MX6ULL点亮led
arm-linux-gnueabihf-objcopy更像一个格式转换工具,我们需要用它将 led.elf文件转换为led.bin文件,命令如下:arm-linux-gnueabihf-objcopy-Obinary-S-gled.elfled.bin。那么连接到底是个什么概念呢?led.elf文件也不是我们最终烧写到 SD卡中的可执行文件,我们要烧写的.bin文件,因此还需要将 led.elf文件转换为.bin文件,这里我们就需要用到 arm-linux-gnueabihf-objcopy这个工具。
2026-03-23 19:59:57
579
1
原创 ARM -02-汇编指令
ARM 处理器有7种工作模式(User/FIQ/IRQ/SVC/Abort/Undef/System),通过操作 CPSR 寄存器切换。SWI(Software Interrupt,软件中断)是一条主动触发中断的指令,用于从用户模式进入管理模式(系统调用)。进入 deal_swi 时,LR 指向 SWI 指令的下一条指令,所以 SWI 指令地址 = LR - 4。ARM 指令固定32位,既要编码操作码和寄存器,留给立即数的只有12位(8位数值 + 4位移位量)。指针本身是什么类型,只有在定义声明时才确定。
2026-03-20 20:04:37
632
原创 ARM-01-硬件基础
嵌入式系统硬件主要由CPU、RAM、Flash/ROM、时钟和复位电路五大核心部件构成。其中,CPU作为核心执行单元,包含多种类型(MCU/MPU/DSP等),ARM处理器分为Cortex-A/R/M三大系列;存储器采用分层设计,从高速寄存器到低速Flash形成速度-成本平衡;SOC架构整合CPU与各类总线(AHB/APB)。系统采用冯诺伊曼或哈佛结构,通过流水线技术提升指令吞吐率,并支持7种工作模式及异常处理机制,由CPSR寄存器统一管理状态。该架构实现了性能、成本与可靠性的优化组合。
2026-03-19 21:30:57
470
原创 51单片机-05-DHT11 温湿度传感器 | DS1302 实时时钟
例:2025年3月18日 14:10:33 周二 写法为:{0x33, 0x10, 0x14, 0x18, 0x03, 0x02, 0x25}(秒分时日月周年顺序)DHT11:温湿度双测,0~50°C,精度 ±2°C,1°C分辨率,高位先发(MSB First)│ ├── 数据:5字节(湿度整数+湿度小数+温度整数+温度小数+校验和)│ └── 判断:等低结束 → 延时60us → 采样(高=1,低=0)3线同步串行:CE(使能)+ SCLK(时钟)+ I/O(数据,双向)
2026-03-18 18:40:11
595
原创 51单片机-04-DS18B20 数字温度传感器
来自 intrins.h,执行一个空操作(NOP指令),占一个机器周期(约1.085us @11.0592MHz)。使用有符号 short(而非 unsigned short),是因为 DS18B20 负温度时高字节符号位为1,short 能正确处理补码,乘以 0.0625 后自动得到负值。作为数据接收方时,必须先释放总线(DQ_HIGH),让上拉电阻把总线拉高,再去检测从机发来的电平变化。位=0.5°C / 10位=0.25°C / 11位=0.125°C / 12位=0.0625°C(默认12位)
2026-03-17 21:30:13
526
原创 51单片机-03-串行通信
上行帧:0xAA + 0x01 + 0x81 + 0x42 + 0x00 = 0x16E,取低8位 = 0x6E ← 应答校验码。例:发送 0xAB = 1010 1011,实际在线上先出现 bit0=1,然后 bit1=1,...,最后 bit7=1。下行帧:0xAA + 0x01 + 0x01 + 0x42 + 0x00 = 0xEE ← 这就是校验码。A-B < -2V = 低电平,抗干扰极强。SMOD=0 → 正常速率。控制LED,0x02=控制数码管,0x03=控制蜂鸣器,0x04=温度采集。
2026-03-16 20:15:53
421
原创 51单片机-02-中断系统
GATE=0(常用):只要 TR0/TR1 置1,定时器就启动。GATE=1(少用):需同时满足 TR0/TR1=1 且 INT0/INT1 引脚为高电平,定时器才启动(用于测量脉冲宽度)。操作:TCON |= (1 << 6) 启动 / TCON &= ~(1 << 6) 停止。操作:TCON |= (1 << 4) 启动 / TCON &= ~(1 << 4) 停止。IT1=1:下降沿触发(推荐,不会误触发)。C/T=1:计数器模式(对外部引脚T0/T1的脉冲计数,用于测量外部事件次数)。
2026-03-16 09:02:37
524
原创 Linux—网络通信04-IO多路复用-并发模型
特性多进程模型 (Process)多线程模型 (Thread)资源开销大。每个进程有独立的内存空间、页表等。小。线程共享进程内存,只有栈和寄存器独立。切换速度慢。涉及上下文切换,TLB 刷新等。快。只需切换栈和寄存器。数据共享难。需要使用 IPC (管道、共享内存、消息队列)。易。直接读写全局变量即可 (但需加锁)。稳定性高。一个进程崩溃不影响其他进程。低。一个线程崩溃 (如段错误) 可能导致整个进程挂掉。适用场景对稳定性要求极高,或需要利用多核 CPU 隔离任务。
2026-03-13 21:09:30
409
原创 51单片机-01-在8位数码管上动态滚动显示数字
main.c││ └─ 把1234拆成 [4,3,2,1,0,0,0,0] 存入 display_buf[]│└─ digiter_show() ← 每调用一次,只显示一位├─ P0 = 0 (消隐)├─ Bit_Select(pos) → 操作 P2.2/P2.3/P2.4 → 译码器选位├─ Seg_Select(数字) → P0 = seg_table[数字] → 点亮对应段├─ delay(100) → 停留一段时间└─ pos++ → 准备下一位。
2026-03-13 20:43:19
624
原创 51单片机-01-基础概念
✅ 优点:节省 I/O 口(8 位段选 + 4 位位选 = 控制 4 位数码管)✅ 不需要外接 RAM/ROM、按键、LED 等(那些是扩展功能)。2. 再向工程中添加.c文件(必须和工程在同一目录)安装Keil:安装路径必须是英文路径,不能出现中文。STC-ISP -> 单片机程序(.hex)💡 寄存器是软件控制硬件的“接口”。本笔记都是用的普中89C51板子。💡 所有模块通过内部总线互联。→ 第 2 位清零,其他不变。❌ 缺点:亮度略低于静态显示。→ 第 3 位置 1。,实现“一对一”选择。
2026-03-13 19:31:09
609
原创 Linux系统编程-数据库-SQLite3
官网:www.sqlite.org / www.kernal.org(GNU 开源)开源,C 语言开发代码量少,1 万行左右,总大小 10M 以内绿色软件,无需安装文件型数据库,可以移动(整个数据库就是一个.db文件)数据容量最大2T。
2026-03-09 20:12:08
476
原创 Linux—网络通信04-IO多路复用
定义:在单线程/单进程中,同时监测多个文件描述符(fd)是否可以执行 IO 操作的能力,也称为 IO 事件(读/写)的通知机制。向集合中添加需要监测的 fd: FD_SET(fd, &rd_set)添加 / EPOLL_CTL_DEL 删除 / EPOLL_CTL_MOD 修改。定义描述符集合(fd_set),并清零: FD_ZERO(&rd_set)关键点 2:父进程关闭 conn,子进程关闭 listfd(文件描述符隔离)返回后,遍历 fd 集合,用 FD_ISSET 找到就绪的 fd。
2026-03-09 19:41:03
348
原创 Linux—网络通信03-协议头结构、HTTP 与 Wireshark 抓包
协议层协议头部大小接口层MAC(以太网 V2)18 字节(不含物理层)网络层IP20 字节传输层TCP20 字节传输层UDP8 字节MAC(18) + IP(20) + TCP(20) = 58 字节Wireshark 是一款网络抓包工具,用于网络调试和协议分析,可以查看网络设备底层收发的每一个字节。步骤UDP 服务器UDP 客户端TCP 服务器TCP 客户端1socket()2可省略bind()可省略3recvfrom()sendto()listen()
2026-03-09 00:58:56
372
1
原创 Linux-基于网络爬虫技术的天气数据查询
一,获取报文数据复制这个网址 去掉s并且获取appkey和sign 再替换到到上图二的网址中,打开修改好的网址这样子我们就可以用了点击network 找到右下角的ip地址和端口ip地址:103.205.5.206 端口:80点击row完全展开,复制全部的报文去写字本(方便等会编辑好放进代码中)二,要求实现下图的功能三,编程思路1,模块图。
2026-03-06 23:52:46
256
原创 Linux-网络通信02-UDP 与 TCP Socket
发送方多次发送数据,接收方因为流式传输特性,无法正确区分每次发送的数据边界,导致无法正常解析。
2026-03-06 19:57:22
445
原创 Linux-网络通信01-基础概念与网络模型
网络通信本质上依然属于进程间通信(IPC)的范畴,只不过是不同主机之间的进程间通信。应用程序↓ 应用层(HTTP/FTP/DNS...)↓ 传输层(TCP/UDP + 端口号)↓ 网络层(IP + IP地址)↓ 接口层(网卡 + MAC地址)↓ 物理网络(电信号/光信号)
2026-03-05 21:57:28
383
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅