嵌入式操作系统内核原理和开发(最快、最优、最差内存分配算法)
C语言嵌入式操作系统裸机和RTOS

C语言嵌入式操作系统裸机和RTOS C语言嵌入式操作系统裸机与RTOS嵌入式操作系统(Embedded Operating System,简称EOS)是一种专为嵌入式设备设计的操作系统,它具有小巧、高效、实时等特点。
而裸机编程是指在嵌入式系统中,直接与硬件进行交互编程的方式,不依赖于任何操作系统。
RTOS(Real-time Operating System,实时操作系统)是一种提供实时响应的操作系统,针对嵌入式系统而设计。
本文将介绍C语言嵌入式操作系统裸机编程和RTOS编程的基础知识和技巧。
一、裸机编程入门在进行裸机编程之前,我们需要了解硬件平台的相关信息,包括处理器型号、寄存器、外设等。
然后,我们可以通过配置寄存器来初始化硬件设备,设置中断服务程序,并编写具体的功能代码。
在裸机编程中,我们需要注意时间分片、中断处理和资源管理等问题。
二、裸机编程与RTOS的区别1. 复杂性:裸机编程相对简单,因为我们可以直接访问硬件资源。
而RTOS编程需要考虑任务调度、资源互斥、消息传递等复杂的操作系统特性。
2. 实时性:RTOS可以提供更好的实时性能,可以用于要求较高实时响应的应用场景。
而裸机编程的实时性取决于程序的具体实现。
3. 可移植性:裸机编程通常与特定的硬件平台绑定,不具备通用的可移植性。
而RTOS提供了抽象层,可以将应用程序与底层硬件解耦,提高了可移植性。
三、RTOS编程基础1. 任务管理:RTOS允许将应用程序划分为多个任务,并通过任务调度器进行管理。
每个任务执行特定的功能,实现任务之间的并发执行。
2. 中断处理:RTOS提供了中断处理机制,可以对不同的中断进行响应和处理。
中断处理程序可以与任务同时运行,保证了系统的实时性。
3. 时间管理:RTOS提供了时间管理功能,可以进行时间片轮转调度、优先级调度等,确保任务按照预定的时间顺序执行。
4. 同步与互斥:RTOS提供了信号量、互斥锁等机制,用于管理共享资源的访问。
嵌入式linux操作系统原理与应用

嵌入式Linux操作系统是一种针对嵌入式设备设计和优化的Linux操作系统。
它在嵌入式系统中发挥着关键作用,为嵌入式设备提供了丰富的功能和灵活性。
以下是嵌入式Linux操作系统的原理和应用方面的概述:嵌入式Linux操作系统原理:内核:嵌入式Linux操作系统的核心是Linux内核,它提供了操作系统的基本功能,包括处理器管理、内存管理、设备驱动程序、文件系统和网络协议栈等。
裁剪:为了适应嵌入式设备的资源限制,嵌入式Linux操作系统通常经过裁剪和优化,只选择必要的功能和驱动程序,以减小内存占用和存储空间,并提高性能和响应速度。
交叉编译:由于嵌入式设备通常具有不同的硬件架构和处理器,所以嵌入式Linux操作系统需要通过交叉编译来生成适用于目标设备的可执行文件和库。
设备驱动:嵌入式Linux操作系统需要适配各种硬件设备,因此需要编写和集成相应的设备驱动程序,以使操作系统能够正确地与硬件进行通信和交互。
嵌入式Linux操作系统应用:嵌入式设备:嵌入式Linux操作系统广泛应用于各种嵌入式设备,如智能手机、平板电脑、家用电器、工业控制系统、车载设备等。
物联网(IoT):随着物联网的快速发展,嵌入式Linux操作系统被广泛应用于连接的嵌入式设备,用于数据采集、通信、远程控制和智能化管理。
嵌入式开发板:嵌入式Linux操作系统在开发板上提供了丰富的开发环境和工具链,用于嵌入式软件开发和调试。
自定义嵌入式系统:开发者可以基于嵌入式Linux操作系统构建自定义的嵌入式系统,根据特定需求进行定制和开发,实现各种功能和应用。
嵌入式Linux操作系统的原理和应用非常广泛,它为嵌入式设备提供了灵活性、可定制性和强大的功能支持,使得开发者能够构建高度定制化和功能丰富的嵌入式系统。
基于C语言的RTOS实时嵌入式系统设计与优化

