搜索
bottom↓
回复: 42

请教GCC往EEPROM存储数组,如何对EEPROM空间绝对地址定位

[复制链接]

出0入0汤圆

发表于 2006-10-19 11:17:29 | 显示全部楼层 |阅读模式
象IAR一样有

__regvar 放置一个变量在工作寄存器中

@ 用于变量的绝对地址定位。也可以用#pragma location 命令

#pragma vector 提供中断函数的入口地址

这3个,例如:



__regvar __noinit__ unsigned char saved_TWDR @ 13;



#pragma location=0x1E80

const unsigned int __flash__ sffA0Flash[256] = {}



GCC是否有相应的语句能实现哪?还是只有读写的时候规定地址?

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

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

出0入0汤圆

 楼主| 发表于 2006-10-23 16:10:33 | 显示全部楼层
#define  __EEPROM_REG_LOCATIONS__   1C1D1E

在http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html#g336a79d3c6ab1e0d870f40f090befedc

看到<avr/eeprom.h>: 头文件有这个定义,不过我使用总是提示出错啊

#pragma __EEPROM_REG_LOCATIONS__ =0x1E80

flash里面绝对定位久干脆没看到过了!郁闷啊!难道大家都不需要绝对定位吗?还是用

void EEPROM_write(unsigned int uiAddress, unsigned char ucData)实现?

出0入0汤圆

发表于 2006-10-23 19:31:52 | 显示全部楼层
没看懂楼主的意思,怎么叫作绝对定位,在avr/eeprom.h里面函数的参数里面就有地址了呀.



extern void eeprom_write_byte (uint8_t *addr, uint8_t val);

extern void eeprom_write_word (uint16_t *addr, uint16_t val);



addr就是地址,这不就是定位了吗,我用这函数就没出过问题,很简单,很好用的.

比如:

times=eeprom_read_byte((unsigned char *)0x05);

出0入0汤圆

 楼主| 发表于 2006-10-24 08:42:48 | 显示全部楼层
我的意思就是象IAR这种定位的语句

#pragma location=0x1E80

const unsigned int __flash__ sffA0Flash[256] = {}

而不是

eeprom_write_byte()

出0入0汤圆

 楼主| 发表于 2006-10-24 09:49:57 | 显示全部楼层
就算用eeprom_write_byte()

我是一个数组,只能使用

unsigned char val1 __attribute__((section(".eeprom")));

eeprom_write_byte (&val1, 0xAA);

这样还是不能定义数组的地址啊!



那flash如何定义地址写那?又没有flash_write_byte()


-----此内容被zx1221于2006-10-24,09:57:45编辑过

出0入0汤圆

 楼主| 发表于 2006-10-25 08:49:12 | 显示全部楼层
真的不能绝对定位吗?看样只能用IAR了,GCC还是有不少差距的!

出0入0汤圆

发表于 2006-10-25 09:49:51 | 显示全部楼层
unsigned char EEMEM MyE2ROM;

