自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 在ARM开发中 volatile与const关键字的关键用途

const 和 volatile 是两个极其重要的关键字。它们不仅是语法规则,更是与硬件交互、保证程序正确运行(尤其是在涉及编译器优化时)的关键。

2026-02-17 17:35:31 607

原创 系统编程的内存零拷贝(Zero-Copy)技术

零拷贝(Zero-copy)是一种优化技术,,特别是在内核空间和用户空间之间传输数据时。

2026-02-17 14:54:39 560

原创 C/C++中的格式化输出与输入snprintf&sscanf

格式化数据写入字符串缓冲区:指向目标字符串缓冲区的指针:缓冲区大小:格式化字符串:可变参数列表:指向一个字符数组的指针,用于存储格式化后的字符串。也就是结果存放的缓冲区。:缓冲区 str 的总大小(以字节为单位)。这是该函数安全性的关键,它确保写入的字符数不会超过这个大小(包括结尾的空字符 \0)。:格式化字符串,与 printf、sprintf 的用法完全相同。它指定了如何格式化后续的参数(例如 %d, %s, %.2f)。:这是一个已经初始化过的可变参数列表变量。

2026-02-16 15:06:32 749

原创 浅谈PC开发中的设计模式搬迁到ARM开发

PC开发有大约二十三种设计模式,在ARM开发中能有效用到的可能也就五六种。但这五六种,一旦用对了,代码质量会有质的提升。

2026-02-16 14:21:32 305

原创 ARM环境日志系统的简单设计思路

在ARM系统开发中(各种架构的嵌入式系统开发也同理),日志系统是至关重要的调试和诊断工具。一个设计良好的日志系统能够帮助开发者快速定位问题、分析系统行为并监控运行状态。

2025-10-05 16:09:52 859

原创 Linux事件循环——高效处理多任务(高并发)

Linux事件循环是一个非常核心的概念,是构建高性能网络服务器、图形界面和应用框架的基石。简单来说,事件循环就是一个,它等待并分派来自多个事件源的事件或消息。。在传统的同步(阻塞)I/O模型中,如果你想从网络套接字读取数据,你的线程会一直卡在 read() 函数那里,直到数据到达。如果你要同时处理多个连接,就需要为每个连接创建一个线程或进程。这在连接数非常多(C10K问题)时,会消耗大量系统资源(内存、上下文切换开销)。事件循环解决了这个问题,它使用和技术,使得。

2025-10-05 12:34:00 1202

原创 系统调用函数——命令行工具readlink

在Linux和其他类Unix系统中,readlink是一个系统调用和命令行工具,用于读取符号链接(symbolic link)的值。符号链接是一种特殊类型的文件,它包含另一个文件或目录的路径作为其数据。换句话说,它是一个指向另一个文件的指针。( 其中,pathname: 符号链接文件的路径;buf: 用于存储符号链接目标路径的缓冲区;bufsiz: 缓冲区的大小。函数返回,成功时:返回读取的字节数;失败时:返回-1,并设置errno )

2025-10-04 21:55:33 512

原创 浅谈内存DDR——DDR4性能优化技术

除了革命性的 Bank Group 和全面的 RASR 功能,DDR4 还引入了其他多项关键技术,这些技术共同支撑了其在频率、容量、功耗和信号完整性上的飞跃。

2025-10-04 21:04:19 1521

原创 浅谈内存DDR——DDR4的RASR/Bank Group等技术

在DDR3及更早的内存中,虽然一个内存芯片内部也划分了多个Bank(可以理解为独立的内存子阵列),可以在不同Bank之间进行流水线操作,但同一时刻只能有一个Bank在进行数据读写。当控制器要访问一个Bank时,必须经历一系列的命令(激活、读写、预充电),在此期间,其他已经准备好的Bank也必须等待,这形成了性能瓶颈。

2025-10-03 16:03:32 1477

原创 再谈Linux多进程——进程处理与守护进程

进程是操作系统资源分配的基本单位,进程是程序执行的实例!!!Linux 内核中管理进程关键数据结构(进程控制块:PCB)通过命令行直接运行程序或者使用系统的启动脚本自动启动程序,表象上的一种创建方式,其底层本质上还是通过fork、exec去创建进程。