基于C语言的RTOS实时嵌入式系统设计与优化在当今数字化时代,嵌入式系统已经成为各种电子设备中不可或缺的一部分。
而实时操作系统(RTOS)作为一种专门用于处理实时任务的操作系统,在嵌入式系统中扮演着至关重要的角色。
本文将重点讨论基于C语言的RTOS实时嵌入式系统设计与优化,旨在帮助开发人员更好地理解和应用RTOS技术,提升嵌入式系统的性能和稳定性。
什么是RTOSRTOS全称Real-Time Operating System,即实时操作系统。
与通用操作系统相比,RTOS更加注重对任务响应时间的保证,能够在严格的时间限制下完成任务。
在嵌入式系统中,时间敏感性是至关重要的,因此RTOS在这种场景下得到了广泛的应用。
C语言在RTOS中的地位C语言作为一种通用且高效的编程语言,在嵌入式系统开发中扮演着举足轻重的角色。
大多数RTOS都是使用C语言编写的,因此熟练掌握C语言对于RTOS开发人员来说至关重要。
C语言具有良好的可移植性和灵活性,能够很好地适应不同硬件平台和系统架构,为RTOS的设计与优化提供了坚实的基础。
RTOS设计原则在设计基于C语言的RTOS实时嵌入式系统时,需要遵循一些重要的原则,以确保系统具有良好的性能和稳定性:任务调度策略:合理设计任务调度策略是RTOS设计的核心。
根据任务的优先级和时间要求,采用合适的调度算法(如优先级调度、时间片轮转等),确保高优先级任务能够及时响应。
资源管理:RTOS需要有效管理系统资源,包括内存、处理器时间、外设等。
合理分配和释放资源,避免资源冲突和浪费,提高系统利用率。
中断处理:嵌入式系统经常面临各种中断事件,RTOS需要具备良好的中断处理能力。
及时响应中断请求,并确保中断服务程序尽快完成,减少对实时任务的影响。
任务通信与同步:不同任务之间需要进行通信和同步操作。
RTOS提供了多种机制(如消息队列、信号量、邮箱等)来实现任务之间的数据交换和协作。
RTOS优化技巧除了设计原则外,优化也是提升基于C语言的RTOS实时嵌入式系统性能的关键。
qnx培训教程

设计阶段
设计驱动架构、数据结 构、算法等。
编码实现
编写设备驱动代码,实 现设备操作功能。
测试验证
对驱动进行单元测试、 集成测试和系统测试, 确保稳定性和可靠性。
设备驱动模型及框架介绍
设备驱动模型
QNX系统采用分层设备驱动模型,包括设备管理 层、驱动服务层和硬件抽象层。
了解QNX系统中的文件类型,如 普通文件、目录、符号链接等, 并掌握文件权限的设置与修改方
法。
目录结构
熟悉QNX系统的目录结构,了解 各个目录的用途和存放内容,如
根目录(/)、用户目录( /home/username)等。
文件操作
掌握文件的创建、打开、读取、 写入、关闭等操作,以及文件的 复制、移动、删除等管理方法。
多任务处理
了解如何在QNX系统中实现多任务处理,包括线程的创建 、同步和调度等,以提高应用程序的响应性和性能。
QNX系统安全性与可靠性保障
08
措施
安全策略制定及实施方法
访问控制策略
通过用户认证和权限管理,确保只有授权用户能够访问系统资源。
最小权限原则
为每个应用程序或服务分配所需的最小权限,以减少潜在的安全风险。
安全审计策略
记录和分析系统活动,以便检测和响应潜在的安全威胁。
数据加密与传输安全保障技术
01
数据加密技术
使用强加密算法对敏感数据进行 加密,确保数据在存储和传输过 程中的安全性。
02
密钥管理策略
03
传输安全保障
实施严格的密钥管理策略,包括 密钥生成、存储、使用和销毁等 过程。
采用SSL/TLS等协议,确保数据 在传输过程中的完整性和保密性 。
操作系统的内存分配算法

