1.简介
在实际使用过程中,部分代码,比如需要实时进行处理,比如需要实时卡尔曼处理数据, 算法模块,编解码操作,大量循环,UI操作。 由于部分RTOS设备,代码指令存储在FLASH中,对于存储在内部FLASH的,执行过程中,取指令速度可控,但是实际使用过程中,有些设备 使用了外部flash存储代码(正常量产,一般需要进行多供,降低供应链风险)。 这个会导致部分平台上,我们代码存储在不同flash上,执行过程中,存在速度差异(部分较差的flash,存取指令周期变长)。
2.优化提升
优化提升,一方面如果平台存在icache,可能会比较友好,因为指令一旦命中,就会从cache中获取,速度相当,对于 未命中,就需要从flash取指令,执行。 另外一个策略,就是在RAM较充足下,将代码指令放置到RAM空间上,我们在实际使用过程中,遇到紫光展锐W217平台 上,运行效率问题,因此考虑进行优化部分放置到内存,进行提升速度。
3.操作流程
涉及的主要流程有,链接脚本调整、代码指令拷贝、运行,以紫光展锐UWS6121E实例部分伪代码策略:
3.1 链接脚本
这个部分要将我们需要执行的代码,链接到一个空间里面,需要在RAM上占个位置, 这个部分的代码其实也是会在ROM里面占位置,如果不需要RAM里面占,可以补充到FLASH后面,单独链接成一段。
;将用户代码单独放置
RAM_EXEC_USER_CODE +0
{
; 所有标记 USER_RAM_CODE 的代码都会放在这里
*(USER_RAM_CODE)
;user_fast_code.o (*.text) <=== 整个文件所有代码都进来!
}
;IMG$$RAM_RW$$LIMIT will be used to check the case of overflow
RAM_RW +0
{
* (+RW)
* (+ZI)
}
HEAP_AREA +0 ALIGN 4
{
mem_prod*.o (BYTE_HEAP_AREA)
}
SYS_STACK +0 ALIGN 4
{
mem_prod*.o (SYS_STACK_AREA)
mem_prod*.o (FIQ_STACK_AREA)
}
;断言--保证没有用超内存
ScatterAssert(ImageLimit(SYS_STACK) <= (MEM_RAM_AP_END_ADDR))
3.2 开机阶段处理
开机阶段主要需要的工作就是将,需要优化的代码放入到RAM上,上面已经占好了空间,对于编译器ARMCC平台,会 自动导入宏定义(标记我定义的段的位置,大小等)
extern unsigned char Image$$RAM_EXEC_USER_CODE$$Base;
extern unsigned char Load$$RAM_EXEC_USER_CODE$$Base;
extern unsigned int Image$$RAM_EXEC_USER_CODE$$Length;
// 从Flash 位置 拷贝到 RAM位置(之前已经占位了)
void copy_user_code_to_ram(void)
{
memcpy(
&Image$$RAM_EXEC_USER_CODE$$Base, // 目标 RAM
&Load$$RAM_EXEC_USER_CODE$$Base, // 源 Flash
&Image$$RAM_EXEC_USER_CODE$$Length
);
}
3.3 测试阶段
伪代码测试效果(实际工程中,可以让自己需要进行优化代码,比如UI相关的、算法相关的)
__attribute__((section("USER_RAM_CODE")))
void my_fast_func(void)
{
volatile int i = 0;
for(i=0; i < 1000000;i++)
{
//SCI_TRACE_LOW("index:%d",i);
}
}
void my_normal_func()
{
volatile int i = 0;
for(i=0; i < 1000000;i++)
{
//SCI_TRACE_LOW("index:%d",i);
}
}
void test_func_all()
{
uint32 start_tick = 0;
uint32 end_tick = 0;
uint32 end_all_tick = 0;
start_tick = SCI_GetTickCount();
my_fast_func();
end_tick = SCI_GetTickCount();
my_normal_func();
end_all_tick = SCI_GetTickCount();
SCI_TRACE_LOW("time1: %d, time2: %d", (end_tick-start_tick), (end_all_tick-end_tick) );
}
3.4 实际测试效果
实际测试效果,在指令较少(或者有cache平台上)差距不大,但是对于指令较多,速度问题,立马就会显现出来:
[test_func_all]<4487> time1: 8, time2: 11
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 11
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 9, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 11
[test_func_all]<4487> time1: 8, time2: 10
[test_func_all]<4487> time1: 8, time2: 11
4.总结
主要是针对RAM足够,外挂FLASH存储代码,且外挂FLASH品质差异,或者对实时性,要求高的场景。
您还没有登录,请您登录后发表评论。