2025-10-03 14:05:35 1075

原创 再谈线程同步——读写锁与屏障

核心问题仍然是当多个线程共享同一进程的内存空间(即共享全局数据、堆数据等)时,如果它们同时读写同一份数据,且操作不是原子性的,就会导致数据的不一致性、逻辑错误或程序崩溃。这就是竞态条件。其中原子操作,指一个操作要么完全执行,要么完全不执行,中间不会被打断。像 i++ 这样的操作看似一行代码,但实际上对应了多条机器指令(读、增、写),因此不是原子操作。线程同步的目的就是为了协调多个线程对共享资源的访问,确保在任意时刻,临界区(访问共享资源的代码段)最多只有一个线程在执行,从而避免竞态条件。

2025-10-01 20:58:14 857

原创 异步事件处理(注册与回调)——C函数指针总结分享一般用途篇

回调函数是什么?一个通过被调用的函数。通俗理解:你写了一个函数,但你不是直接调用它,而是把这个函数的“地址”告诉另一个系统或函数(例如一个库、一个框架、或者你自己写的某个模块)。之后,当某个特定的事件发生或者条件满足时(比如按钮被点击、数据接收完成、定时器到期),那个系统或函数就会拿着你给的“地址”回过头来调用你的函数。“回”这个字很重要,意思是“回过头来调用”。调用权不在你手里,你只是提供了函数。注册函数是什么?一个用于回调函数指针的函数。通俗理解:这是那个系统或模块提供的一个“登记处”或“注册接口”

2025-10-01 20:25:17 1274

原创 线程同步机制——生产者消费者问题与FreeRTOS

互斥锁解决临界区互斥问题,条件变量则解决多线程条件等待问题,两者通常相辅相成。

2025-08-24 18:15:36 694

原创 Linux应用编程核心与表驱动技巧

1.系统调用系统调用是用户空间程序与内核之间进行通信的方式。它提供了一组接口,允许应用程序请求内核执行特权操作。在Linux中,系统调用包括(创建新进程)、(读取文件)、(写入文件)等。开发者通常通过系统调用接口来访问操作系统提供的功能。2.进程与线程在Linux中,进程是正在运行的程序的实例。每个进程都有独立的内存空间、文件描述符和执行上下文。系统调用用于创建新进程。系列系统调用用于在进程中执行新程序。线程是一个轻量级的执行单元,可以与同一进程的其他线程共享内存空间。线程可以通过库创建和管理。

2025-08-24 14:02:09 911

原创 操作系统(Linux Kernel 0.11&Linux Kernel 0.12)解读整理——内核初始化(main & init)之内存的划分

MMU:内存管理单元(Memory Management Unit)完成的工作就是虚拟地址到物理地址的转换,可以让系统中的多个程序跑在自己独立的虚拟地址空间中,相互不会影响。程序可以对底层的物理内存一无所知,物理地址可以是不连续的,但是不妨碍映射连续的虚拟地址空间。Linux 内核的内存管理程序采用了分页管理方式。它利用页目录和页表结构处理内核中其他部分代码对内存的申请和释放操作。内存的管理是以内存页面为单位进行的,一个内存页面是指地址连续的 4K 字节物理内存。

2025-01-25 12:07:44 940

原创 操作系统(Linux Kernel 0.11&Linux Kernel 0.12)解读整理——内核初始化(main & init)之控制台工作

在 Linux 内核中,字符设备主要包括和,对这些设备的输入输出涉及控制台驱动程序,这包括keyboard.S 和程序 console.c,还有终端驱动程序与上层程序之间的接口部分。终端驱动程序用于控制终端设备,在终端设备和进程之间传输数据,并对所传输的数据进行一定的处理。用户在键盘上键入的原始数据(Raw data),在通过终端程序处理后,被传送给一个接收进程;而进程向终端发送的数据,在终端程序处理后,会被显示在终端屏幕上或者通过串行线路被发送到远程终端。

2025-01-25 11:33:06 1321

