打印
[AVR单片机]

基于IAR环境开发ATxmega系列之RAM优化

[复制链接]
2620|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nextkey|  楼主 | 2012-9-11 10:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
http://blog.sina.com.cn/s/blog_7420cd1701019c6x.html

为一款MCU开发软件,首先要了解的是芯片的结构,是冯.诺尹曼结构,还是哈佛结构。这里我们一起来看下AVR规格书的介绍吧:


上图为AVR系列MCU的芯片结构图,如图所示,程序总线与数据总线是分开的,即不在同一个线性空间。
规格书中亦有介绍:
The AVR uses a Harvard architecture - with separate memories andbuses for program and data.

鉴于上边提到的AVR程序与数据总线是分开的,那在软件编码即需要体现出来,因此需要在编译器中设置允许扩展语法Allow IARextensions,如下图所示:

编译器手册中,与数据存储有关的扩展字如下:
__eeprom Controls the storage of data objects in code memoryspace
__ext_io Controls the storage of data objects in I/O memory spaceSupports I/O instructions; used for SFRs
__far Controls the storage of data objects in data memoryspace
__farflash Controls the storage of data objects in code memoryspace
__flash Controls the storage of data objects in code memoryspace
__generic Declares a generic pointer
__huge Controls the storage of data objects in data memoryspace
__hugeflash Controls the storage of data objects in code memoryspace
__io Controls the storage of data objects in I/O memory spaceSupports I/O instructions; used for SFRs
__near Controls the storage of data objects in data memoryspace
__no_init Supports non-volatile memory
__regvar Places a data object in a register
__root Ensures that a function or data object is included in theobject code even if unused
__tiny Controls the storage of data objects in data memoryspace
__tinyflash Controls the storage of data objects in code memoryspace

这里的自定字很多,就笔者所用的芯片ATxmega64A1来讲,仅关注__flash即可,详细使用如下:
__flash Controls the storage of data objects in flash (code) memoryspace.
The __flash memory attribute places objects in flash (code)memory.
Note that it is preferable to declare flash objects as constant.The __flash keyword is
available for all AVR chips.
Because the AVR microcontrollers have only a small amount ofon-board RAM, this
memory should not be wasted on data that could be stored in flashmemory (of which
there is much more). However, because of the architecture of theprocessor, a default
pointer cannot access the flash memory. The __flash keyword is usedto identify that
the constant should be stored in flash.
A header file called pgmspace.h is installed in the avr\incdirectory, to provide some
standard C library functions for taking strings stored in flashmemory as arguments.
Examples
A program defines a couple of strings that are stored in flashmemory:
__flash char str1[] = "Message 1";
__flash char str2[] = "Message 2";
The program creates a __flash pointer to point to one of thesestrings, and assigns it
to str1:
char __flash *msg;
  msg=str1;

到这,理论知识已准备充足,再来看看实践吧。

首先看下map文件,
Module               CODE   DATA
------               ----   ----
                    (Rel)  (Rel)
?C_STARTUP             44
?EPILOGUE_B_L09        42
?FILLER_BYTES           4
  +common            496
?FLOATS_L04           812
?L_EC_MUL_L03          64
?PROLOGUE_L09          34
?RESET
  +common              4
?SL_DIVMOD_L03         16
?SS_DIVMOD_L02         48
?SS_SHR_L02            12
?S_EC_MUL_L02          16
?S_SHL_L02             12
?UL_DIVMOD_L03         70
?UL_SHR_L03            16
?US_DIVMOD_L02         40
?__exit                 2
?_exit                  4
?exit                   4
?frexp                196
?low_level_init         4
?segment_init         162
?xV_SWITCH_L06        156
?xdnorm               156
AppPrintf           2844    96
AppService          2 026   198
CMD_List            3 659  1 592
  +shared             20
QueueList             170
eeprom              1506     6
eeprom_driver         188
fpga                2 273   128
gpio_driver           336    44
  +common            388
main                1 689   212
nmea_decode         1 694   298
shellMain             736    158
system              1 114
timer_driver          256     2
  +common             68
usart_driver          950    594
  +common            496
N/A (commandline)           288
N/A (alignment)
----------         ------  -----
Total:             21 375  3 616
  +common            496
这里仅以CMD_List一个文件为例进行优化,编译结果显示CMD_List占用1592字节内存。
分析代码发现问题主要集中在一个打印输出的方式上,更改前:
u32 GetVersion(s16 argc, TCHAR* argv[])
{
Shell_OutTXT(curSwitch, "$UNCMT,================================\r\n");
Shell_OutTXT(curSwitch, "$UNVER,3.1.0,Build: %s%s\r\n",__DATE__,__TIME__);
Shell_OutTXT(curSwitch, "$UNAUR,walnutcy,Email:walt_chen@163.com\r\n");
Shell_OutTXT(curSwitch, "$UNCMT,================================\r\n");

return 0;
}

按IAR的扩展定义要求,作如下更改,
增加一个接口函数UART_Flash_PrintStr,extern void UART_Printf(u8 sw, const char *fmt, ...);
extern void UART_Flash_PrintStr(u8 sw,const char _MEMATTR * fmt);

#define Shell_OutTXTUART_Printf
#define Shell_OutTXT_FUART_Flash_PrintStr


并更改字符串定义如下:#define _MEMATTR__flash

_MEMATTR const char s_ver_comment[] ="$UNCMT,================================\r\n";
_MEMATTR const char s_ver_info1[] ="$UNVER,3.1.0,Build: "__DATE__ " " __TIME__"\r\n";
_MEMATTR constchar s_ver_info2[] ="$UNAUR,walnutcy,Email:walt_chen@163.com\r\n";

u32 GetVersion(s16 argc, TCHAR *argv[])
{
Shell_OutTXT_F(curSwitch, s_ver_comment);
Shell_OutTXT_F(curSwitch, s_ver_info1);
Shell_OutTXT_F(curSwitch, s_ver_info2);
Shell_OutTXT_F(curSwitch, s_ver_comment);
return 0;
}

可以精简内存几百字节,按同样道理修改CMD_List中其他类似模块,可以优化到以下结果:
CMD_List            3 721   687
  +shared             20

另一种办法是修改编译设置,如下图所示:

但按理论而言,需要对等修改函数,类似于笔者增加的函数:
void
UART_Flash_PrintStr(u8 sw, const char _MEMATTR * fmt);
这里不再做测试,因为需要修改原始的函数较多。
如有更好的想法,可以邮件联系walnutcy#gmail.com;

相关帖子

沙发
aaron96031| | 2013-9-21 22:23 | 只看该作者
avr 官方函数代码 怎么下载,LA知道告知下吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

69

帖子

1

粉丝