操作系统的内存分配算法操作系统的内存管理是计算机系统中一个重要的组成部分。
内存分配算法决定了如何合理地利用系统的内存资源,以达到高效、安全、稳定的运行。
本文将介绍几种常见的内存分配算法,包括首次适应算法、循环首次适应算法、最佳适应算法以及快速适应算法。
首次适应算法(First Fit Algorithm)首次适应算法是一种简单而常见的内存分配算法。
它从内存空闲列表的头部开始寻找第一个适合分配的内存块。
当找到满足要求的内存块后,将该块划分为两部分,一部分用于分配给请求的程序,另一部分保留为剩余空闲块。
这种算法的优点是分配速度较快,缺点是可能会导致内存碎片的产生。
循环首次适应算法(Next Fit Algorithm)循环首次适应算法是首次适应算法的一种改进版本。
与首次适应算法不同的是,循环首次适应算法从上一次分配的位置开始搜索空闲块,直到找到一个满足要求的内存块为止。
这样可以避免每次都从头开始搜索,提高了查找的效率。
同样,这种算法也可能导致内存碎片的产生。
最佳适应算法(Best Fit Algorithm)最佳适应算法是为了解决内存碎片问题而提出的一种分配算法。
该算法会在内存空闲列表中查找最小且能满足要求的空闲块,并将该块分配给请求的程序。
这样可以尽量充分利用内存资源,减少内存碎片的产生。
但是,最佳适应算法的缺点是分配速度相对较慢,因为需要遍历整个内存空闲列表。
快速适应算法(Quick Fit Algorithm)快速适应算法是一种综合了首次适应算法和最佳适应算法的策略。
它将内存空闲列表分成了多个不同大小的链表,每个链表分别存储相应大小的空闲块。
当有程序请求内存时,快速适应算法会直接从对应大小的链表中查找可用的空闲块进行分配,以提高分配的速度。
这个算法在时间效率和空间效率上都较为出色,但是需要付出额外的存储开销。
总结不同的内存分配算法各有优缺点,选择合适的算法取决于具体的应用场景和系统需求。
首次适应算法和循环首次适应算法适用于内存分配需求频繁变化的场景。
嵌入式linux系统开发标准教程

嵌入式linux系统开发标准教程嵌入式Linux系统开发是一门非常重要的技术,它在嵌入式设备、物联网和智能家居等领域中得到广泛应用。
本文将介绍嵌入式Linux系统开发的标准教程,帮助读者了解该技术的基本原理和常用的开发工具。
一、嵌入式Linux系统开发的基本原理嵌入式Linux系统开发是指将Linux操作系统移植到嵌入式设备中,并针对特定的应用领域进行定制开发。
它与传统的桌面Linux系统有很大的区别,主要体现在以下几个方面:1. 硬件平台的选择:嵌入式设备通常采用ARM架构或者其他低功耗的处理器架构,而不是传统的x86架构。
因此,在进行嵌入式Linux系统开发时,需要根据具体的处理器架构进行相应的移植和优化。
2. 精简的内核:由于嵌入式设备的资源有限,为了提高系统性能和节省资源,嵌入式Linux系统通常会精简内核。
这需要对Linux内核的源代码进行裁剪和优化,以去除不必要的模块和功能,并保留对应用需求的必要功能。
3. 定制化的驱动程序和应用程序:嵌入式设备通常需要与各种外设进行交互,因此需要编写相应的驱动程序。
此外,根据具体的应用需求,还需要定制相关的应用程序和用户界面。
二、嵌入式Linux系统开发的工具嵌入式Linux系统开发需要使用一些常用的工具,下面是一些常用的工具和其功能的介绍:1. 交叉编译工具链:由于嵌入式设备和开发主机的处理器架构不同,无法直接在开发主机上编译和运行目标代码。
因此,需要使用交叉编译工具链,在开发主机上生成适用于目标设备的可执行文件。
2. 调试工具:在嵌入式Linux系统开发过程中,调试是非常重要的一环。
常用的调试工具包括GDB(GNU调试器)和strace(系统调用跟踪工具),它们可以帮助开发人员追踪程序的执行过程和定位错误。
3. 文件系统工具:嵌入式设备的存储资源有限,需要使用文件系统来组织和管理存储的数据。
常用的文件系统工具包括mkfs(创建文件系统)、mount(挂载文件系统)以及文件传输工具(如scp和rsync)等。
嵌入式系统中的实时操作系统调度算法

