- 博客(51)
- 收藏
- 关注
原创 链式队列的实现及其应用
所以,采用第二种思路:删除头结点,移动头指针指向下一个,使之成为新的头结点,它原本的值作为出队的值后再赋值为0。而由于链表中特殊的存在(头结点、尾结点),正好可以用于队列的头指针、尾指针。和释放队列的区别是,最后还保留头结点,因此可以利用头指针指向的下一个来遍历。注意申请两块内存区域,一块用于链表,另一块用于队列的头指针、尾指针。入队新结点需要申请内存,通过尾插方式入队(符合队列头读出,尾写入)第一种如下,删除头结点指向的下个结点,然后更新头结点指向下下个结点。释放思路和出队一样,换新的头结点。
2024-12-15 13:27:47 965
原创 顺序栈及其实现过程
不难看出有顺序表的影子,栈的存储空间就可以看作一张顺序表,只不过因为是栈,对于插入、取出操作有限制,另外还多了栈顶指针的概念。根据2.1顺序栈的结构模型可知,创建时需要分配两块内存空间,因此要malloc申请两次。栈是限制在某一端进行插入、删除操作的线性表,俗称堆栈,其实就和顺序表插入数据元素差不多,注意判断栈是否满了。
2024-12-12 22:33:21 396
原创 线性表之单链表详解
链表作为线性表的,将线性表L = (a0,...ai-1,ai,ai+1...an-1) 中的各元素分布在存储器的不同存储块,称为结点。ai的直接后继结点由此也能看出,头结点的重要性,特别地,
2024-12-12 17:16:13 433
原创 线性表之顺序表
L为表名,ai为数据元素,n为表长,n=0时为空表,n!主要思路是利用两个下标进行移动,判断是否相等,相等则进行删除操作。(因为涉及到所有元素的移动,同时需要提供一片较大的连续空间)由于线性表的特征非常符合顺序存储结构,即。主要还是通过 顺序表结构体中的last成员 值的判断。
2024-12-10 19:12:53 733
原创 LinuxUDP编程
由于的,所以Server端绑定完IP、端口号后,使用recvfrom可以阻塞等待客户端的数据,而且Client端通过sendto发送的数据包直接发送到互联网(也是基于IP、端口号)这种操作是不担保Server端是否收到的,
2024-12-05 19:30:51 411
原创 Linux之TCP三次握手、四次挥手详解
Three-way Handshake,其实就是。、指定自己的初始化序列号为后面的可靠性传输作准备。实质上就是连接服务器指定端口,建立TCP连接,并,交换TCP窗口大小信息客户端connect阻塞、服务端accept阻塞时,进行三次握手:第一次握手:客户端给服务端发一个SYN报文,并指明客户端的初始化序列号ISN-------此时客户端处于SYN_SENT状态首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序列号。
2024-12-05 19:28:47 1330
原创 Linux网络编程基础
以该图为例(左边server往右边client发送数据):发送方经过各层会加上包头进行封包,最终通过驱动发送到路由器,路由器中间可能会经过不同网络,最终发送给接收方,存入它的空间,读取这个数据包就是不断地拆包环节。ARP/RARP:解析地址,比如IP地址---->MAC地址,MAC地址---->IP地址。,内设置流量控制,避免数据流淹没慢的接收方。局域网IP:192.XXX.XXX.XXX、 10.XXX.XXX.XXX。组播IP:224.XXX.XXX.XXX、239.XXX.XXX.XXX。
2024-12-03 20:01:23 904 1
原创 Linux条件变量&线程池详解
避免了多线程对同一块临界资源访问产生的冲突,同一时刻对临界资源的访问,,由此也带来了竞争的问题。即之间时刻都在这把锁,而临界资源是有限的,当的候,,反而降低了运行效率。有没有什么办法可以等生产者线程生产出资源,消费者线程再去竞争锁消费呢?这就是条件变量的作用。正如互斥量保护了【临界资源】,条件变量也保护【条件】资源,当条件不符合时即【条件】资源空缺,消费者线程休眠等待;当【条件】资源产生,消费者线程被唤醒然后去消费资源。这样便解决了线程间等待的问题,提高了运行效率。
2024-12-03 19:50:03 713
原创 Linux信号集、信号的阻塞&信号驱动
信号的三种方式,即使是忽略,也仍然打断了进程的进行(相当于是捕捉了信号,执行的了空函数什么都没做),可如果在访问重要资源时不希望被打断呢?可以用,即,它处于,并不是不响应该信号,而是信号的状态递达delivery:信号产生并递达到进程未决pending:信号产生但未递达到进程,主要是阻塞屏蔽导致的,
2024-12-02 21:38:59 455
原创 Linux进程间通信——信号量&信号详解
SIG_DFL 为默认动作,SIG_IGN 为忽略(函数名是函数的入口地址,这里的sighandler_t 是函数指针类型名 通过typedef void(*sighandler_t)(int)实现,因此自定义函数也要设置成无返回值,参数为1个int型的//由于signal在不同类unix系统的行为不完全一样,系统建议使用sigaction函数。
2024-12-02 21:28:40 1357
原创 Linux互斥量&读写锁
1.临界资源同一时刻只允许一个进程/线程访问的共享资源(比如文件、外设打印机)2.临界区访问临界资源的代码3.互斥机制mutex互斥锁,用来避免临界资源的访问冲突,形象点的说法 好比有一个公共卫生间,进去使用的人会给门上锁,使用完会开锁4.创建互斥锁5.销毁互斥锁Linux中,互斥锁不占任何资源,所以销毁锁不是必须的,可利用其返回值查询锁状态,锁定时返回EBUSY6.申请互斥锁(P操作)7.释放互斥锁(V操作)
2024-12-01 21:27:45 492
原创 Linux线程详解
在引入线程之前,作为(分配得到了CPU的时间、内存等),操作系统通过调度算法实现多进程并发执行,共用CPU,但由于创建或撤销进程时,系统都要为之分配或回收资源,限制了并发程度的提高。后来,为了减少进程间切换的开销,可把进程作为资源分配单位和调度单位两个属性分隔开,于是有了,甚至。采用多线程来实现多任务开发可以极大减小切换开销。Linux中不区分进程、线程,而是通过来实现线程,也叫轻量级进程LWP。由于线程是进程的一部分,
2024-12-01 21:15:31 1140
原创 Linux进程间通信(中)
这类IPC对象有唯一的ID,用key值来关联,并且IPC创建后一直存在,直到被删除。注意:消息内容读到变量的buf里,类型读到msg_type里,消息读取一条,该类型的一条消息则少一条,读完了则阻塞等待消息添加进来。1.生成key值(不是必须的步骤,但通过节点号产生的key值可以确保是唯一的)1.生成key值(不是必须的步骤,但通过节点号产生的key值可以确保是唯一的)6.控制共享内存(常用于删除共享内存,删除前应断开所有进程的连接)(成员包含消息类型、消息内容、其他节点的结构体)和优先级,独。
2024-11-30 20:08:08 681
原创 Linux进程间通信(上)
进程间通信(Inter Process Communicating)主要包括:无名管道pipe、有名管道fifo、内存映射mmap、共享内存shm,消息队列msg、信号signal、套接字socket(多机之间,多用于网络编程)
2024-11-30 19:44:28 767
原创 Linux进程操作(下)
控制终端:由于在 Linux 中,每一个系统与用户进行交流的界面称为终端(shell窗口,本身也是一个控制进程),每一个从此终端启动的进程都依附于这个终端,终端也称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。进程组:进程的集合,进程组长是相关联进程中的父进程,其PID也是进程组ID,也可通过getpgid(getpid())获取。,可以实现父子进程执行不同的程序(即父进程创建子进程,子进程调用exec函数族,shell命令的源码逻辑也是如此),这种进程脱离终端,为什么要脱离终端呢?
2024-11-29 20:31:49 732
原创 Linux进程操作(上)
每个进程,比如shell窗口下敲的命令都是进程,它们的父进程都是shell脚本/bin/bash通过下面的函数获取自身和父进程的PIDgetpid() 返回自身PIDgetppid() 返回父进程的PI父进程创建子进程后,可以,从而让它们执行不同的内容两个进程会(并发),子进程(这样也避免了自动地无限fork)父、子进程有的,互不影响,执行的顺序由操作系统决定。
2024-11-29 20:15:59 962
原创 Linux进程基础
在用户的视角上,这些进程看似同时进行,但不是真正意义上的“同时进行”,因为只有一个处理器,在固定的时刻只有固定的进程被执行了,只不过CPU处理的速度很快,它把一个时间段划分成很短的时间片段,然后在这之间来回切换。这个时间片段短到人无法感知的程度,所以才能让用户感觉是多个进程同时在进行。并发也称时分复用,是系统对于进程的一种调度管理其实决定并行的因素不是CPU的数量,而是CPU的核心数量,比如一个CPU多个核也可以并行。
2024-11-28 20:11:14 929
原创 Linux文件操作
创建函数还有一个单独的函数 int creat(filename,mode) mode的值有S_IRUSR 可读 、S_IWUSR 可写、S_IXUSR 可执行 、S_IRWXU 可读可写可执行 ,但用的少,原因是它只创建不打开。文件描述符,范围(3~1023),0、1、2(默认已使用)分别对应标准输入stdin(键盘)、标准输出stdout(显示器屏幕)、标准错误stderr三个标准IO。不同于文件IO使用文件描述符(非负整数)来操作文件,标准IO使用文件流指针,使用上的区别只是定义的变量需要注意一下。
2024-11-28 19:47:20 898
原创 Linux命令操作基础
这个通过按“↑”或“↓”键,便可快速输入之前输入的命令,也可以使用histroy [number] 来直接显示之前的number条命令。vi是一种方便的文本编辑器,Linux系统一般是自带的,而vim是在vi的基础上发展升级的,平常使用上没太大区别,在。很多时候容易忘记命令或文件名(也不好记住),可以输入命令或文件名的前几个字符然后按下。命令模式下按下a/i/o进入到此模式,可以进行文本编辑,按下ESC可以退回到命令模式。的提示符,如果当前用户为超级用户,提示符为“#”,其他用户的提示符均为“$”
2024-11-27 21:02:53 1116
原创 Linux操作系统概述
MCU和MPU的区别:MCU,Micro Controller Unit,微控制器,俗称“单片机”,内置CPU、存储器和各种外设接口,特点是单核,小容量存储,控制简单(执行刺激-响应式的过程控制),适合数据采集、家电控制MPU,Micro Processor Unit, 微处理器,需要外挂大容量存储器(如DDR和FLASH),多核,高主频(几GHz),适合高性能计算和复杂算法处理MCU不具备内存管理单元MMU。
2024-11-26 19:52:10 1127
原创 FreeRTOS——列表及列表项
对于pvOwner、pxContainer 可以简单理解成,列表项是文件,pxContainer是文件夹,pvOwner是执行程序。每调用一次这个函数列表的 pxIndex变量就会指向下一个列表项,并且返回这个列表项的pxOwner变量值。作为多任务的核心,列表和列表项在FreeRTOS中被大量使用,功不可没。FreeRTOS提供了一个函数来完成列表的遍历。列表和列表项是一个数据结构,简单地说,
2024-11-26 19:42:17 567
原创 FreeRTOS——内存管理(下)
(first fit)来分配内存,即寻找第一块能满足申请要求的内存,同时,他还会把相邻的空闲内存合并为一个更大的空闲内存,这有助于较少内存的碎片问题。栈,stack,函数调用时局部变量保存在栈中,当前程序的环境也是保存在栈中,特别地,可以从堆中分配一块空间用作栈。——按照调用者的要求分配合适大小的动态内存区,返回该内存块的首地址,如果没有足够的内存,返回空指针。堆,heap,实际就是一块空闲内存,需要使用规定的管理函数来操作,如malloc、free。动态内存:即ZI-Data堆空间,分配在堆区,用户。
2024-11-25 20:03:30 1008
原创 FreeRTOS——内存管理(上)
将.c文件生成标准库,当不想把项目源码授予他人时,可以通过这个文件来把文件打包成lib文件.c/.cpp源文件,生成目标文件,armasm与汇编相关使用armlink链接对象文件,根据程序的调用把各个.o文件的内容链接起来,最后生成程序的axf映像文件,并附带程序各个域大小的说明,包括code、RO-data、RW-data、及ZI-data的大小使用fromelf生成下载格式文件,他根据axf映像文件转换成hex文件,并列出编译过程中出现的错误(Error)和警告(Warnning)数量。
2024-11-25 19:49:35 804
原创 FreeRTOS——低功耗管理
是的话,终止休眠状态,当前systick计数值放到systick装载寄存器中,启动systick,重新赋值装载寄存器值为一个系统的tick周期,开启中断。否则装载休眠systick装载值,清除systick当前计数值,启动systick定时器,进入休眠前的工作,然后休眠。补偿系统的tick周期值,也就是说运行了多少时间,因为调度器恢复的时候,会根据tick值进行遍历,保证实时性。四种唤醒方式,WKUP引脚上升沿,RTC闹钟事件,NRST引脚的复位、IWDG独立看门狗的复位。
2024-11-24 22:44:12 1029
原创 FreeRTOS——软件定时器
区别于硬件定时器,软件定时器是基于系统时钟节拍tick值实现的,之所以叫软件定时器是因为它不需要额外使用硬件定时器,而且可以创建多个,因此也叫软件定时器组因为是定时器,定时时间到了,总要做点什么。硬件定时器定时时间到了一般会触发定时器中断或触发其他外设,而使用软件定时器时,会用到创建时指定的回调函数,由守护任务管理可裁剪,通过宏来开启/关闭软件定时器的功能扩展定时器数量,允许创建更多定时任务定时模式有单次/周期,周期就是按照定时时间重复执行回调函数用途可以是闹钟、智能家居自动化控制。
2024-11-24 22:16:18 1332
原创 FreeRTOS——事件标志组
事件是实现的机制,用于同步,。(注意与二值信号量区分)与信号量不同的是,事件可以实现的同步,即一个任务可以等待多个事件的发生:可以是任意一个事件发生时唤醒任务进行事件处理;也可以是几个事件都发生后才唤醒任务进行事件处理。同样,也可以是多个任务同步多个事件。实际上,
2024-11-23 22:53:12 1127
原创 FreeRTOS——互斥信号量
一种特殊的二值信号量,具有防止优先级翻转的特性,可临时提高低优先级任务(让其释放信号量),让任务独占资源,也因为这样特殊的优先级继承机制,它只能在任务中起作用FreeRTOS中的互斥信号量包含两种:mutex、recursivemutex,后者可以解决mutex可能出现的死锁问题2.2工作原理2.2.1优先级继承核心关键:低优先级任务临时提高优先级,有机会释放信号量,从而高优先级得以获取2.2.2解决死锁死锁是由于占用锁的任务在未释放前,继续占用锁,相当于把自己锁住递归互斥信号量。
2024-11-23 22:39:37 436
原创 FreeRTOS——信号量
信号量是应用层面实现任务与任务或任务与中断间通信的机制,可以类比裸机编程中的标志位当信号量被获取了,信号量值变为0;当信号量被释放了,信号量值变为1。把这种取值只有0与1两种状态的信号量称之为二值信号量。创建二值信号量时,系统会为创建的二值信号量分配内存二值信号量是一种长度为1,消息大小为0的特殊消息队列。因为这个队列只有空或满两种状态,而且消息大小为0,因此在运用时,只需要知道队列中是否有消息即可,而无需关注消息是什么取值为0~n(n>1具体用户决定)的信号量。
2024-11-22 22:51:21 937
原创 FreeRTOS——消息队列
xQueueGenericCreat其中参数queueQueue_Type_BASE 属于队列的一种类型,基于队列创建了很多这样的类型,包括互斥锁、计数信号量、二值信号量、递归锁,可以看出:信号量基于队列实现。xQueueSend——实际接口为xQueueGenericSend(多了一个参数queSend_TO_BACK,有关入队类型的,尾插、头插或覆盖入队)头指针赋值,未读消息个数为0,写入指针赋值给头指针,读出指针赋值为头指针+(长度-1)*ItemSize,读写锁解锁。
2024-11-22 22:13:02 1197
原创 FreeRTOS——临界段
可以看出:两个打印任务“打架”了,原因就是两个任务优先级相同,其中一个任务执行时,遇上另一个任务从阻塞恢复成就绪态时,就影响了上个任务。即:中断屏蔽门限值5,>=5的中断都被关 (这个是用来关中断的) 同时 内核调度中断优先级为最低的15。这对API成对使用,其实很好操作,就是把要保护的代码,用这两个API上下包裹住。关中断,临界段嵌套值++(这个值在内核启动时初始化为0,后续如果嵌套就再自增)函数内部:临界段嵌套值 — — (说明确实需要成对出现,不然是无法恢复中断的)可以看出,两个任务不会再打架了。
2024-11-21 21:09:08 756
原创 FreeRTOS——多任务调度
Reset_Handler复位程序是系统上电后执行的第一个程序启动代码的主要功能:初始化堆栈指针SP初始化程序计数器指针PC设置堆、栈大小设置中断向量表的入口地址调用SystemInit()函数完成初始化设置C库的分支入口__main,最终指向用户所写的main函数。
2024-11-21 13:45:29 1791
原创 FreeRTOS——多任务基础
Task Contro Block,每个任务都有一些属性需要存储,FreeRTOS把这些属性集合到一起,用一个结构体来表示,即TCB_t (任务创建时自动会分配),有了TCB,调度器在调度时才便于恢复各个任务上次执行的进度。:任务调度器在进行任务切换的时候会将当前任务的现场(CPU寄存器值、局部变量等)保存在此任务的任务堆栈中,等到此任务下次运行的时候就会先用堆栈中保存的值来恢复现场。空闲任务的优先级最低,为0。每个任务都有自己的栈空间,应用不同,每个任务需要的栈大小也是不同的。
2024-11-20 15:21:38 810
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人