0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于DWC_ether_qos的以太网驱动开发-LWIP的堆管理介绍

嵌入式USB开发 来源:嵌入式Lee 作者:嵌入式Lee 2023-09-08 08:40 次阅读

本文转自公众号欢迎关注

基于DWC_ether_qos的以太网驱动开发-LWIP的堆管理介绍 (qq.com)

https://mp.weixin.qq.com/s/OMnn1WsbdvqeqL6UOGsQVA

一.前言

堆管理是重点的基础代码,需要重点关注,移植时也需要关注。所以这一篇就来讲讲LWIP的堆管理。

二.LWIP的堆管理实现

LWIP实现了内部的堆管理,这样无OS等环境也可以直接移植使用,不依赖系统的堆管理。

当然也可以配置为使用系统的堆管理。

源码位于mem.c,mem.h

如果使能MEM_LIBC_MALLOC则使用系统的堆管理接口

需要配置以下宏

mem_clib_free

mem_clib_malloc

mem_clib_calloc

默认是

/* in case C library malloc() needs extra protection,

如果使能MEM_USE_POOLS则使用内存池实现,这个上一篇已经讲解了。

否则使用mem.c的实现,我们重点关注这一部分。

三.堆的存储分配

如果没有定义LWIP_RAM_HEAP_POINTER则

mem.c中定义一个大数组LWIP_DECLARE_MEMORY_ALIGNED

大小是MEM_SIZE_ALIGNED + (2U * SIZEOF_STRUCT_MEM)

用户可用空间是#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE)

即用户定义的MEM_SIZE,默认值是1600

/**

这里多分配了2U * SIZEOF_STRUCT_MEM是一方面多一个ram_end标记末尾,作为末尾的边界节点,一方面预留对齐的浪费空间。

用户也可以直接定义宏LWIP_RAM_HEAP_POINTER指定存储的位置。

个人觉得这里LWIP_RAM_HEAP_POINTER静态指定,改为指针变量,初始化变量值为LWIP_RAM_HEAP_POINTER,然后也可以通过接口设定会更好。这样用户可以根据实际情况动态分配出这部分存储来,否则静态分配,程序不运行也要占用空间比较浪费。

LWIP_DECLARE_MEMORY_ALIGNED

实现如下

/** If you want to relocate the heap to external memory, simply define

四.源码分析

4.1数据结构

核心数据结构如下struct mem

/**

* The heap is made up as a list of structs of this type.

* This does not have to be aligned since for getting its size,

* we only use the macro SIZEOF_STRUCT_MEM, which automatically aligns.

*/

struct mem {

/** index (-> ram[next]) of the next struct */

mem_size_t next;

/** index (-> ram[prev]) of the previous struct */

mem_size_t prev;

/** 1: this area is used; 0: this area is unused */

u8_t used;

#if MEM_OVERFLOW_CHECK

/** this keeps track of the user allocation size for guard checks */

mem_size_t user_size;

#endif

};

一个双向链表来实现,该结构体描述某一个区块,used表示当前区块是否使用。

Next和prev分别指向前后区块,用于入链表和出链表操作。

这里为什么没有描述本区块大小的字段呢?

因为可以直接从next减去当前区块的基地址得到,所以不需要额外的大小信息了。

比如当前区块基地址是ptr则当前区块可用于分配的有效空间如下计算

(mem->next - (ptr + SIZEOF_STRUCT_MEM))

即后一个区块的开始的地址-本区块开始地址-信息头。

这个实现其实和uCOS的堆管理实现差不多。

4.2接口

mem_init

初始化时,初始全局变量ram即对齐后的存储空间,

lfree指向空闲块的开头,初始化时为ram,

lfree始终用于指向未分配的区块。

此时只有一个整的未分配的区块,next指向MEM_SIZE后,

MEM_SIZE外ram_end用于标记结束,这也是之前存储多分配的原因。

wKgaomT6e8mAOc3CAABfv0oF-p8552.png

mem_malloc/mem_calloc

分配算法核心思想如下,

从lfree开始查找空闲空间大于等于需求size的块。

如果找到了就分配它。

这里有一个处理,如果本块比较大,则分配了size后还有剩余,所以要拆分,即分配出size后剩余的部分成为空闲块。

这个到底多大要拆分,标准是大于等于(size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)拆分,即可用空间是MIN_SIZE_ALIGNED才拆分。

分配完后,如果分配出的块刚好是lfree位置,则要更新lfree指向后续空闲块。

因为lfree始终是指向的空闲块,即lfree链接起来的都是空闲块。分配出的块就从lfree中去掉了。

比如分配黄色空间后如下

wKgZomT6e8mADuLYAABqy7Qyj1Y058.png

注意返回的是结构体之后的可用空间部分。

mem_free

区块链接到lfree空闲块中去,如果该块前后为空闲则和前后拼接成大的空闲块。

mem = (struct mem *)(void *)((u8_t *)rmem - (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET));

先偏移结构到块头。

如果mem小于lfree则要更新lfree为mem。

核心处理是plug_holes,判断mem前后是否空闲,如果是空闲则和前后合并。

mem_trim

缩小

如果本块缩小后剩余的空间不够SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED,则没有必要缩小,不处理。

如果缩小后剩余空间大于上述大小则看next是否空闲如果是则和next合并,否则单独独立出来一个空闲块。

五.总结

LWIP实现了小型的堆管理,这样无OS也可以直接移植使用,另外也可以配置为实用内存池和系统实现,比较灵活。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 以太网
    +关注

    关注

    40

    文章

    5079

    浏览量

    166251