嵌入式系统中的实时操作系统调度算法嵌入式系统是一种特殊的计算机系统,其设计目标是在特定的应用领域内提供高度可靠和实时的性能。
实时操作系统(RTOS)是嵌入式系统中常用的操作系统类型,它以管理任务和资源的方式为应用程序提供服务。
实时操作系统中的任务调度算法起着至关重要的作用,它们决定了任务执行的顺序和优先级,直接影响系统的实时性能和稳定性。
实时操作系统中常用的任务调度算法包括时间片轮转调度(Round-Robin Scheduling)、优先级调度(Priority Scheduling)、最早截止时间优先调度(Earliest Deadline First Scheduling)等。
每种调度算法都有其自身的特点和适用场景,下面将逐一进行介绍。
1. 时间片轮转调度算法时间片轮转调度算法是实时操作系统中最常见的调度算法之一。
它基于任务的优先级,为每个任务分配一个固定长度的时间片,并按顺序轮流执行任务,每个任务在一个时间片内执行完毕后转移到下一个任务。
当时间片用尽时,下一个任务将获得执行机会。
这种调度算法保证了每个任务的执行时间相对均匀,避免了某个任务霸占资源而导致其他任务无法运行的情况。
时间片轮转调度算法适用于任务的执行时间相对较短和相对平衡的场景,对于响应时间要求较高的实时系统非常有效。
然而,当任务的执行时间差异较大或任务的数量过多时,时间片轮转调度算法可能会导致任务响应时间的不确定性,不适用于要求确定性响应时间的实时系统。
2. 优先级调度算法优先级调度算法是一种简单而直观的调度算法,它为每个任务分配一个优先级,并按照优先级顺序进行调度,具有较高优先级的任务将优先执行。
在实时操作系统中,任务的优先级通常由开发者根据任务的重要性、对实时性的要求和资源的需求等因素进行设定。
优先级调度算法适用于对任务执行时间要求相对灵活的实时系统。
这种调度算法在任务完成时间较长的情况下可以保证重要任务先执行,但是如果任务的数量过多或优先级设置不当,可能会导致低优先级任务长时间等待的情况,从而影响系统的实时性。
嵌入式操作系统_第3章 任务结构、状态、优先级、代码结构、任务控制块及链表、任务堆栈

