搜索
bottom↓
回复: 40

51t9py成功移植到avr,共享GCC源代码,GCC访问flash的心得

[复制链接]

出0入0汤圆

发表于 2006-9-24 15:26:02 | 显示全部楼层 |阅读模式
经过几天努力将C51的T9输入法移植到AVR上,C51的源代码:http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=629049&bbs_page_no=1&bbs_id=1000

编译环境avr-gcc-3.4.6

由于AVRGCC与C51在很多方面的差异,T9输入法的移植还是有些难度的,集中表现在如何把拼音索引表完整地存放在flash区,并能正确地检索与读取。



1.GCC访问flash有关内容

头文件:avr/pgmspace.h

数据类型:在基类型冠以“prog_”如char -->prog_char 等等

字符指针:PGM_P(const prog_char *)

空(void)指针:PGM_VOID_P(const prog_void *)指任意类型

数组定义:(常规)类型 数组名[下标常量]PROGMEM 或 (flash)类型 数组名[下标常量]

flash区常量的初始化:

prog_char c='A';

prog_int a=1234;

prog_char str[]="string";

PGM_P pstr;

pstr=PSTR("static strings");//字符串"static strings"在flash区,宏PSTR(获得静态字符串指针)只能在函数中使用。

flash区常量的读取:

读字符:pgm_read_byte(address_short)

读字:pgm_read_word(address_short)

读n个字符/字节:void *memcpy_P(void *, PGM_VOID_P, size_t) //void * 指目的指针(在SRAM)

读字符串:char *strcpy_P(char *, PGM_P)

其他内容参阅pgmspace.h和avr-libc用户手册

2.访问或定义flash区常量应注意的问题

flash区常量是不可见的,不能用常规 的方法来读取/定义,比如:

//拼音索引表结构定义

struct t9PY_index

{

    PGM_P    t9PY_T9;

    PGM_P    PY;

    PGM_P    PY_mb;

};

const prog_char PY_mb_space     []PROGMEM={""};

const prog_char PY_mb_a     []PROGMEM={"@啊阿"};

...

}

/*"拼音输入法查询码表,T9数字字母索引表(index)"*/

const struct t9PY_index  t9PY_index2[]PROGMEM ={

{"","",PY_mb_space},

{"2","a",PY_mb_a},

..

}

结构定义中的所有域都定义成PGM_P,按理拼音输入法查询码表t9PY_index2所有数据都应放在flash区,但事实并不这样,“”、“2”、“a"

却放在.data段(SRAM),不管在字符串常量前加强制类型转换,这是因为GCC把全局或静态常量强制放在.data段(SRAM),解决的方法是

字符串常量换成常量标识符:

const prog_char digits_2[]="2";

..

const prog_char alpha_a[]="a";

..

const struct t9PY_index  t9PY_index2[]PROGMEM ={

{PY_mb_space,PY_mb_space,PY_mb_space},

{digits_2,alpha_a,PY_mb_a},

..

}





PGM_VOID_P p_PY_CurrenIndex;//指向拼音输入法查询码表的指针

指向flash 结构指针或结构类型不能用指向符或域引用符获取结构的域成员,如(struct t9PY_index) p_PY_CurrenIndex->t9PY_T9。

正确方法:

struct t9PY_index PY_TempIndex;

char  temp_t9PY_T9[8],*str;

memcpy_P(&PY_TempIndex,p_PY_CurrenIndex,sizeof(struct t9PY_index));

strcpy_P(temp_t9PY_T9,PY_TempIndex.t9PY_T9);

str=strstr(temp_t9PY_T9,p_PadInput);





点击此处下载源代码

出0入0汤圆

发表于 2006-9-24 20:22:04 | 显示全部楼层
这个还是要顶的,谢谢楼主

出0入0汤圆

发表于 2006-9-24 23:19:37 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2007-10-16 13:03:53 | 显示全部楼层
永远都感谢楼主的大力贡献、、、、、、、、、、、

出0入0汤圆

发表于 2007-10-16 14:11:22 | 显示全部楼层
其实没必要用memcpy_P()每次都把FLASH一个结构体复制到SRAM。

出0入0汤圆

发表于 2007-10-16 17:18:40 | 显示全部楼层
顶一下!
关于gcc,winavr的教程还是比较少的!
icc好象是老少皆易!^_^
正在学习使用winavr中......

出0入0汤圆

发表于 2007-10-18 14:39:16 | 显示全部楼层
请问楼主有没有像显示手机那样的方法,用键盘控制,打出字来显示到液晶12864中???
请赐教///

出0入0汤圆

发表于 2007-10-18 14:52:27 | 显示全部楼层
处理flash GCC还是比较烦,还是IAR好。

出0入0汤圆

发表于 2007-10-20 09:54:54 | 显示全部楼层
> "make.exe" all

-------- begin --------
avr-gcc (GCC) 3.4.3
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Size before:
testpp.elf  :
section            size      addr
.data               282   8388864
.text             17940         0
.bss                 76   8389146
.noinit               0   8389222
.eeprom               0   8454144
.debug_aranges       64         0
.debug_pubnames   15055         0
.debug_info       40267         0
.debug_abbrev       805         0
.debug_line        1521         0
.debug_str        11297         0
.debug_ranges        12     17940
Total             87319