原创 操作系统(Linux Kernel 0.11&Linux Kernel 0.12)解读整理——内核初始化(main & init)之进程调度的开始

是一个可执行的文件,而是一个执行中的程序实例。利用分时技术,在Linux操作系统上同时可以运行多个进程。分时技术的基本原理是把 CPU 的运行时间划分成一个个规定长度的,让每个进程在一个时间片内运行。当进程的时间片用完时系统就利用调度程序切换到另一个进程去运行。因此实际上对于具有单个 CPU 的机器来说某一时刻只能运行一个进程。但由于每个进程运行的时间片很短(例如 15 个系统滴答=150 毫秒),所以表面看来好象所有进程在同时运行着。

2025-01-23 14:12:32 1048

原创 操作系统(Linux Kernel 0.11&Linux Kernel 0.12)解读整理——内核初始化(main & init)之缓冲区的管理

当一个程序需要读取硬盘上的一个逻辑块时,就会向提出申请。而请求读写的程序进程则进入睡眠等待状态。缓冲区管理程序首先在缓冲区中寻找以前是否已经读取过这块数据。如果缓冲区中已经有了,就直接将对应的缓冲区块头指针返回给程序并唤醒等待的进程。若缓冲区中还不存在所要求的数据块,则缓冲管理程序就会调用低级块读写函数,向相应的块设备驱动程序发出一个读数据块的操作请求。该函数会为此创建一个请求结构项,并插入请求队列中。

2025-01-23 12:05:06 1463

原创 操作系统(Linux Kernel 0.11&Linux Kernel 0.12)解读整理——内核初始化(main & init)之硬盘初始化

对和块设备上数据的读写操作是通过进行的。内核每次读写的数据量以一个(1024 字节)为单位,而块设备控制器则是以(512字节)为单位访问块设备。在处理过程中,内核使用了来顺序地缓冲一次读写多个逻辑块的操作。具体的,当一个程序需要读取硬盘上的一个逻辑块时,就会向缓冲区管理程序提出申请。而请求读写的程序进程则进入睡眠等待状态。缓冲区管理程序首先在缓冲区中寻找以前是否已经读取过这块数据。如果缓冲区中已经有了,就直接将对应的缓冲区块头指针返回给程序并唤醒等待的进程。

2025-01-22 11:34:39 1095

原创 操作系统(Linux Kernel 0.11&Linux Kernel 0.12)解读整理——块设备驱动之读取硬盘上的文件

文件读取在高版本的linux是一个复杂无比的流程。一个进程(task_struct)读取一个文件会被存储在自身的file_struct结构中,对应打开文件的索引,然后陷入内核,系统调用,内核态调用最终要调用通用块(理解为硬盘之上)提供的读取接口,向硬盘发请求(request),然后IO调度系统去按照高效的算法调度,磁头去读取。其中的大前提基础是进行request结构初始化其中的块设备操作主要涉及下面这个接口读取硬盘数据到内存中,是操作系统的一个基础功能。读取硬盘需要有。

2025-01-22 11:01:27 1092

原创 操作系统(Linux Kernel 0.11&Linux Kernel 0.12)一手资料解读整理——引导启动程序(Boot)之内存的映射机制

上电启动流程如下:boot/目录下的三个汇编语言文件(bootsect.S 和 setup.S 是实模式下运行的 16位代码程序,采用近似于 Intel 的汇编语言语法,并且需要使用 8086 汇编编译器和连接器 as86 和 1d86。而 head.s 则使用一种 AT&T 的汇编语法格式,并且运行在保护模式下,需要用 GNU 的 as(gas)汇编器进行编译)。操作系统第一阶段如下:(剖析操作系统,一开始就是面向芯片编程,按照芯片手册,当涉及了进程调度则面向多任务处理)

2025-01-21 10:39:55 970

原创 pip 安装 transformers报错处理 error: subprocess-exited-with-error × Preparing metadata (pyproject.toml)...