从应用程序设计的
角度来看, μC/OS-II的任务就 是一个用户编写的 C函数和与之相关 联的一些数据结构
内存
在内存中应该 存有任务的代 码和与该任务 配套的堆栈
任务代码 任务堆栈
而构成的一个实体。
进程的状态
运行态 就绪态 等待态(阻塞态)
程序通过访问它来了解CPU的利用率, 所以这个系统任务OSTaskStat( )叫做 统计任务
任务及的优优先先级权别 用O常明常使O个固O应把计别OSSSS户_数应数用_定_用优任是_CLLL可F用一的OO地O程先务:OGWSWW权 一 表 优 则 低以.程旦优E_μ,E序级,E0HSLCSS,个先表分 示根序被先T中O系T中别因T/_W__1O级级示为 。据中定级P通E统P还此PO,SRSRRS别别任应任义I过T数6_总I使用I2_O_4IOO…L用务,为给P,I务都最字个是用户自-ORO1W把程优则:表I共把了任动S个E的用高优0O_S表任序先意示赋0O最统务赋LT优一,先S,O_示务的级味最_值低计可给WP先个数级L1ER需别着低O,的任的优任以空SIW级数字别TO要的系优E2方务优先务使闲_-S,别字P1越,,数 统先T法级, 用任R自的先_…I越来大每在目中级P,别系的务O动R…-文。可别I来统优。2赋O,,件该供的+说则先如给1共会级果统
任当务控应制用块结程构序的主调要用成员函数OSTaskCreate( )
任务及控任制务块控(O制S_块TC链B)表 t…y创统进任务控这表…pOssIII数具链的表…etNNtNdrr…S建函行务控制个的TTTuue任_会有接任。fcc188Stts任 任 制 认务6UUT一数初从制块任头μ栈务理控tooUr当由按相为务即Kuss控__c个始空块各务部O务务块和ttt制C的*指有制cc进于用应一,相oSObbOOOs/块任化任,个控T_S**SSS控的的管行这户数个故当t针关优OT块OOC链TTTcbC务。务然成制BCCSCSS表系 些提量链这于BTT{BBBI制 身 任理、的先-SCCDPS时这控后员块ntItBBr统任供的表个是lkiayi块 份 务的PNPot任 属级I;,个制用进链t;;rte初务的任。链一re用x///;vt///就 证 是这函块任行入(任任任/;;务 性别//始控任务表些指///指务务务来指个数链务赋到)向相 , 不的 的化制等向务控叫空等的的向来任记函首表的值任后待当优前时块数制做白当 没 能务为当 表一一的前先一空数先获属,务堆录,还个为块空的时状级个任任于 有 被栈前 就些会为取性最控任限态别任务初没系并任身任栈务务标(务是 任 系控状 叫与调 被 一对 后 制顶始有控统把务 份志节控控制务的用创个任再块制拍一务统制态做任块化对创它块证指制块数块的链系建任务把链针个控承函应的建们链。)、任务的块表指堆指任管务针针
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
嵌入式操作系统内核原理和开发(最快、最优、最差内存分配算法)前面我们说到了基于链表的内存分配算法。
但是之前我们也说过,其实内存分配一般有三个原则,最快、最优和最差。
最快比较好理解,就是寻找到合适的节点就立即分配内存,我们在前面一篇博客采用的就是这个方法。
最优呢,就是寻找可以满足当前内存分配的最小节点,这样不会有很大的浪费,但是有可能会产生碎片节点。
最后一种就是最差分配算法,说是最差效果未必最差。
因为在大的内存分配的时候至少不会很快产生内存碎片,对整个系统的稳定来说有可能是好事。
所以这三种方法很难说哪一种好,哪一种不好,需要结合具体的应用场景客观进行分析。
不过话说回来,内存碎片是无论如何都避免不了的。
首先,为了灵活对这三种分配算法进行配置,我们定义了宏开关,需要哪个就把那个开关放开。
暂时默认打开的算法的是最快分配算法。
[cpp]view plaincopy1.#define MAX_SPEED_MALLOC 12.#define MIN_SIZE_MALLOC 03.#define MAX_SIZE_MALLOC 0因为之前已经讨论过最快分配算法,所以这里着重讨论的最优分配算法和最差分配算法。
又由于两者的差别极小,所以单独分析其中一种算法也行。
就拿最优分配算法来说,为了寻找到最小的节点,我们需要对整个链表进行遍历,这个还是比较消耗时间的。
[cpp]view plaincopy1.while(pCur)2.{3.if(pCur->size > (size + sizeof(MNG_NODE)))4. {5.if(NULL == pFind || pFind->size > pCur->size)6. {7. pFind = pCur;8. }9. }10.11. pPre = pCur;12. pCur = pCur->next;13.}寻找到pFind这个我们需要的节点之后,还需要从pFreeList中删除该节点。
所以,我们需要进一步的判断和分析,1.if(NULL == pFind)2.return NULL;3.4.pPre = find_previous_node_in_list(pFind, pFreeList);5.if(NULL == pPre)6. pFreeList = pFreeList->next;7.else8. pPre->next = pFind->next;9.10.return pFind;首先判断pFind前面有没有节点,如果没有表示pFreeList就是pFind,那么pFreeList 需要自行向后退缩;当然如果当前的pFind节点是有前节点的,那么只需要把前节点的next 指针重新更改一下即可。
当然,这里还对原来的查找节点函数作了一下修改,使之更合理更通用。
[cpp]view plaincopy1./*************************************************2.* function: find previous node3.**************************************************/4.5.MNG_NODE* find_previous_node_in_list(MNG_NODE* pNode, MNG_NODE* pList)6.{7. MNG_NODE* pFind = pList;8. MNG_NODE* pPre = NULL;9.10.while(pFind && pFind != pNode)11. {12. pPre = pFind;13. pFind = pFind->next;14. }15.16.if(NULL == pFind)17.return NULL;18.19.return pPre;20.}上面也只是说了个大概,具体的内容可以参见下面的源代码。
既可以在VC上编译,也可以在GCC上面编译,都没有问题。
当然,如果本地os没有编译器,可以选择网上在线编译,也是个不错的选择。
1./*************************************************2.* malloc & free in link node algorithm3.**************************************************/4.5.#include <string.h>6.#include <malloc.h>7.8./*************************************************9.* struct definition10.**************************************************/11.12.typedef struct _MNG_NODE13.{14.struct _MNG_NODE* next;15. unsigned int size;16.}MNG_NODE;17.18.19./*************************************************20.* macro declaration21.**************************************************/22.23.#define MAX_SPEED_MALLOC 124.#define MIN_SIZE_MALLOC 025.#define MAX_SIZE_MALLOC 026.27.#define MEM_BUFFER_LENGTH (0x1 << 24)28.29.30./*************************************************31.* global variable declaration32.**************************************************/33.34.static void* pGlbData;35.static MNG_NODE* pFreeList;36.static MNG_NODE* pAllocList;37.38.39./*************************************************40.* function declaration41.**************************************************/42.43.MNG_NODE* find_previous_node_in_list(MNG_NODE* pNode, MNG_NODE* pList);44.45.46./*************************************************47.* function: add node into headlist48.**************************************************/49.50.static void add_node_into_list_head(MNG_NODE* pNode, MNG_NODE** ppList)51.{52. pNode->next = *ppList;53. *ppList = pNode;54.}55.56.57.#if MAX_SPEED_MALLOC58./*************************************************59.* function: find best fit node in max_speed60.**************************************************/61.62.static MNG_NODE* find_best_fit_node(unsigned int size)63.{64. MNG_NODE* pFind = pFreeList;65. MNG_NODE* pPre = pFind;66.67.while(pFind && pFind->size < (size + sizeof(MNG_NODE)))68. {69. pPre = pFind;70. pFind = pFind->next;71. }72.73.if(NULL == pFind)74.return NULL;75.76.if(pFreeList == pFind)77. pFreeList = pFreeList->next;78.else79. pPre->next = pFind->next;80.81.return pFind;82.}83.#endif84.85.86.#if MIN_SIZE_MALLOC87./*************************************************88.* function: find best fit node in min size89.**************************************************/90.91.MNG_NODE* find_best_fit_node(unsigned int size)92.{93. MNG_NODE* pCur = pFreeList;94. MNG_NODE* pPre = pCur;95. MNG_NODE* pFind = NULL;96.97.while(pCur)98. {99.if(pCur->size > (size + sizeof(MNG_NODE)))100. {101.if(NULL == pFind || pFind->size > pCur->size) 102. {103. pFind = pCur;104. }105. }106.107. pPre = pCur;108. pCur = pCur->next;109. }110.111.if(NULL == pFind)112.return NULL;113.114. pPre = find_previous_node_in_list(pFind, pFreeList); 115.if(NULL == pPre)116. pFreeList = pFreeList->next;117.else118. pPre->next = pFind->next;119.120.return pFind;121.}122.#endif123.124.125.#if MAX_SIZE_MALLOC126./*************************************************127.* function: find best fit node in max size128.**************************************************/129.130.MNG_NODE* find_best_fit_node(unsigned int size)131.{132. MNG_NODE* pCur = pFreeList;133. MNG_NODE* pPre = pCur;134. MNG_NODE* pFind = NULL;135.136.while(pCur)137. {138.if(pCur->size > (size + sizeof(MNG_NODE)))139. {140.if(NULL == pFind || pFind->size < pCur->size) 141. {142. pFind = pCur;143. }144. }145.146. pPre = pCur;147. pCur = pCur->next;148. }149.150.if(NULL == pFind)151.return NULL;152.153. pPre = find_previous_node_in_list(pFind, pFreeList); 154.if(NULL == pPre)155. pFreeList = pFreeList->next;156.else157. pPre->next = pFind->next;158.159.return pFind;160.}161.#endif162.163.164./*************************************************165.* function: implement memory allocation166.**************************************************/167.168.static void* _mem_malloc(unsigned int size)169.{170. MNG_NODE* pOld;171. MNG_NODE* pNew;172.173. pOld = find_best_fit_node(size);174.if(NULL == pOld)175.return NULL;176.177. pNew = (MNG_NODE*)((char*)pOld + sizeof(MNG_NODE) + pOld->size - (sizeo f(MNG_NODE) + size));178. pNew->size = size;179. pOld->size -= sizeof(MNG_NODE) + size;180.181. add_node_into_list_head(pOld, &pFreeList);182. add_node_into_list_head(pNew, &pAllocList);183.184.return (void*)((char*)pNew + sizeof(MNG_NODE));185.}186.187.188./*************************************************189.* function: memory allocation190.**************************************************/191.192.void* mem_malloc(unsigned int size)193.{194.if(0 == size)195.return NULL;196.197.if(size > (MEM_BUFFER_LENGTH - sizeof(MNG_NODE)))198.return NULL;199.200.return _mem_malloc(size);201.}202.203.204./*************************************************205.* function: find previous node206.**************************************************/207.208.MNG_NODE* find_previous_node_in_list(MNG_NODE* pNode, MNG_NODE* pList) 209.{210. MNG_NODE* pFind = pList;211. MNG_NODE* pPre = NULL;212.213.while(pFind && pFind != pNode)214. {215. pPre = pFind;216. pFind = pFind->next;217. }218.219.if(NULL == pFind)220.return NULL;221.222.return pPre;223.}224.225.226./*************************************************227.* function: implement memory free228.**************************************************/229.230.static void _mem_free(MNG_NODE* pNode)231.{232. MNG_NODE* pPreNode;233.234.if(pNode == pAllocList)235. {236. pAllocList = pAllocList->next;237. add_node_into_list_head(pNode, &pFreeList);238.return;239. }240.241. pPreNode = find_previous_node_in_list(pNode, pAllocList);242.if(NULL == pPreNode)243.return;244.245. pPreNode->next = pNode->next;246. add_node_into_list_head(pNode, &pFreeList);247.return;248.}249.250.251./*************************************************252.* function: free memory function253.**************************************************/254.255.void mem_free(void* pData)256.{257.if(NULL == pData)258.return;259.260.if(pData < pGlbData || pData >= (void*)((char*)pGlbData + MEM_BUFFER_LE NGTH))262.263. _mem_free((MNG_NODE*)((char*)pData - sizeof(MNG_NODE))); 264.}265.266.267./*************************************************268.* function: get memory buffer269.**************************************************/270.271.void mem_init()272.{273. pGlbData = (void*)malloc(MEM_BUFFER_LENGTH);274.if(NULL == pGlbData)275.return;276.277. memset(pGlbData, 0, MEM_BUFFER_LENGTH);278. pFreeList = (MNG_NODE*)pGlbData;279. pFreeList->size = MEM_BUFFER_LENGTH - sizeof(MNG_NODE); 280. pAllocList = NULL;281.}282.283.284./*************************************************285.* function: free memory buffer286.**************************************************/287.288.void mem_exit()289.{290.if(NULL != pGlbData)291. free(pGlbData);292.293. pFreeList = NULL;294. pAllocList = NULL;295.}296.297.298./*************************************************299.* function: file starts here300.**************************************************/301.302.int main(int argc, char* argv[])303.{304. mem_init();306.return 1; 307.}。