收藏 人收藏

    评论

    相关推荐

    基于DWC_ether_qos以太网驱动开发-MAC帧格式介绍

    本文转自公众号,欢迎关注 基于DWC_ether_qos以太网驱动开发-MAC帧格式介绍 (qq.com) 一.前言   在
    的头像 发表于 08-30 09:23 1284次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-MAC帧格式<b class='flag-5'>介绍</b>

    基于DWC_ether_qos以太网驱动开发-MDIO驱动编写与测试

    本文转自公众号欢迎关注 基于DWC_ether_qos以太网驱动开发-MDIO驱动编写与测试 一.前言
    的头像 发表于 08-30 09:37 2281次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-MDIO<b class='flag-5'>驱动</b>编写与测试

    基于DWC_ether_qos以太网驱动开发-描述符链表介绍

    本文转自公众号欢迎关注 一.描述符概述 1.0 前言 对于DWC Ethernet QoS驱动的编写来说,初始化完成之后,核心操作就是DMA的描述符链表配置(linked list
    的头像 发表于 08-30 09:39 2736次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-描述符链表<b class='flag-5'>介绍</b>

    基于DWC_ether_qos以太网驱动开发-数据流验证过程

    转自公众号欢迎关注 https://mp.weixin.qq.com/s/klrHhaLMM_0W3FGVwHXFkA 基于DWC_ether_qos以太网驱动开发-数据流验证过程
    的头像 发表于 08-31 08:41 1169次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-数据流验证过程

    基于DWC_ether_qos以太网驱动开发-收发驱动编写与调试

    本文转自公众号,欢迎关注 基于DWC_ether_qos以太网驱动开发-收发驱动编写与调试 (qq.com) https://mp.wei
    的头像 发表于 09-05 08:47 1368次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-收发<b class='flag-5'>驱动</b>编写与调试

    基于DWC_ether_qos以太网驱动开发-无OS环境移植LWIP

    本文转自公众号欢迎关注 基于DWC_ether_qos以太网驱动开发-无OS环境移植LWIP (qq.com) https://mp.we
    的头像 发表于 09-06 08:40 810次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-无OS环境移植<b class='flag-5'>LWIP</b>

    基于DWC_ether_qos以太网驱动开发-LWIP的内存池介绍

    本文转自公众号,欢迎关注 https://mp.weixin.qq.com/s/mBoGSf_u9edFF01U_OZT9g 一.前言 lwIP为基础结构提供了专用的内存池管理,比如netconn
    的头像 发表于 09-07 08:45 876次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>LWIP</b>的内存池<b class='flag-5'>介绍</b>

    基于DWC_ether_qos以太网驱动开发-LWIP的堆(内存池)未对齐导致问题的案例分享

    本文转自公众号欢迎关注 https://mp.weixin.qq.com/s/ErIa2ss2YZLGYbSwoJEzog 一. 前言 内存未对齐访问问题这个已经是老生常谈的问题了, 由于LWIP
    的头像 发表于 09-09 08:44 1222次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>LWIP</b>的堆(内存池)未对齐导致问题的案例分享

    基于DWC_ether_qos以太网驱动开发-RTOS环境移植LWIP与性能测试

    本文转自公众号,欢迎关注 基于DWC_ether_qos以太网驱动开发-RTOS环境移植LWIP与性能测试 (qq.com) https:
    的头像 发表于 09-11 11:20 1106次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-RTOS环境移植<b class='flag-5'>LWIP</b>与性能测试

    基于DWC_ether_qos以太网驱动开发-LWIP在PC上进行开发调试

    本文转自公众号欢迎关注 基于DWC_ether_qos以太网驱动开发-LWIP在PC上进行开发
    的头像 发表于 09-11 08:40 1110次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>LWIP</b>在PC上进行<b class='flag-5'>开发</b>调试

    基于DWC_ether_qos以太网驱动开发-LWIP的定时器模块详解

    一. 前言 LWIP的定时器模块,实现了通用的软件定时器,用于内部的周期事件处理,比如arp,tcp的超时等,用户也可以使用。这一篇来分析该模块的实现。 二.代码分析 2.1源码 源码
    的头像 发表于 09-18 09:33 875次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>LWIP</b>的定时器模块详解

    基于DWC_ether_qos以太网驱动开发-LWIP的ARP模块介绍

    TCP/IP通讯第一步需要先调通ARP,否则TCP/IP包都不知道MAC地址要发给谁。这一篇来基于LWIP的ARP实现进行相关的分析。
    的头像 发表于 09-18 09:34 1027次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>LWIP</b>的ARP模块<b class='flag-5'>介绍</b>

    设计软件核心以太网服务质量数据手册免费下载

    本文描述Synopsys设计软件核心以太网服务质量DWC以太网QoS核心5.10A。DWC以太网
    发表于 10-23 08:00 15次下载
    设计软件核心<b class='flag-5'>以太网</b>服务质量数据手册免费下载

    基于DWC_ether_qos以太网驱动开发-包过滤

    以太网上数据非常多,如果所有数据都接收交给软件去处理软件负载会非常重,所以一般只需要接收发给自己的数据即可
    的头像 发表于 09-02 09:19 827次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-包过滤

    基于DWC_ether_qos以太网驱动开发-软复位介绍与问题案例

    一般模块都会有软复位的功能,软复位在驱动编写中很重要。一般初始化时执行软复位使得模块进入确定的初始状态以提高可靠性,异常时也可以重新初始化来恢复,所以软复位在驱动中一般是必须要做的动作。
    的头像 发表于 09-02 09:17 889次阅读
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太网</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-软复位<b class='flag-5'>介绍</b>与问题案例