在conda 虚拟环境中使用 python 的 pip install transformers报错处理 (当前使用的是python3.7.13)(分析可能的原因是依赖包冲突,导致依赖包冲突的原因可能是缺失关键包,版本兼容等问题)由于Hugging Face的transformer依赖包是封装比较完整的包,安装导致的缺失关键包,可能是conda虚拟环境的Python版本优化了部分包。

2025-01-21 10:01:10 3264

原创 Linux系统编程——IO多路复用(select,poll,epoll)详解及应用场景使用分析汇总

IO多路复用是一种操作系统技术,旨在提高系统处理多个输入输出操作的性能和资源利用率。与传统的多线程或多进程模型相比,IO多路复用避免了因阻塞IO而导致的资源浪费和低效率问题。它通过将多个IO操作合并到一个系统调用中,允许程序同时等待多个文件描述符(如sockets、文件句柄等)变为可读或可写状态,然后再执行实际的IO操作。在IO多路复用的实现中,常用的系统调用包括select()、poll()和epoll()。

2024-12-15 14:07:16 1651

原创 数据结构与算法汇总整理篇——链表与二叉树(常用特性的概念及细节处理)

链表与典型的树结构是通过使用指针变量进行链接构建的。

2024-12-14 14:01:36 988

原创 数据结构与算法汇总整理篇——哈希表(细节学习及各容器选取的思考)

散列表(Hash table,也称哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表(数组+链表 或 数组+树)。hashtable(key,value) 就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。

2024-12-14 13:41:54 1373

原创 嵌入式处理器程序设计(处理思路及经验篇)——开发必备的特定设计思维及POSIX标准

嵌入式系统的核心是嵌入式处理器。嵌入式处理器一般划分为如下类型:嵌入式系统分层结构一般可如下:两层结构:硬件层、应用层(软件层) 诸如: MCU裸机系统三层结构:硬件层(原厂芯片用库函数封装驱动)、操作系统层、应用层 诸如: MCU的RTOS系统。

2024-12-11 16:25:21 1392

原创 什么是CPU的上下文切换(context switch的统计与进程排查)

由于Linux是一个多任务的分时操作系统,能够支持远大于CPU数量的任务同时运行。实际上,对于单个CPU核,其处理数据是串行的,同时,这些任务实际上并不是真的在同时运行,而是由CPU进行调度,将时间分片,每个任务占用1个时间片,通过轮流的方式运行,但由于时间片粒度非常小,而CPU速度非常高,造成多任务同时运行的错觉。(就比如排队登记,只有一个登记处的操办人员,组织人员会在登记处排几个队列,每个队列头部数出10个人构成一组。

2024-12-11 15:26:26 1292

原创 程序设计的难点讨论——技术性与思维性和集思广益的并存

程序设计的根本性难点不外乎是和(技术与思维的铸就)。程序,专业的说法,是由数据结构和算法共同组成的用计算机语言表示的逻辑。逻辑和数学实则可以归为算法。前者强调的是算法的顺序性,后者强调的是算法的运算性(复杂度)。绝大部分的程序员做的其实都是建立在已有设施上的劳动密集型工作。而既然是劳动密集型,那么就有一个问题需要解决,即一个难点:分工。广义层面上的分工,下至模块、框架、接口、设计模式、上至IEEE标准说到底都是为了解决这个问题--分工。

2024-12-09 15:05:21 1021

原创 C实用型语法技巧与功能——面向过程的语法实现面向对象的编程效果相关细节

可以指定数组的元素来进行初始化。特别是当需要根据一组#define来保持某种映射关系的同步更新时。

2024-12-09 14:27:26 1096

原创 数据结构与算法汇总整理篇——数组与字符串&&双指针与滑动窗口的联系学习及框架思考

(2) if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,⽽寻找区间是左闭右开区间,所以right更新为middle,即:下⼀个查询区间不会去⽐较nums[middle](2) if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]⼀定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1。

2024-10-27 20:23:46 1007

原创 软硬件开发面试问题大汇总篇——针对非常规八股问题的提问与应答(代码规范与生态管理)

DMA(Direct Memory Access):DMA 是一种允许外部设备(如硬盘、网络适配器等)直接访问主内存而不通过 CPU 的技术。这样可以在数据传输时释放 CPU,让其处理其他任务,提高系统效率。FIFO(First In, First Out):FIFO 是一种数据结构,用于缓存数据。按照“先进先出”的原则,最早进入缓冲区的数据会最先被读取。FIFO 通常用于实现队列或缓冲区。为了确保安全性和效率,可以为每个分区定义访问权限。例如:只读/可写:对于固件区域,可设为只读;

2024-10-27 19:29:21 1372

原创 软硬件开发面试问题大汇总篇——针对非常规八股问题的提问与应答

软硬件开发,从微控制器编程到复杂的嵌入式系统开发,离不开下位机、操作系统、上位机等,涵盖范围很广。

2024-10-26 21:07:13 1522

原创 Orange Pi(H616)出现wiringPiSetup错误解决方案;wiringpi Unable to open /dev/mem or /dev/gpiomem: Permission de

( 当使用自写脚本的形式编译 H616的可执行程序时,出现无法打开设备,访问权限不够 )(可能 build.sh 执行权不够 (尝试给其权限755 776 777均出错))

2024-10-25 12:43:11 708

原创 算法汇总整理篇——贪心与动态规划学习及框架思考

如果某⼀问题有很多重叠⼦问题,使⽤动态规划是最有效的动规是由前⼀个状态推导出来的,⽽贪⼼是局部直接选最优的 不同路径IIdp[i][j] 表示到达位置ij共有多少中方法整数拆分dp[i] 表示拆分数字i的乘积最大值不同的二叉搜索树dp[n] n个节点组成的节点值从1到n互不相同的二叉搜索树数量 dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]num i, root j : left j-1 right i-j j相当于是头结点的元