AVR Memory Usage:
-----------------
Device: atmega128

Program:   18222 bytes (13.9% Full)
(.text + .data + .bootloader)

Data:        358 bytes (8.7% Full)
(.data + .bss + .noinit)



Compiling C: main.c
avr-gcc -c -mmcu=atmega128 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.lst  -std=gnu99 -Wundef -MD -MP -MF .dep/main.o.d main.c -o obj/main.o
main.c: In function `main':
main.c:132: error: variable `uart_stream' has initializer but incomplete type
main.c:132: warning: implicit declaration of function `FDEV_SETUP_STREAM'
main.c:132: error: `FDEV_SETUP_RW' undeclared (first use in this function)
main.c:132: error: (Each undeclared identifier is reported only once
main.c:132: error: for each function it appears in.)
main.c:132: error: storage size of 'uart_stream' isn't known
main.c:132: warning: unused variable `uart_stream'
make.exe: *** [obj/main.o] Error 1

> Process Exit Code: 2


这是啥错误

出0入0汤圆

发表于 2007-10-25 15:37:00 | 显示全部楼层
可能是目标文件夹缺少uart.h或uart.c,(只是猜测),
本人编译结果如下:
rm -rf main.o uart.o avrt9py.o  t9.elf dep/* t9.hex t9.eep
Build succeeded with 0 Warnings...
avr-gcc.exe  -mmcu=atmega32 -Wall -gdwarf-2 -O0 -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
avr-gcc.exe  -mmcu=atmega32 -Wall -gdwarf-2 -O0 -MD -MP -MT uart.o -MF dep/uart.o.d  -c  ../../t9pyAVR/uart.c
avr-gcc.exe  -mmcu=atmega32 -Wall -gdwarf-2 -O0 -MD -MP -MT avrt9py.o -MF dep/avrt9py.o.d  -c  ../../t9pyAVR/avrt9py.c
avr-gcc.exe -mmcu=atmega32  main.o uart.o avrt9py.o     -o t9.elf
avr-objcopy -O ihex -R .eeprom  t9.elf t9.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex t9.elf t9.eep
d:\Program Files\WinAVR\bin\avr-objcopy.exe: there are no sections to be copied!
d:\Program Files\WinAVR\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used
make: *** [t9.eep] Error 1
Build succeeded with 0 Warnings...

好像有一个问题:
d:\Program Files\WinAVR\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used
make: *** [t9.eep] Error 1

出0入0汤圆

发表于 2007-11-9 01:08:14 | 显示全部楼层
记号

出0入0汤圆

发表于 2007-11-9 08:46:05 | 显示全部楼层
感谢

出0入0汤圆

发表于 2008-1-15 14:12:09 | 显示全部楼层
看看。。谢谢·!

出0入0汤圆

发表于 2009-1-7 09:10:18 | 显示全部楼层
想问一下楼主 你的移植程序太棒了 我编译通过了为什么在 你提供的仿真中不能进行输入呢?

出0入0汤圆

发表于 2009-4-7 21:24:43 | 显示全部楼层
Mark之

出0入0汤圆

发表于 2009-4-8 14:00:16 | 显示全部楼层
Mark

出0入0汤圆

发表于 2009-4-9 09:12:26 | 显示全部楼层
顶一下
高手

出0入0汤圆

发表于 2009-5-7 12:19:53 | 显示全部楼层
学习了,谢谢LZ

出0入0汤圆

发表于 2009-5-7 17:49:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-25 15:03:53 | 显示全部楼层
flag

出0入0汤圆

发表于 2009-9-17 10:44:51 | 显示全部楼层
想问下楼主大师:void uart_init(void) __attribute__ ((naked)) __attribute__ ((section (".init0")));这个语句的作用是什么?
                 tmp = (RxHead+1)&RXBUFMASK;这个语句的作用是什么?
谢谢了!

出0入0汤圆

发表于 2009-9-20 13:44:29 | 显示全部楼层
mark1

出0入0汤圆

发表于 2010-1-4 22:53:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-4 23:44:28 | 显示全部楼层
既然被挖出来了,就mark一个

出0入0汤圆

发表于 2010-1-5 13:47:15 | 显示全部楼层
继续顶起来

出0入0汤圆

发表于 2010-1-5 14:40:31 | 显示全部楼层
ding

出0入0汤圆

发表于 2010-1-5 15:07:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-7 02:48:09 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-12 11:41:59 | 显示全部楼层
正在学习使用。谢谢。

出0入0汤圆

发表于 2010-1-12 13:04:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-4 11:03:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-15 14:37:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-15 14:58:21 | 显示全部楼层
记号~~

出0入0汤圆

发表于 2010-5-15 15:30:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-28 16:47:58 | 显示全部楼层
顶一个!回去再好好看!

出0入0汤圆

发表于 2011-8-25 08:10:57 | 显示全部楼层
MARK

出0入0汤圆

发表于 2012-6-6 17:49:58 | 显示全部楼层
MARK,慢慢学。

出0入0汤圆

发表于 2012-7-11 19:38:41 | 显示全部楼层
mark.......

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-7 23:45

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

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