(或 unsigned char MyE2ROM __attribute__((section(".eeprom")));//EEPROM 变量定义方式)



unsigned int OFFSET;

for (OFFSET=0;OFFSET<0x3FF;OFFSET++) {

    eeprom_busy_wait();

    eeprom_write_byte(&MyE2ROM+OFFSET,0xAA);

}

出0入0汤圆

发表于 2006-10-25 10:22:39 | 显示全部楼层
绝对定位做甚,GCC还是有多少差距?N多人用GCC!

zx1221 幻:你的积分:209不低哈.

出0入0汤圆

 楼主| 发表于 2006-10-25 14:26:11 | 显示全部楼层
ml07077就孤陋寡闻了!绝对定位做甚?我要实现当然是有用的!而且是必须绝对定位MEGA88的512字节EEPROM的每个地址是什么数据!错1个都不行!并且用GCC的多不能代表他完善,说明他易用容易上手!并且免费!
-----此内容被zx1221于2006-10-25,14:30:11编辑过

出0入0汤圆

发表于 2006-10-25 14:44:35 | 显示全部楼层
我给的例子满足不了要求吗?



&MyE2ROM一直为零,OFFSET不就可以定位每个字节吗?

出0入0汤圆

 楼主| 发表于 2006-10-25 14:48:37 | 显示全部楼层
感谢yeungxl兄的思路!不过我定义的是数组,不是一个个数据的输入!一个个输入要写256次啊!下面这样可能行!试一下去!

#define __eeprom__ __attribute__((section(".eeprom")));

const __eeprom__ unsigned int eep[256]={}

unsigned int OFFSET,i;

for (OFFSET=0;OFFSET<0xFF;OFFSET++)

{

     

     eeprom_busy_wait();

     eeprom_write_word(&_eeprom__+OFFSET,eep);

     i++;

}

不过按照芯艺的例程eeprom_write_byte (&val1, 0xAA);

应该:

eeprom_write_word((unsigned int *)&eep,eep);



好像数组定义必须这样!还是不能实现绝对定位!先去试试了!

但是flash里面没有eeprom_write_word()这样的语句啊不知道怎么搞flash了!顺便问下flash 有可能实现绝对定位吗?

-----此内容被zx1221于2006-10-25,14:49:38编辑过



-----此内容被zx1221于2006-10-25,15:10:07编辑过


-----此内容被zx1221于2006-10-25,15:13:27编辑过

出0入0汤圆

发表于 2006-10-25 14:51:47 | 显示全部楼层
这叫函数定位,和IAR的编译定位根本不一样。

出0入0汤圆

发表于 2006-10-25 15:16:07 | 显示全部楼层
但是flash里面没有eeprom_write_word()这样的语句啊不知道怎么搞flash了!



  AVR GCC里面没有针对flash写的函数,只有读的函数:

    pgm_read_byte

    pgm_read_word

    pgm_read_dword



顺便问下flash 有可能实现绝对定位吗?

    6.5.2.1 #define PGM_P const prog_char 

      Used to declare a variable that is a pointer to a string in program space.

出0入0汤圆

 楼主| 发表于 2006-10-25 15:20:48 | 显示全部楼层
总感觉还是不对,好像是

unsigned char __eeprom__ __attribute__((section(".eeprom")));

const  unsigned int eep[256]={}

unsigned int OFFSET,i;  

for (OFFSET=0;OFFSET<0xFF;OFFSET++)  

{

      

     eeprom_busy_wait();  

     eeprom_write_word(&_eeprom__+OFFSET,eep);

     i++;

}

出0入0汤圆

 楼主| 发表于 2006-10-25 15:28:31 | 显示全部楼层
我说的绝对定位不是把他定位在flash就可以了,是要定位flash里面的每个地址

出0入0汤圆

 楼主| 发表于 2006-10-25 15:41:18 | 显示全部楼层
吐血了:

#if defined(__AVR_AT90CAN128__) || defined(__AVR_ATmega48__) ||\

    defined(__AVR_ATmega88__) || defined(__AVR_ATmega165__) ||\

    defined(__AVR_ATmega168__) || defined(__AVR_ATmega169__) ||\

    defined(__AVR_ATmega325__) || defined(__AVR_ATmega3250__) ||\

    defined(__AVR_ATmega645__) || defined(__AVR_ATmega6450__)

# warning "The functions from <avr/eeprom.h> are not supported on this MCU."

#endif

出0入0汤圆

发表于 2006-10-25 15:41:55 | 显示全部楼层
gcc根本没有,别费力了

出0入0汤圆

 楼主| 发表于 2006-10-25 15:48:44 | 显示全部楼层
aini兄说的是真的假的?不要说气话啊!要真没有我的项目还真难搞了!妈的这个项目还就是一定要实现512个eeprom数据的绝对定位啊,还有256个flash的!

出0入0汤圆

发表于 2006-10-25 16:09:43 | 显示全部楼层
看一看以下语句能否进行FLASH定位读取:

    PGM_VOID_P pCurAdd=0x60;

    unsigned char i,k[256];

    for (i=0;i<255;i++){

       k=pgm_read_byte(pCurAdd+i);

    }

出0入0汤圆

发表于 2006-10-25 16:13:05 | 显示全部楼层
不骗你,真的。所有的AVR编译器里只有IAR有绝对地址定位。CAVR也有,不过有限制不好用

出0入0汤圆

 楼主| 发表于 2006-10-25 16:25:43 | 显示全部楼层
谢谢aini 的提醒!赶紧去学IAR了! yeungxl 兄十分感谢你提供的思路!不过浪费在这一个问题2周了不能再拖了◎!再拖要被老板干掉了!学IAR!


-----此内容被zx1221于2006-10-25,16:30:51编辑过

出0入0汤圆

发表于 2006-10-25 16:42:46 | 显示全部楼层
eeprom_write_byte ((unsigned char *)0x40,0xA5);      //向EEPROM的0x40地址写入数据 0xA5

data=eeprom_read_byte ((unsigned char *)0x40);      //读出,然后看看数据对不对?

出0入0汤圆

发表于 2006-10-25 18:33:08 | 显示全部楼层
存储于EEPROM的常数直接可以用编译器写呀,为什么非要用函数的方法呢?占用程序代码。浪费。

出0入0汤圆

发表于 2006-10-25 21:07:40 | 显示全部楼层
【22楼】 aini 真聪明.

出0入0汤圆

发表于 2006-10-25 21:23:41 | 显示全部楼层
自己编 函数,想写哪 就 写哪!

出0入0汤圆

发表于 2007-12-18 14:28:30 | 显示全部楼层
register volatile INT8U filteredTimeSinceCommutation asm("r14");
各位大侠,小弟来解决这个问题

出0入0汤圆

发表于 2008-4-30 17:12:22 | 显示全部楼层
ICCAVR转到GCC,操作EEPROM也遇到问题,参考6楼的方法已经能正常读写EEPROM 了,gcc是071221版本

出0入0汤圆

发表于 2008-4-30 17:25:30 | 显示全部楼层
GCC绝对地址定位使用段定义就可以了。
unsigned char EEPROM_VAR_AT_0X20  __attribute__((section("EEPROM_0X20")));


(原文件名:Image0008.JPG)

不管是RAM,EEPROM还是FLASH,绝对地址定义都可以采用次办法。
还有外部RAM使用也用次方法。
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=990169&bbs_page_no=1&search_mode=3&search_text=ATmega32&bbs_id=9999

IAR绝对地址定义本质和GCC绝对地址定位方法是一样的。
只不过,IAR是编译器自动定义绝对地址段,而GCC需要手动定义绝对地址段。

出0入0汤圆

发表于 2008-4-30 19:26:40 | 显示全部楼层
是连续地址么?
几个变量数组连续的么?

连续的可以用 结构体 使用.变相定位了.

出0入0汤圆

发表于 2008-6-17 16:25:33 | 显示全部楼层
27楼的不好用,在studio中选择段Eeprom根本就是假的,只有自定义的段是.eeprom才能放到eeprom中指定的地址

出0入0汤圆

发表于 2008-6-17 18:50:51 | 显示全部楼层
ding

出0入0汤圆

发表于 2008-12-20 09:51:18 | 显示全部楼层
mack

出0入0汤圆

发表于 2009-2-2 14:18:33 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2009-7-21 08:44:44 | 显示全部楼层
从头看到尾,到最后还是没明白怎么用flash的绝对地址,
???比如在程序中定义一个指针char *p;p=0x2000;*p=0x56;然后运行,我们就能在flash中的0x2000地址上看到0x56这个东西……难道没有这样用的?难道gcc不能实现这个功能?难道只有iar可以?

怎么在指定的flash地址写入数据,前提是程序运行过程中,比如采集了一个数据,然后存到指定的flash地址中,然后再用串口将这个数据传输到上位机……
期盼解答,谢谢

出0入0汤圆

发表于 2009-7-21 09:25:24 | 显示全部楼层
27楼的不好用,在studio中选择段Eeprom根本就是假的,只有自定义的段是.eeprom才能放到eeprom中指定的地址 ??
-----------------------------------------------------------------------------------------------------------


(原文件名:Image0333.JPG)


(原文件名:Image0334.JPG)


(原文件名:Image0335.JPG)

出0入0汤圆

发表于 2009-7-21 12:04:25 | 显示全部楼层
没这么麻烦吧,用eeprom_read_block 和 eeprom_write_block不行吗?即能定位写也能定位读,我都用N年了,下面是我的用法,希望对大家有帮助。
另外,使用那种IDE和编译器均是自己爱好和机缘,无论是哪种编译器只要你使用得好都是好东西,不存在这个行那个不行的问题。

下面是两个读与写的函数,你也可以直接用eeprom_read_block 和 eeprom_write_block,我只是为了参数传递方便,又写了ReadDataFromEEPROM和SaveDataToEeprom
//从EEPROM中读取指定地址的指定个数字节到缓冲内;
void        ReadDataFromEEPROM(byte *sBuffer,word wStAddr,byte iReadNum)
{
                Reset_WDT();
                eeprom_read_block(sBuffer,(void *)wStAddr,iReadNum);
}
//向EEPROM中指定地址存指定个数数据;
byte        SaveDataToEeprom(byte *sBuffer,word wStAddr,byte iReadNum)
{
        if( (wStAddr<5) && (wStAddr>1023))
        {
                return        1;                //地址错;
        }
        if(iReadNum>30)
        {
                return        2;                //个数太多(此处个数自己根据情况定);
        }
        if(iIfCanWriteEEP!=0x55)     //软写保护标志,函数前手动打开。
        {
                return        3;
        }
        Reset_WDT();
        eeprom_write_block(sBuffer,(void *)wStAddr,iReadNum);
        return 0;
}

其中:byte、word、dword分别是unsigned char ,unsigned int,unsigned long的宏定义
函数的三个参数分别是:要读或写的数据缓冲指针,要读或写的绝对地址(M32的为0~1023),要读或写入数据的字节数;

///--------------以下为对上边函数的使用(为了使用方便,我多数用结构而不是直接用char数组,当然要用什么还看你自己的喜好了)。下面只列举读的,写的同理,不赘述
//读取系统数据;返回0成功
byte        ReadSysinfoFrEEP()
{
        byte        sBuffer[16];
        memset(sBuffer,0,sizeof(sBuffer));
        ReadDataFromEEPROM(sBuffer,SYSSTRUCTSTADDR,SYSSTRUCTLENGTH);    //后两个参数分别是结构在EEP中存储的开始地址和长度宏定义,
        //读出后先存备份结构中
        memset(&struSysInfo.wPrice,0,SYSSTRUCTLENGTH);
        memcpy(&struSysInfo.wPrice,sBuffer,SYSSTRUCTLENGTH);
        //验证CRC是否正确;
        if(CalculateCRC8(sBuffer,SYSSTRUCTLENGTH-1)!=sBuffer[SYSSTRUCTLENGTH-1])
        {
                  //数据校验错误,再从备份区取数据,
                memset(sBuffer,0,sizeof(sBuffer));
                ReadDataFromEEPROM(sBuffer,SYSSTRUCTSTADDR+BAKADDRELSE,SYSSTRUCTLENGTH);
                if(CalculateCRC8(sBuffer,SYSSTRUCTLENGTH-1)!=sBuffer[SYSSTRUCTLENGTH-1])
                {
                        return        2;
                }
        }
        //处理将数据复制到结构;
        memset(&struSysInfo.wPrice,0,SYSSTRUCTLENGTH);
        memcpy(&struSysInfo.wPrice,sBuffer,SYSSTRUCTLENGTH);
        return 0;
}

其中struSysInfo是一个16Byte长度的结构,其成员有uchar型的,有int型的,还有unsigned long型的。 不过定义时要注意字节对齐。

出0入0汤圆

发表于 2009-7-21 12:40:27 | 显示全部楼层
绝对定位是一种编程思想。
总体上,GCC是利用绝对定义段间接定位变量,函数。

出0入0汤圆

发表于 2010-5-11 22:19:16 | 显示全部楼层
原来可以这样,试一试

出0入0汤圆

发表于 2010-5-17 22:17:02 | 显示全部楼层
虚心学习了

出0入0汤圆

发表于 2010-6-18 12:08:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-30 17:03:51 | 显示全部楼层
mark一下,有空多学习学习。

出0入0汤圆

发表于 2010-12-30 00:37:13 | 显示全部楼层
回复【34楼】void_c  上官金虹(胡文涛)
-----------------------------------------------------------------------

上官兄,参照你的方法试图在编译过程中产生eep文件,选择了存储器类型Eeprom指定了段名称和地址,不过奇怪的是编译完成以后并未如期生成eep文件,而是将欲保存的内容放置到了Flash的对应地址里面。这是什么原因?
我使用的环境是:AVR Studio 4.18 + AVR Libc 1.6.7


(原文件名:MEMsetting.jpg)

使用:
uint8_t settings __attribute__((section(".settings"))) = 0xFE;
没有生成eep文件,0xFE保存到Flash的0x20位置。
使用:
uint8_t unitID EEMEM = 0xFE;
生成eep文件,0xFE保存在Eeprom的起始字节。

你看是哪里的问题?

谢谢!

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-6-30 17:21

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

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