MDK5 #254: type name is not allowed

前言

在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 <stdio.h>
#include <stdlib.h>

#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 MDK5
const 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;
}

发布了436 篇原创文章 · 获赞 126 · 访问量 175万+

猜你喜欢

转载自blog.csdn.net/LostSpeed/article/details/103500483
今日推荐