• 关于LWIP的一点记录(一)


    天天在提瓦特砍树也不是个事,等宵宫连续剧完结,整理一下以前的一些东西。
    仰望天空中须臾的绚烂,也直面脚下具体的小困难。烟花易逝,人情长存
    在这里插入图片描述

    应用层(DNS,DHCP,HTTP,SNMP)
    传输层(TCP,UDP)
    网络互联层(IPv4,IPv6,ICMP,IGMP,ARP)
    网络接口层(ppp,SLIP)

    以下以1.3版本为例,高版本文件会有不同,但道理一样
    文件结构:
    doc->sys_arch.txt(移植)
    src->api->api_lib.c,api_msg.c(sequential API)
    ->socket.c(socket API)
    core->(TCP,UDP,DNS,DHCP,IPV4,IPV6,SNMP,ICMP,IGMP)
    ->(mem,memp,pbuf,autoip,timer)
    netif->(PPPOE,etharp,ethernetif(网卡操作,自己实现),slipif(串行))
    include->lwip(opt.h,init.h)
    进程模型:LWIP作为OS上的一个进程,用户程序可以运行在协议栈进程,也可以单独开一个进程
    前者通过rawapi(回调)来通信,灵活,效率高,但处于同一进程,用户程序if耗时则会影响协议栈,不适合大量数据耗时处理等场合
    后者使用sequential API,通过OS提供的邮箱和信号量来通信,so灵活性降低效率降低,但可以并发多任务,大量数据而不影响协议栈
    将LWIP进程设为最高优先级,以提高实时性
    socket API:模拟BSD socket接口,封装sequential API

    动态内存池分配(POOL)
    初始化大内存分为多种固定大小的块(A类型a块——B类型b块——C类型c块。。。物理上连续),申请时按照参数的类型申请某个固定大小
    ex:TCP/IP中有许多固定大小的数据结构(TCP首部、IP首部等)
    so LWIP实际初始化时按照宏定义中的配置,初始化用到的各种类型(大小)的内存
    POOL管理相关结构:
    memp_tab[]:指向每类POOL中的第一个
    memp_sizes[]:每类POOL单个POOL的大小
    memp_num[]:每类POOL的个数
    memp_desc[]:描述
    memp_memory[]:为所有POOL分配的空间
    程序中的实现方法举例:
    为用到的POOL类型编号:
    typedef enum{

    #define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name
    #include "lwip/memp_std.h"
    MEMP_MAX	
    
    • 1
    • 2
    • 3

    }memp_t;
    用第一句的宏替换第二句头文件中的内容,就取出了所有预先定义的POOL类型,形成了一个枚举,后面再放个MAX记录数量
    上面的几个POOL管理相关的结构都是用的这种定义方式,通过不同的宏替换实现头文件复用,且配置时只需改头文件
    memp_init()之后:
    memp_tab[A]->A->A->A(共a个)
    memp_tab[B]->B->B->B->B(共b个)
    memp_tab[C]->C->C(共c个)

    当然这些东西实际上在连续的空间(如AAABBBBCC…)

    动态内存堆分配:
    常用方式(跟OS一样,也有各种fit):first fit + 回收时尝试合并相邻块
    相关结构:
    ram_heap[]:内存堆空间
    ram:内存堆起址
    mem:各块内存头部的管理结构(prev,next形成双链,used标记使用)
    ram_end:指向最后一块(最后一块初始标记为已使用(只有mem没有其他空间))
    lfree:指向最低地址空闲块(从此处开始一个个往后寻找没有被使用且大小满足要求的,
    if空闲块去掉被申请的部分还能满足最小分配大小,则截取下来一个新的空闲块加入链表)
    初始化时是一整块内存,然后根据申请从头开始分配对应的大小(要多少给多少,除非剩下的太小)
    所有的内存块(不管使用还是未使用都在同一条链上,used标记区分)
    mem_calloc:调用mem_malloc,并清零(推荐)
    mem_trim:内存区域重分配(减小)
    另外的分配方式:使用C库的malloc和free;使用内存堆的方式实现内存池;使用内存池的方式实现内存堆

  • 相关阅读:
    forest框架单个和批量添加头部信息
    openssl + 3DES开发实例(linux)
    垃圾回收器
    GitLab项目中添加用户,并设置其角色权限等
    【云原生 • Kubernetes】一文掌握 k8s 包管理工具 Helm
    代理IP与Socks5代理:跨界电商智能爬虫与出海之道
    【D3.js】1.17-给 D3 元素添加标签
    【7 查找】顺序表折半查找。
    关于飞桨UIE等模型预测推理时间很久的问题分析以及解决,蒸馏剪枝部署问题解决
    Android自定义组合控件
  • 原文地址:https://blog.csdn.net/weixin_40852534/article/details/126203071