- 博客(49)
- 收藏
- 关注
原创 ADC
一般采用逐次逼近法的ADC会先拿采用电压Vadc跟基准电压Vref的1/2进行比较,如果Vadc>Vref,则结果为1,否则结果为0。比如一个比较了8次的ADC外设,它就称为8位ADC,其结果是0~255之间的一个数值,设该数值为n,那么实际电压就是Vref * (n/255)。并且2440的ADC外设是为了检测LCD屏的触控功能的,由于2440只有一个ADC,所以2440在内部设计了8个通道。ADC的工作原理是将模拟信号分割成一系列离散的取样,并将每个取样值转换为相应的数字表示。第144行:使能预分频。
2024-09-25 18:55:54
889
原创 I2C
同时,SCL信号由数据启动发送的设备提供。由于空闲时SDA和SCL都是高电平状态,每次通信前,发送方首先发送一个“起始”信号,其实信号就是在SCL为高电平时,SDA发送一个低电平。单字节读时序比写时序要复杂一点,读时序分为 4 大步,第一步是发送设备地址,第二步是发送要读取的寄存器地址,第三步重新发送设备地址,最后一步就是 I2C 从器件输出要读取的寄存器值,我们具体来看一下这几步。上图所示是IIC的总线的使用场景,所有挂载在IIC总线上的设备都有两根信号线,一根是数据线SDA,另一根是时钟线SCL。
2024-09-25 00:15:05
799
原创 UART配置流程
比如我们选择使用PCLK,即50M,波特率为9600,那么公式计算的结果就是324.52,取整得325,把这个数存到UBRDIVn波特率就设置好了,简直不要太方便。如果我们把uart的时钟设置为FCLK,那么uart的实际工作频率就由该寄存器的[15:12]决定,有兴趣的读者可以自行尝试。uart状态寄存器是用来查询uart的状态的,第2比特可用于判断数据是否发送完毕,类似于51的RI,同理,第1比特和第2比特的区别在于一个是位移寄存器为空,另外一个是位移寄存器不一定为空。
2024-09-23 23:58:07
2205
1
原创 时钟的配置
也就是arm内核的工作频率,其实也是代码执行的速率。上图是时钟框图中的左上角部分,红圈这个部分是一个选通器,意思是2440的时钟源可以选择:外部晶体振荡器或者是外部时钟。2440中的大多数外设是可以被关闭的,关闭的方法其实就是不提供时钟,时钟控制寄存器就是用来管理这些外设的时钟的。为了操作方便,2440设置了一个名字也叫MPLL的寄存器,这个寄存器中有三个域P,M,S。,我们的思路就是配置MPLL寄存器,想办法让它输出一个400M,再找找用于分频的寄存器,把Hclk和Pclk分频成100和50。
2024-09-22 23:00:19
1233
原创 单片机基础知识1 | 中断
1.GPIO通用目的输入输出.2.Kernel内核中的寄存器不能被寻址Kernel外设寄存器可被寻址,有固定地址,使用时当作全局变量使用3.看门狗定时器它实际上是一个,一般给看门狗一个数字,程序开始运行后看门狗开始计数。如果程序运行正常,过一段时间应发出指令让看门狗,重新开始计数。如果看门狗增加到就认为程序没有正常工作,强制整个系统复位。
2024-09-22 00:30:56
459
原创 汇编语言的基本指令及基本使用操作
当执行 SWI #7 时,处理器会跳转到一个预定义的中断处理程序,该程序会根据 #7 的值来执行特定的操作。例如,在某些系统中,SWI #7 可能被用来请求特定的系统调用,如获取系统时间或处理文件操作。对于加减法指令,在操作数和结果是有符号的整数时,如果发生溢出,则V=1;将内存地址为R1+8的字数据读入寄存器R0,这里的#8作为12位立即数是可以省略的。在结果是有符号的二进制补码情况下,如果结果为负数,则N=1;把某个数展开成2进制,这个数的最高位1至最低位1之间的二进制数序列的位数不能超过8位;
2024-09-20 00:02:18
3168
原创 Linux驱动开发 ——架构体系
这是一种非易失性存储器,用于永久存储数据和程序。与随机存取存储器(RAM)不同,ROM中的数据在断电后不会丢失,通常用于存储固件和系统启动程序。它的内容在制造时或通过特定过程写入,通常不可修改。是计算机中重要的内存类型,主要用于临时存储正在处理的数据和程序。
2024-09-19 00:41:44
842
原创 framebuffer 帧缓冲
Framebuffer(帧缓冲)是Linux系统中为显示设备提供的一套应用程序接口,它将显存抽象为一种设备,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。原理:通过内存映射技术向显存空间中写入rgb颜色值;
2024-09-11 15:59:01
887
原创 哈 希 表
是一种数据结构,它通过某种函数(称为哈希函数)将元素的关键码映射到表中的位置,以实现快速的插入、查找和删除操作。哈希表的查找时间复杂度为O(1),这使得它在处理大量数据时非常高效。然而,哈希表也面临哈希冲突的问题,即不同的关键码通过哈希函数计算得到相同的位置,这种情况下需要通过解决冲突的方法来处理,如链地址法,开放地址法。
2024-09-09 22:27:02
580
原创 内核链表
但应用层不能使用上述两个宏,处理方法:将节点作为结构体第一个成员(结构体第一个成员首地址为结构体的地址)组成:将链表的结点作为结构体成员存在 ,只放指向前驱结点和后继结点的指针。offsetof 获取结构体中的成员到结构体开头中的偏移量。container_of通过偏移量获取结构体首地址。结点将作为结点保存在结构体中,不能定义为指针。内核链表:双向循环有头链表。
2024-09-05 19:43:41
904
原创 内存泄漏 | 双向链表
内存泄漏是一个常见的问题,尤其在长时间运行的程序中更为突出,因为它会导致系统资源的逐渐耗尽。3. 循环引用:两个或多个对象相互引用,形成一个循环链表,如果这些对象没有被其他部分访问,但它们之间存在引用,那么它们的引用计数永远不会为零,导致内存泄漏。• 频繁的垃圾回收:为了清理不再使用的对象,垃圾回收器会频繁运行,导致程序暂停(Stop-The-World,STW)次数增加,用户体验变差。• 程序性能下降:随着内存泄漏的积累,程序可用的内存逐渐减少,导致程序运行速度变慢。
2024-09-04 20:32:33
502
原创 数据结构
一组用来保存一种或者多种特定关系的数据的集合(组织和存储数据)程序 = 数据结构 + 算法程序的设计:将现实中大量而复杂的问题以特定的数据类型和特定的存储结构存储在内存中,并在此基础上实现某个特定的功能的操作;
2024-09-03 20:37:57
687
原创 数据库
函数原型 int sqlite3_open(const char *filename, /* Database filename (UTF-8) */sqlite3 **ppDb /* OUT: SQLite db handle */);create table if not exists 表名称(列名称1 数据类型,列名称2 数据类型,列名称3 数据类型,....);create table 表名称(列名称1 数据类型,列名称2 数据类型,列名称3 数据类型,....);
2024-08-29 18:52:30
1147
原创 IO多路复用
1.多路复用是指通过一个线程同时监听多个IO事件的就绪状态。在传统的阻塞IO模型中,每个IO操作都需要一个独立的线程来处理,当有大量的IO操作时,会导致线程数量的增加,从而带来线程切换和上下文切换的开销。而多路复用通过使用一个线程来监听多个IO事件,避免了线程数量的增加,减少了线程切换和上下文切换的开销。2.IO事件就绪通知:IO多路复用机制通过操作系统提供的系统调用(如select、poll、epoll等)来监听多个IO事件的就绪状态。
2024-08-28 21:04:12
940
原创 并发服务器---IO多路复用
单循环服务器:同一时刻只能处理一个客户端任务并发服务器: 同一时刻,只能处理多个客户端的任务实现方法:多进程 多线程 IO多路复用。
2024-08-27 21:12:50
881
原创 粘包现象 | wireshark抓包的使用
TCP协议为了保证传输效率,可能会将多次send调用发送的数据合并在一个TCP报文中发送出去。这样,接收方在读取时就可能遇到粘包问题,即无法直接从字节流中识别出各个独立的数据包。1.自己规定数据之间的间隔符,"\aa";2.指定要发送的数据长度3.自己将数据打包 struct。
2024-08-23 22:23:45
842
原创 UDP通信函数补充 | TCP
将套接字( sockfd )变成被动的连接监听套接字(被动等待客户端的连接),至于参数 backlog 的作用是设置内核中连接队列的长度(这个长度有什么用,后面做详细的解释),的挂起连接队列中提取第一个连接请求,创建一个新的已连接套接字,并返回一个新的文件描述符,该文件描述符引用这个新套接字。,不是这个函数完成的,这个函数的作用仅仅是通知 Linux 内核,让 Linux 内核自动完成。对于客户端的 connect() 函数,该函数的功能为客户端主动连接服务器,建立连接是通过。:控制接收行为的标志。
2024-08-22 21:14:27
802
原创 IPC对象通信方式---共享内存 | 网络通信 -编程
共享内存机制其允许两个或多个进程共享一个给定的存储区,这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取错做读出,从而实现了进程间的通信。采用共享内存进行通信的一个主要好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝,对于像管道和消息队里等通信方式,则需要再内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次:一次从输入文件到共享内存区,另一次从共享内存到输出文件。//第二个参数的用处在这里。
2024-08-21 20:25:31
1129
原创 有名管道 | 信号
匿名管道由于没有名字,只能用于具有亲缘关系的进程间通信。为了克服这个缺点,就提出了有名管道(FIFO),也称为命名管道FIFO文件。
2024-08-17 18:51:03
577
原创 信号量 | 进程共享——无名管道
P操作:使用这个资源(个数减1)。尝试获取资源;有则用,无则等。V操作:产生这个资源(个数加1)。释放一个资源;如果有任务则等,无任务则用。
2024-08-16 20:10:32
636
原创 线程的退出 | 锁
传的是退出状态值对应的地址2.执行函数中return4.在任何一个线程中调用了exitwhile (1)//线程的任务函数sleep(1);//线程执行函数中returnif (ret!sleep(3);//取消线程#if 0#endifreturn 0;
2024-08-15 20:03:27
423
原创 进程的退出 | 线程
1.wait 和 waitpid都是 等待子进程状态改变2.wait是一种阻塞调用3.waitpid 可以实现非阻塞调用。
2024-08-14 18:55:34
1226
原创 进程的执行和进程的结束
不需要写入文件路径,只需要传入可执行文件的文件名,可执行文件必须在/bin目录中。l:list path:要执行的文件的路径 arg:要执行的文件的参数,以NULL结尾。v:指针数组 path:要执行的文件的路径 arg:要执行的文件放入一个数组,传数组名。exec函数族用于替换当前进程的映像,允许程序在运行时加载并执行新的程序代码。作用:可以在一个程序中启动另外一个功能,用新的进程段替换当前进程的段.c.最终调用顺序与注册顺序相反 d.函数可以多次注册。e:可以给要执行的程序传递一个环境变量。
2024-08-13 23:58:01
458
原创 进 程
8.孤儿进程,子进程在,父进程不在。4.kill -【】 -9 给进程发信号 killall 可以指定进程名称。2.父子进程的空间:在32位系统中,每个进程拥有4g运行空间(虚拟的)。3.pstree -sp【pid号】 //查看父子进程间的关系、树状图。fork() 通过复制调用进程复制的子进程(复制进程实体|数据代码)返回值:成功:父进程返回子进程的PID号、子进程返回0。Linux系统中,进程间关系是一种父子关系。4.父子进程中,数据相互独立,不受影响。6.孤儿进程会被收养自动变成后台进程。
2024-08-12 19:49:46
712
原创 系统时间的获取 | 文件操作相关函数 |报错函数 | makefile
默认的情况下,make 命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件。有另外一些 make 只对全小写的“makefile”文件名敏感,但是基本上来说,大多数的 make 都支持“makefile”和“Makefile”这两种默认文件名。参数:target:被链接向的文件的路径 linkpath:新符号链接文件。参数:oldpath:要链接向的文件newpath:创建的新硬链接文件。返回值:成功返回1970年到现在的秒数(长整型);
2024-08-08 18:44:02
1103
原创 转换函数 | 目录相关操作 | 命令级函数
mkdir(新目录文件名(区分大小写),777(umask新建文件或者目录时,系统默认会和该数字相减))返回值:成功返回包含路径空间的字符串首地址成功返回将指向buf 失败返回NULL。参数:pathname:路径 mode: mode & ~umask 0002。套入宏,只命中一个,(本身为32bit的数,其中7个为文件类型,只有一位被置1)参数:buf:保存工作路径空间的首地址 size:保存路径空间的长度。参数: pathname:目录文件的名字。返回值:成功返回文件描述符失败返回-1。
2024-08-07 19:34:43
984
原创 文件相关操作 ——标准IO
1.输入输出都是以计算机来说2.一切都当文件看待,包括鼠标,键盘(设备文件)等。3.系统头文件所有都在/usr/include/stdio.h路径下so文件 动态库文件 里面没有main函数,是编译后的.c。
2024-08-05 20:10:18
325
原创 linux
if 条件测试操作 if 条件测试操作 if。d为目录 L软链接 -p管道文件(不同进程共享设备)-s 网络文件(套接字文件/设备)b块设备。1.if 可以比较目录 一般文件类型 字符串 表达式中,结果为0时为真。2.``为反单引号 中间写命令,直接执行,结果给一个变量 ,并保存。-为普通文件(文本文件,可执行文件,数据类) c字符设备。命令行可以写参数,随参数传入,默认为字符串。* 通配符,写不加$,读加$=不加空格 运算符要加空格。
2024-08-03 23:04:11
743
原创 结构体与链表
1.先声明结构体,再定义变量名。2.在声明类型的同时定义变量。3.直接定义结构体类型变量s1,s2在全局区,若省略student,使用者只能使用定义好的全局变量。
2024-08-01 18:45:17
748
原创 指针的中阶用法
可加static或返回函数结束后依旧存在的,不被销毁的变量。在指针变量前加const,说明该指针常指针,不能改变指针指向,也不能修改指针变量所指向的变量。2. 遍历当前数组,从第二个值开始,比基准元素小的放到左侧数组,比基准元素大的放到右侧数组。堆上申请的空间需要手动释放:free:空指针传给free,并不会程序崩溃。二分查找(两个指针间不可以+*/,所以计算mid地址时,需要用到减法)字符串在字符串常量区,就算有指针指向,也不能被修改。申请成功时,会返回申请到的地址的首字节地址。返回值是指针为指针函数。
2024-07-30 20:04:36
346
原创 指针及其部分使用
定义指针变量的一般形式:基类型 *指针的变量名如:int *p(此后指针变量只能装整型)此处的*为类型说明符其余地方出现的 * 为指针运算符,要求操作数为指针例:该代码中,指针变量p指向i的地址,*p 为 i 本身i= 100 为直接访问;*p = 100为间接访问例:求两数最大值(通过指针形参改变实参的值)指针在程序中访问地址主要包括以下步骤:1、通过指针变量中的值到内存空间中定位;2.从定位处开始向后偏移sizeof(基类型);3.将偏移好的那部分内存空间当作是一个基类型变量来看。
2024-07-29 17:17:39
311
原创 标识符的作用域与可见性
不加: 要求宏名必须大写 -E要求编译器只做预处理,不编译分为:带参宏 不带参宏(只有宏名 没有内容 表明定义过)带参数的宏定义不是进行简单的字符串替换,还要进行参数替换。其定义的一般形式为:#define宏名(参数表)字符串字符串中包含在括号中所指定的参数。计算三角形面积:带参宏效率高于函数,但不利于代码复用性。
2024-07-27 16:26:23
586
原创 数组作为函数参数
若编写程序时,若需要传的是数组,需要传两个参数:1.传递数组数组名,内部本质为指针 2.数组长度。3.由于实参可以是表达式,而数组元素可以是表达式的组成部分,因此数组元素当然可以作为函数的实参,与用变量作实参一样,是单向传递,即“值传送”方式。4.用数组名作函数实参时,不是把数组元素的值传递给形参,而是把实参数组的首元素的地址传递给形参数组,这样两个数组就共占同一段内存单元.二维数组作为参数传递时,依旧为首元素地址等价于 &a[0],无法算出行数,可以算出列数,因此可以不传列数,只传行数。
2024-07-26 19:24:40
271
原创 函数的调用和嵌套调用
栈区中存放的为:形参,调用函数的返回值,局部变量。一般来说栈区的空间不会很大,Windows系统不超过1MB,Linux系统栈区不超过8MB。实参是形参的复制品,两者拥有不同的内存空间;无法在被调函数中修改主调函数被定义的实参和数值。被调函数有2个或者2个以上时,默认传参次序为自右向左。禁止在实参中进行++、--操作,结果不确定。如果函数递归使用不恰当,会导致堆栈被耗尽,每次函数调用都需要在栈区上申请空间在栈区。自己调自己 不是死循环 栈堆被耗尽 需要找循环不递归的条件。打印指定范围内所有的素数。
2024-07-25 20:15:50
216
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人