搜索
bottom↓
回复: 12

在winavr gcc环境下定义变量到固定地址的flash区的方法.

[复制链接]

出0入0汤圆

发表于 2009-3-11 14:12:21 | 显示全部楼层 |阅读模式
前段时间有如题的问题,在论坛找了不少贴子看,有些启发和参考价值,但是没找到个能看了就可以用的答案(可能有但我没找到),经过2个晚上的研读(《GNU-ld链接脚本浅析》:http://blog.chinaunix.net/u/13991/showart_177822.html ) 和实践,终于自己把问题解决掉. 现在整理下,贴在这里.

可能大家都熟悉 "char  a[] PROGMEM={1,2,3,4}; "的定义方式,但是这种方式定义出来的变量地址
是由编译器和连接器分配的,不能确定. 那有什么办法没呢? 答案是有.
  
在网上搜索到2种方法:
1. 在makefile 中定义section,如下:
LDFLAGS = -Wl,--section-start=.mydatasection=0x001000,-Map=$(TARGET).map,--cref  

然后引用
const unsigned char data[] __attribute__((section(".mydatasection")))={   
0x10,0x20,0x30   
};   

2. 在连接脚本里修改设置.  

在实验方法1
在makefile 中设置
LDFLAGS += -Wl,--section-start=.mydatasection=0x001500
在main.c中引用
const unsigned char mydata[4] __attribute((section(".mydatasection"))) = {'9','1','2','3'};

但是要注意,mydatasection 的定位地址,要是其它段没有用到的才可以,否则会报错,有地址重叠.


   
实验方法2(修改连接脚本),winavr20071221 版本,默认用的是avr4.x 脚本.
先是研读了下)《GNU-ld链接脚本浅析》:http://blog.chinaunix.net/u/13991/showart_177822.html  
(惭愧啊,现在也还是没读太明白).

  我修改后的脚本内容部分:
   
   .start :     /*原来这里是.text,我改成.start*/
  {
    *(.vectors)
    KEEP(*(.vectors))
    /* For data that needs to reside in the lower 64k of progmem.  */
    *(.progmem.gcc*)
    *(.progmem*) /*呵呵,常用到的 "PROGMEM" 是在这里定义的啊 */
    . = ALIGN(2);
     __trampolines_start = . ;
    /* The jump trampolines for the 16-bit limited relocs will reside here.  */
    *(.trampolines)
    *(.trampolines*)
     __trampolines_end = . ;
    /* For future tablejump instruction arrays for 3 byte pc devices.
       We don't relax jump/call instructions within these sections.  */
    *(.jumptables)
    *(.jumptables*)
    /* For code that needs to reside in the lower 128k progmem.  */
    *(.lowtext)
    *(.lowtext*)
     __ctors_start = . ;
     *(.ctors)
     __ctors_end = . ;
     __dtors_start = . ;
     *(.dtors)
     __dtors_end = . ;
    KEEP(SORT(*)(.ctors))
    KEEP(SORT(*)(.dtors))
    /* From this point on, we don't bother about wether the insns are
       below or above the 16 bits boundary.  */
    *(.init0)  /* Start here after reset.  */
    KEEP (*(.init0))
    *(.init1)
    KEEP (*(.init1))
    *(.init2)  /* Clear __zero_reg__, set up stack pointer.  */
    KEEP (*(.init2))
    *(.init3)
    KEEP (*(.init3))
    *(.init4)  /* Initialize data and BSS.  */
    KEEP (*(.init4))
    *(.init5)
    KEEP (*(.init5))
    *(.init6)  /* C++ constructors.  */
    KEEP (*(.init6))
    *(.init7)
    KEEP (*(.init7))
    *(.init8)
    KEEP (*(.init8))
    *(.init9)  /* Call main().  */
    KEEP (*(.init9))
  }   
  
  .first_data 0x100 : AT(0x100)  /*这里开始定义第一个自己section,注意要 VMA 和LMA 都要设置,且
                                                                    相同,否则编译会有错,可能是因为不支持VMA与LMA不同地址*/
  {
    . = ALIGN(2);
         *(.first_data)
    *(.first_data*)                        /*注意这行哦,*(.first_data*) 表示用改section 定义的数据放在这里*/
  }
      

  .second_data 0x180 : AT(0x180 ) /*这里第2个*/
  {
  . = ALIGN(2);
         *(.second_data)     
         *(.second_data*)
  }
   
  .text 0x200 :  AT(0x200)   /*这里第3个*/
  {
         
    *(.text)
    . = ALIGN(2);
    *(.text.*)
    . = ALIGN(2);
    *(.fini9)  /* _exit() starts here.  */
    KEEP (*(.fini9))
    *(.fini8)
    KEEP (*(.fini8))
    *(.fini7)
    KEEP (*(.fini7))
    *(.fini6)  /* C++ destructors.  */
    KEEP (*(.fini6))
    *(.fini5)
    KEEP (*(.fini5))
    *(.fini4)
    KEEP (*(.fini4))
    *(.fini3)
    KEEP (*(.fini3))
    *(.fini2)
    KEEP (*(.fini2))
    *(.fini1)
    KEEP (*(.fini1))
    *(.fini0)  /* Infinite loop after program termination.  */
    KEEP (*(.fini0))
     _etext = . ;
  }  > text
  
