MDK5 #254: type name is not allowed
发布日期:2021-06-30 22:01:51 浏览次数:2 分类:技术文章

本文共 2323 字,大约阅读时间需要 7 分钟。

前言

在MDK工程中使用cJSON来分析json文件,突然发现cJSON用内存太猛了。基本是1KB的json文件,要使用3KB~6KB的内存用量。

内存用量猛的原因如下:

  • 内存管理模块的最小块单位额为32Bytes, 如果申请很多次,会浪费很多内存. e.g. "hello"这个字符串,如果要申请内存,就会占掉32Bytes. 如果json文件的key_value较多,那就会为很多的key/value申请内存,那内存用量,就要比实际的json文件size大好多。
    但是内存最小块太小(e.g. 4Bytes), 那内存管理表就很大, 甚至比要管理的有效内存更大。
  • 分析json文件时,json内容就是一棵树,如果我自己作,肯定也会用单链表来作,每个节点下都挂一堆单链表。而且还会有一些额外的管理信息。这些额外的管理信息,也会占用多余的内存空间。

开始想挂外部内存芯片,原理图都画完了,方案被老大给枪毙了。原因如下:

  • 板子画出来太丑, 因为属于打补丁性质的板子,要保持硬件管脚接口(插件)兼容,又多了2个大片子(cpu管脚由100脚上升到144管脚,新加入的内存芯片为tsop44), 原始板子的原件密度又大(40mm*60mm), 有50个元器件。先不用布线,将元器件先摆开,那板子体积至少扩大一倍. 板子重心已经偏了,特别的丑:)
  • 动硬件板子,时间成本高。
  • 他感觉,从软件上优化,能解决这个问题。不使用cJSON库,自己用手掰json文件的分隔符号,只载入必须的元素,并进行元素替代(e.g. 有些已知的字符串或参数,用变量ID来代表)那样就省很多空间。web端用json表示的文件内容,可能是web端html的表内容。那这些表内容,有很多都是下位机用不到的。如果完全载入原始的json文件,确实会占用很多宝贵的RAM空间。特别是,这些json文件载入后,不能释放。因为要用于后续的判断(不可能每次判断一个逻辑,都再读一次json文件,肯定要将json配置文件,载入一次后,就缓存起来,不释放了).

试验

第一步要做的是,将有些已知的变量内容,用变量ID来表示。

e.g. “param1” 用1000来代替,"hello"用2000
那么 {“param1”:“hello”} 就可以用 {1000, 2000}来代替。如果{1000, 2000}放在一个有2个int类型值的结构中,那这个结构,就只占用8个字节.
其中1000,2000用枚举值自己定义,这样维护起来,也很方便,不至于看蒙。

那首先,要先定义一个常量结构体数组, 这样,结构体数组,就在代码空间内,不会占用宝贵的片内RAM了。

但是,定义好数组后,总是编译不过,报错为#254: type name is not allowed

回来做了试验,定义的常量结构体数据,在vs2017和MDK下都编译过了。

明天接着优化json文件的载入。

可以在vs2017和MDK5中都编译通过的“常量结构体数组的初始化代码”如下

#include 
#include
#pragma pack(push, 1)typedef enum _ENUM_dev_id { ENUM_DEV_ID_dev1 = 1, ENUM_DEV_ID_dev2}ENUM_DEV_ID;typedef struct _tag_Info { ENUM_DEV_ID id; const char* psz_name;}TAG_INFO;#pragma pack(pop)// 将字符串用一个数字表示// ok on vs2017, error on MDK5//const TAG_INFO g_ary_for_id_by_name[] = {// TAG_INFO{ENUM_DEV_ID_dev1, "dev1"},// TAG_INFO{ENUM_DEV_ID_dev2, "dev2" }//};// const char* psz_dev1_name = "dev1";// #define DEV1_NAME "dev1"// compile both ok on vs2017 and MDK5const TAG_INFO g_ary_for_id_by_name[] = { {ENUM_DEV_ID_dev1, "dev1"}, // “dev1” 只能是常量字符串,不能是常量指针变量psz_dev1_name,否则报错 “error: #28: expression must have a constant value” 所以,这里最多是一个宏 DEV1_NAME {ENUM_DEV_ID_dev2, "dev2" } };int main(){ int i = 0; int i_ary_size = sizeof(g_ary_for_id_by_name) / sizeof(g_ary_for_id_by_name[0]); for (i = 0; i < i_ary_size; i++) { printf("struct[%d].id = %d\n", i, g_ary_for_id_by_name[i].id); printf("struct[%d].psz_name = %s\n", i, (NULL != g_ary_for_id_by_name[i].psz_name) ? g_ary_for_id_by_name[i].psz_name : "NULL"); } return EXIT_SUCCESS;}

转载地址:https://lostspeed.blog.csdn.net/article/details/103500483 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:experiment : convert function as shellCode on our C project
下一篇:STM32F407 SPI线的选择

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月16日 20时31分47秒