自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 ARM切换工作模式,异常处理

例:MSR CPSR_c,RO;传送RO的内容到CPSR,但仅仅修改 CPSR 中的控制位域。ldr r1,[r0] 类似*运算,取[]就是取寄存器里指向的数据的值。语法:MSR{条件}程序状态寄存器(CPSR 或SPSR)_<域>,操作数。#5 发生软中断,处理中断类似进程里的信号处理signal。拿到swi #5的地址指向的值。例:MRS RO,CPSR;用于将操作数的内容传送到程序状态寄存器的特定域中。

2024-09-06 09:08:26 458

原创 ARM汇编

要用LDR方式,LDR本身作用是加载一个地址到寄存器中,地址就是32根线,刚好可以加载进去,这个数也是32位,所以可以用 ldr sp, = 0x40001000。,把栈指针初始化一下,栈在ARM中,这里是满减栈,所以应该让栈顶指针sp初始化指向0x40001000。操作数2是32位的掩码,如果在掩码中设置了某一位,则相应的在操作数1中清除对应的那一位。:是为了安全而扩展出的用于执行安全监控代码的模式:监护模式也是一种特权模式。:非特权模式,大部分任务执行在这种模式用户模式。

2024-09-03 21:37:40 1304

原创 ARM体系结构

DRAM:动态,一个内存单元需要晶体管+电容,有电荷代表 1,无电荷代表 0,代表 1 的电容会放电,代表 0的电容会吸收电荷,因此。:链接寄存器 保存函数的返回地址(比如有递归调用,每一个函数都应该有一个LR,来保存放回地址,所以,就需要用栈来存,因为栈后进先出):当前程序状态寄存器,运算结果为正,负,进错位,结果为0等标志,中断的使能,工作状态,工作模式。满栈:(先加减再放数据)栈指针指向最后压入栈的数据,数据入栈时,sp先减一(或加一)再入栈。SDRAM:同步,需要刷新,速度较快,容量大。

2024-09-02 21:32:44 973

原创 数据结构——二叉树

/二叉树节点类型int No;}TreeNode;

2024-08-30 21:36:10 1304

原创 顺序循环队列

队头插入元素,队尾删除元素本来应该判空和判断是否存满的条件都是:队头 = 队尾,但这样就没办法区分了,所以,就牺牲一个空间(比如长度为10,但只能存9个),这样判断是否存满就变成了队头 = (队尾+1)% 队列长度。顺序循环队列判空条件:队头 = 队尾顺序循环队列判断是否存满条件:队头 = (队尾+1)% 队列长度3.判空4.判断是否存满5.入队6.出队7.销毁

2024-08-30 19:39:24 253

原创 数据结构——栈和队列

2.每次删除,始终删头结点指向的下一个节点next;出栈(弹栈):将数据元素从栈顶位置取出。栈底:不允许入栈和出栈的一端称为栈底。1.使用尾插法,插入到链表中(入队)栈和队列只允许在固定位置插入和删除。栈顶:允许入栈出栈的一端称为栈顶。入栈(压栈):将数据元素放入栈顶。表可以在任意位置插入和删除。先进先出,后进后出(排队)栈和队列是特殊的表状结构。也可以使用内核链表实现。可以使用内核链表实现。

2024-08-29 20:50:21 537

原创 双向循环链表,内核链表