.third_data 0x1400 : AT(0x1400)  /*这里第4个*/
  {
        . = ALIGN(2);
    *(.third_data)
    *(.third_data*)
  }
   
  .data          : AT (ADDR (.third_data) + SIZEOF (.third_data))
  {
     PROVIDE (__data_start = .) ;
    *(.data)
    *(.data*)
    *(.rodata)  /* We need to include .rodata here if gcc is used */
    *(.rodata*) /* with -fdata-sections.  */
    *(.gnu.linkonce.d*)
    . = ALIGN(2);
     _edata = . ;
     PROVIDE (__data_end = .) ;
  }  > data

文件中引用:
const unsigned char buff2[4] __attribute((section(".first_data"))) = {'9','1','2','3'};
const unsigned char buff3[4] __attribute((section(".first_data"))) = {'9','1','2','3'};



看编译后的map
first_data     0x00000100        0x8 load address 0x00000100
                0x00000100                . = ALIGN (0x2)
*(.first_data)
.first_data    0x00000100        0x8 main.o
                0x00000104                buff3
                0x00000100                buff2
*(.first_data*)

.second_data    0x00000180        0x0 load address 0x00000180
                0x00000180                . = ALIGN (0x2)
*(.second_data)
*(.second_data*)     
  
third_data     0x00001400        0x0 load address 0x00001400
                0x00001400                . = ALIGN (0x2)
*(.third_data)
*(.third_data*)

.data           0x00800100        0x0 load address 0x00001400
                0x00800100                PROVIDE (__data_start, .)



读取函数还是跟  用 PROGMEM 定义的一样, PROGMEM,只是告诉编译器或连接器把该变量放到什么地方去.

另外,该ld脚本是经过修改,可能就适合这个特定项目,可以在makefile 中指定该项目的特定的脚本,而不是用默认的
方法:  LDFLAGS += -Wl,-T ./avr4.x


呵呵,这样就能做到开辟一个指定地址空间的flash,用来存储特定的数据,而不必担心被其它text 或data  
占用掉.

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2009-3-17 17:28:57 | 显示全部楼层
谢谢分享!学习了。

出0入0汤圆

发表于 2009-3-17 17:58:57 | 显示全部楼层
这个得顶,谢谢楼主的分享。

出10入8汤圆

发表于 2009-3-27 09:17:22 | 显示全部楼层
支持,MARK

出0入0汤圆

发表于 2009-4-18 22:28:08 | 显示全部楼层
O(∩_∩)O谢谢

出0入0汤圆

发表于 2009-6-23 10:58:03 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-7-5 14:02:00 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-6-19 10:49:03 | 显示全部楼层
mark 在winavr gcc环境下定义变量到固定地址的flash区的方法.

出0入0汤圆

发表于 2011-3-31 11:29:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-9 17:36:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-27 13:06:23 | 显示全部楼层
受教了~尝试中~~~~~~~~·

出0入0汤圆

发表于 2012-4-3 14:07:58 | 显示全部楼层
研究学习中

出0入0汤圆

发表于 2012-9-11 21:40:31 | 显示全部楼层
这个mark不犯法吧
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 09:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表