2024-10-25 10:27:43 1101

原创 项目管理必备Git使用及关键指令(总体结构 + 必要步骤)教你如何协同开发

在linux的Ubuntu发行版,执行以下命令即可安装其他系统可以到官方网站进行下载安装Windows系统的安装包阿里巴巴镜像git作为项目管理工具,配置并初始化一个仓库(repository)、开始或停止跟踪(track)文件、暂存(stage)或提交()都是必要环节。

2024-10-24 15:26:00 892

原创 算法汇总整理篇——回溯与图论的千丝万缕及问题的抽象思考

(回溯的核心:分清楚什么数据作为广度,什么数据作为深度!!!!!

2024-10-24 15:11:06 1234

原创 Linux内核——内核源码的探索+教你如何系统认识Linux内核源码树(推荐方式+推荐工具+推荐书目)

全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,该操作系统是由 Linus Torvalds于1991年10月5号首次发布, 它主要受到Minix和Unix思想的启发,是一个。严格地讲,Linux单指操作系统的内核,加上用户空间的应用程序之后,就成为Linux操作系统。

2024-08-25 14:54:23 1498

原创 动态链接库——深入探讨C++程序中.so技术细节和实现方式及C程序中动静态库的区别(+工程分步骤编译库)

在开发中,动态链接库(DLL)和共享对象(Shared Object).so文件的使用成为提升程序灵活性和重用性的关键手段。如下相关工具,一种用于创建可移植共享库的工具。关于动态链接器的更多信息。一个跨平台的构建系统,简化了共享库的管理和构建。无论是提升程序的模块化程度,还是优化资源使用,动态链接都是一种强大的技术手段。

2024-08-25 11:50:48 1564

原创 ARM架构的BootLoader详解——对于Linux与Baremetal(裸机MCU)

BootLoader的启动方式基本如下:stage1程序(汇编)在内存之外的存储介质中对内存空间进行初始化后,再将stage2程序(C)加载到内存中执行。stage2。

2024-08-23 12:11:10 2822 6

原创 PWM驱动电机系列——PID控制 (各电机设备之间的驱动差异及区别)自动控制系统的性能指标

对于速度跟踪控制来说,增量式 PID 更加适合,因为它直接计算速度变化量。相比之下,位置式 PID 需要计算绝对速度误差,在速度跟踪控制中可能会产生超调和振荡等问题。

2024-08-23 11:28:45 3836

空空如也

空空如也

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

TA关注的人

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