((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 根据当前成员的地址(小)获得节点首地址(大结构)存在的意义:无论node在大结构中的哪个位置,都可以找到大结构的首地址,不然只有小结构在大结构的开头,小结构的地址可以充当大结构的地址。(unsigned long)(&((type *)0)->member))):大结构中小结构的偏移量。((type *)((char *)(ptr):把当前成员地址(小结构)转变成大结构。

2024-08-29 20:38:46 1850

原创 数据结构——单向链表

算法:快指针先走k步,慢指针和快指针每次走1步(快指针总是领先慢指针k步),当快指针走到末尾时,慢指针即指向链表倒数第k个节点。无头单向链表,节点插入在头的话,每次头结点都会变,所以有了有头链表,头结点的pNext总是指向链表的第一个节点。算法:快指针pFast每次走2步,慢指针pSlow每次走1步,快指针到达末尾时,慢指针所在的位置即为中间位置。因为快指针第一次比慢指针多1,第二次快指针比慢指针快2,依次类推,环长一定是一个自然数,所以一定能相遇。每次选出最小的,第二小的...最大的,

2024-08-28 21:00:54 873

原创 数据结构——顺序表

例如:查找顺序表中的某个元素所在下标,就可以使用ForeachSeqList函数,搭配FindData函数传参对遍历到的数据进行操作。如果要存放字符串类型的,最好写成以下形式。空间可以不连续,访问元素方便。

2024-08-27 20:47:22 811

原创 sqlite3数据库

1.callback回调函数(只有在select语句时会使用,其余SQL语句只需传入NULL),对找到的数据完成要完成的操作。2.perrmsg是申请空间的来的,所以出错必须要释放。pcontent:指针数组的数组名(指向该条数据。(与SQL语句select后面选择的列数有关)arg:sqlite3_exec给传的参数。ptitle:指针数组的数组名(指向。column:找到的一条数据的。//打开一个数据库文件。

2024-08-22 20:49:06 663

原创 select,poll,epoll

注意:select,poll,epoll都是单任务处理的,一个事件一个事件的处理,后面的只能等前面的处理完才能处理,类似排队。步骤:先初始化文件描述符集(不初始化的话,不知道文件描述符是否可用),遍历文件描述符集,如果事件已经就绪,做相应的操作。1.select监听的文件描述符集合是一个数组,受 fd_set 的大小限制,有上限(1024个)2.epoll监听的事件表在内核层,内核监听事件不需要操作用户层空间提高效率。1.poll监听的文件描述符集合在应用层,内核层监听事件后需要传递给用户层带来资源开销。

2024-08-21 19:20:38 719

原创 TCP并发服务器

监听文件描述符集合,将所有要监听的事件加入集合中,使用select监听所有事件,当集合中有事件发生, select不再阻塞,同时select会将产生事件的文件描述符留在集合中,而把没有产生事件的文件描述符从集合中踢出,所以留在集合中的文件描述即为产生事件的文件描述符,对其处理即可。将一个文件描述符设定为异步IO,当IO有事件发生时,内核会向用户层发送SIGIO信号提醒用户层处理事件。//将fd设置为异步IO(文件描述符,发生可读事件时,会发送信号通知)fcntl(fd,F_SETFL,flags);

2024-08-20 21:38:18 824

原创 TCP通信,HTTP协议

TCP包头组成:20个字节(源端口号、目的端口、序列号、确认号、校验和、标志位、滑动窗口大小、紧急指针。2.流式套接字:数据以流的形式连续的传输,有可能产生数据粘连,解决方式(固定长度、数据包间设定间隔。1.数据报套接字:每一包数据传输的目的可能不同,所以每一包需要单独处理(MTU:1500):接收到数据的编号(只有当ACK为1时,该位有效)、确认号即想要让对方下次发送数据的序号(滑动窗口:用来控制接收和发送窗口的大小,来实现对流量的控制。协议://主机:端口号/资源路径。

2024-08-19 11:28:48 604

原创 TCP网络编程

1.创建用来通信的套接字(socket)2.绑定IP地址和端口号(bind)2.UDP资源开销小,实现机制简单。3.UDP是无连接的(面向数据包)2.发送连接请求(connect)4.处理连接请求(accept)1.创建套接字(socket)1.不安全不可靠的传输方式。成功返回一个新的文件描述符。3.发送数据(send)4.接收数据(recv)3.监听(listen)5.关闭(close)

2024-08-16 19:33:30 1021

原创 消息队列,共享内存,信号

进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信机制。/* 当 cmd 为 IPC_STAT 或 IPC_SET 时使用 *//* 当 cmd 为 IPC_INFO 时使用 */ipcrm -Q/M/S Key 删除ipc对象的消息队列/共享内存/信号灯。/* 当 cmd 为 SETVAL 时使用 */ipcrm -q/m/s 消息队列ID/共享内存ID/信号灯ID。

2024-08-14 22:16:21 739

原创 无名管道,有名管道

练习:实现一个进程读一个进程写。

2024-08-09 20:03:44 290

原创 互斥锁,信号量

资源数 == 0 申请操作会阻塞,直到资源数不为0,申请得到资源后继续向下执行。注意:互斥锁不能同步,多个任务依然保持异步执行,但是可以解决资源竞争。申请:资源数 > 0 申请操作让资源数-1。信号量是一种资源(可以初始化、销毁、申请、释放)互斥锁主要是用来防止多个线程任务竞争某个资源。释放操作让资源数+1。

2024-08-08 19:58:12 1033

原创 进程,线程

第一个参数可以只传要执行的代码的文件名,不用传路径,它会在一个叫系统路径PATH下寻找hello,所以要把hello放在系统目录下。pthread_join具有阻塞功能,线程不结束,会阻塞等到直到线程结束回收线程空间。wait 回收进程空间 回收线程 pthread_join。参数的结尾必须以NULL作为参数的结束标志,第一个参数传递的是要执行文件的路径。根据环境变量的名字获得环境变量对应的值。利用当前的进程空间执行另外一份代码(同一个进程空间)v:参数以指针数组形式传递。

2024-08-07 21:51:32 945

原创 进程创建,进程消亡

虚拟地址:通过虚拟技术,将外部存储设备的一部分空间,划分给系统,作为在内存不足时临时用作数据缓存。当内存耗尽时,电脑就会自动调用硬盘来充当内存,以缓解内存的紧张。父进程中打印自己的PID和两个子进程的PID。编写一个代码实现,一个父进程创建2个子进程,子进程中打印自己的PID和父进程的PID。

2024-08-06 21:04:25 210

原创 目录文件操作,链接文件

功能:创建目录参数:pathname:目录文件的路径mode:目录文件的权限返回值:成功返回0失败返回-1注意:1.r 决定是否目录下可以查看其余文件信息2.w 决定目录下的文件是否能够新建3.x 决定目录文件是否能够进入。

2024-08-02 19:35:20 761

原创 标准IO流

使用fread和fwrite,写入和读出的数据类型要一致,不然可能会乱码,比如fwrite时写入的char name[32],占32个字节,但fread读出时,定义的结构体中char name[20],它会按照20个字节读出,会乱码。从结果可知,是按结构体为单位写入文件的,一个stu_t类型的变量占44个字节,写入了4个stu_t类型的变量,所以共占176个字节。练习:将一个文件中的内容拷贝到另一个文件中。fgets不会去掉用户输入的\n字符。gets会去掉用户输入\n字符。结果:net = 1。

2024-07-31 18:53:15 160

原创 shell命令,IO流

tar -zcvf 文件名.tar.gz 文件名/* 例:tar -zcvf homework.tar.gz homework/*Linux内核:Linux操作系统的核心代码,包括对CPU管理、硬件设备管理、内存管理、文件系统管理、进程调度管理等。4. - 普通文件 保存数据信息的文件(代码、图片、音视频、压缩包等)[a-z]:匹配a-z之间的任意字符 例:ls [a-z][1-9].txt。stdin 标准输入流 行缓存。

2024-07-30 20:03:45 949

原创 内存管理,链表

比strcpy安全,防止内存越界,最多拷贝31个元素,还剩一个存‘\0’1.函数体内部的局部变量会随函数结束被回收,可以考虑存放到堆区空间中避免随函数结束回收。当使用strcat、strcpy、strcmp函数时可能会产生内存越界。注意:操作指针时,注意指针指向的空间是否存在?4.单向链表、双向链表、内核链表、循环链表。如果成功,返回指向申请空间的指针。申请size个字节的堆区空间。size:申请空间的大小。2.要修改谁就传谁的地址。4.让头结点pnext指向新申请的节点。1.数组是有限个元素的集合。

2024-07-28 20:33:53 491

原创 结构体,共用体,枚举,位运算

/传参传的是结构体数组的数组名(s),访问用stu[i].name这种类型。//传参传的是结构体指针类型(&d),访问用‘->’3.^可以实现两个数的交换(a ^ 0 = =a , a ^ a == 0)1.枚举常量第一个值默认为0,后面的枚举常量为前一个枚举常量的值+1。2.枚举类型对应的变量的值应该为枚举常量中的值之一。

2024-07-26 20:33:53 419

原创 指针函数,函数指针,结构体

就是让p这个函数指针指向Add这个函数,p(num1,num2)等价与(*p)(num1,num2),意思就是取p这个函数指针所指向的值,也就是函数本身。虽然返回了str,但是str是一个局部变量,函数体结束,局部变量会被回收,地址是返回了,但里面没有值,相当于返回了一个野指针。//这样赋值是对的,“hi”是char *型的,*pstr也是char* 型的。结构体访问成员变量最终的类型由成员变量的类型决定。函数指针是指针,占8个字节空间,指向函数。指针函数是函数,函数的返回值是指针。

2024-07-25 19:10:32 976

原创 指针数组,数组指针,二级指针

表示指针数组pstr中有5个元素,每个元素均为char*型指针,5个元素分别存放"hello","world","how","are","you"这5个字符型常量的首地址。4.strcpy(pstr[0],pstr[1]),不能完成赋值操作,因为"hello" 和 "world"是字符型常量,值不能改变,所有要想完成赋值操作,要写成。例:实现char *pstr[5] = {"hello","world","how","are","you"};//改变指针的指向,但值没变,指数存的地址发生了改变。

2024-07-24 21:18:38 699

原创 数组和指针的关系

1.字符串在函数中传参时,只想让函数体内使用字符串,而不允许通过指针改变字符串的值使用const。const修饰*p,p可以修改指向的空间,但不能利用该指针修改指向空间中的值。2.定义指向字符串常量的指针,最好加const。1.数组的数组名a是指向数组第一个元素的指针。指针[n] == *(指针 + n)3.C语言中所有指针均可以使用[]访问空间。练习:封装一个函数,传入一个字符串,对字符串实现倒置。指针用来操作数组中的数据。const 指针只读不能写。

2024-07-23 20:08:11 513

原创 条件编译,指针

4.*p = *q //p中存放的是0x1000,p指向a没变,但修改了a中值,a=200;2.*p = b //p中存放的是0x1000,p指向a没变,但修改了a中值,a=200;3.p = q //p中存放的是0x3000,p变成指向b。1.p = &b //变成p中存放的是0x3000,p指向b。int 占4个字节,&a:取的是a在内存中占的4个字节的首地址。p = a的地址+4。//p中存放的是0x1000,p指向a。//q中存放的是0x3000,p指向b。

2024-07-22 19:32:45 668

原创 函数的传参,递归函数,宏定义,头文件

----include ---- add.h add.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明。|--- mul.h mul.c中 用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明。|--- sub.h sub.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明。jisuanqi--------src ----- main.c 主函数的实现。2.带参宏没有参数类型、返回值、传参的概念。

2024-07-21 20:21:35 992

原创 函数,字符二维数组

Num不会赋值成功,static变量编译时,就会开辟空间,代码执行结束时回收变量但作用域还是离它最近的{},超过作用域,就不能使用了,但它在内存中存在.遍历字符串,当两者字符相等并且str1[i]和str2[i] 都不等于'\0'时,继续向后遍历。优先存放到CPU内部的寄存器中,如 果寄存器存满了,等价于auto存放在栈区中。局部变量作用域在离定义该变量最近的大括号内。2.代码执行到变量定义时为变量开辟空间。1.限定变量的作用域只能在本文件中使用。3.超过变量的作用域回收变量空间。

2024-07-19 20:48:22 850

原创 嵌入式学习第七天

char str[6] = {'h','e','l','l','o','o'} //打印时,会出现越界异常,没有找到‘\0’,打印时,会一直向后找,直到找到‘\0’,所有可能会出现乱码。判断字符串相等时,if(0==strcmp(str1,str2)) 和 if (!char str[] = {"hel\0"} //五个字符,字符串结尾有一个默认的‘\0’char str[] = {'h','e','l','l','o'} //5个字符。结果 == 0 str1 == str2。

2024-07-18 20:06:43 527

原创 嵌入式学习第六天

表示有一个值为0的元素,不要和局部初始化混在一起。内层循环进行交换操作(i),交换次数:len - 1 -j。定义变量时没有给定数组元素个数,通过给定初值的个数决定数组元素个数。求最大值,最小值,只需要将数组里的值赋给max/min,不涉及交换数组中的元素(temp)只给定一部分元素的值,没有给定初值的元素会被默认赋值为0。使用双层for循环实现,外层循环控制轮数(j),轮数:len - 1次。

2024-07-17 19:27:47 403

原创 嵌入式学习第五天

3.switch只与case后面的值比一次,然后顺序向下执行直到break或者switch结束。双层switch中,里层switch结束,如果没有break,外层switch会继续向下执行。y是偶数的表达式: 0==y%2等价与!2.y是奇数的表达式: 1==y%2等价与y%2。1.逻辑&&优先级高于逻辑||

2024-07-16 19:04:10 161 1

原创 嵌入式学习第四天

5.在今天的作业求三角形的面积中,用到了开平方,要先声明#include <math.h>头文件,然后使用sqrt()库函数,注意在gcc编译时要加上-lm(链接数学库),否则编译不通过。3.小细节:if分支语句中最好写成if(0 == Num %2 )这种形式,不要写出if(Num % 2 == 0)这种形式,如果少些一个=,变成Num %2 = 0,变成了赋值表达式,编译也不会报错,不容易发现错误。2.在内存中,逻辑真假用1,0表示,但不是只有1为真值,所有非0都为逻辑真。逻辑与:一假为假,全真为真。

2024-07-15 20:06:07 301

原创 嵌入式学习第三天

结果为ch = -32,480的二进制为1 1110 0000,char占8bit,所以在内存中保存的是1110 0000,1位符号位+7位数据位,110 0000是数据的反码形式,其原码为010 0000,故结果为-32。a - 20 > 0 结果应该为真, a - 20 相当于无符号整数类型+有符号整数类型,结果会被隐式类型转换为无符号整数类型,而0是最小的无符号整数,所以a - 20 > 0 结果为真。2.整数类型中无符号类型精度大于有符号类型精度。3.浮点数类型精度高于整数类型精度。

2024-07-13 18:04:12 387

原创 嵌入式学习第二天

8.75 1000.11 1.00011*2^3 必须以1开头,所以可以去掉1变成.000113+127=130 指数都要加上127,因为指数是8位,指数范围是-127到128 ,指数偏移量为127,所以+127为了让负数变成正数存储。浮点数->二进制形式->科学计数法转换->小数点后存入尾数中->指数位+偏移位(float+127 double+1023)以二进制存入指数位。八进制的1位 == 二进制的3位。十六进制1位 == 二进制的4位。1位符号位+15位数据位(补码)

2024-07-12 21:51:59 1051

原创 嵌入式学习第一天

2024-07-11 21:42:31 119

空空如也

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

TA关注的人

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