打印

在我的**中

[复制链接]
10263|40
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
程序匠人|  楼主 | 2008-7-1 17:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

 如何实现对PIC芯片ROM中的程序地址的精确定位。
一个悬而未决的问题,历时4个月终于获解。大块人心。
事情要从4个月前的一场讨论说起。详细情况见:天梯 之 从零开始玩PIC——11.关于FLASH操作的讨论 

问题的实质,就是如何实现对ROM中的程序地址的精确定位。因为只有精确定位了,才能通过对FLASH的写操作来修改表格中的数据。(甚至可以修改程序!)。

当时,yewuyi 和martin 参与了讨论。并且,martin给出了一个不太理想的解决方案:在编译器命令行选项中进行设置,让编译器绝对避开某些区域。然后把这块区域开辟为表格。但是这个方案的缺点是,在烧芯片时,无法对表格内容初始化,必须通过串口下载,由单片机程序去修改。

这个问题被悬置了很久,今天,终于在网上看到一篇贴(参见:PICC中如何用指针访问const 数组?),匠人由此受到启发。找到了问题的解决方案,总结如下:

1、在定义const数组的同时,定义const指针:

const tU08 LED_TAB[]=
{
        //。。。。内容略。。。。 
};
const tU08 *romPtr; //定义指向ROM 的指针

2、程序中可以对上面的指针变量赋值和实现取数操作:

tU08 i ;
romPtr = LED_TAB;
i=*romPtr++; //取指针指向的一个数,然后指针加1

3、同样的,我们也可以把romPtr 指针值传递给其他变量:

tU16 m;
romPtr = LED_TAB;
m=romPtr;

4、更神奇的是,我们可以通过这种方式,找到任意一个函数的起始PC地址:

romPtr = temp_cnt;   //说明:“temp_cnt”为一个函数。

5、找到了地址,再要修改该地址所在的FLASH,自然应该没有问题了吧。呵呵。





 
沙发
lanyong| | 2008-7-1 17:14 | 只看该作者

?

我要把
 
void led(); 放在0x0800处.

void lcd();放在0x0fff处.

怎么弄,请给个例子,我编下.

picc,picc18

使用特权

评论回复
板凳
lanyong| | 2008-7-1 17:17 | 只看该作者

here

http://www.goldenchip.com.cn/gdbbs/dispbbs.asp?id=200585147403442&announceid=200585147403442&prefile=searchlist.asp&searchkey=picc&boardid=5&area=0&dateandtime=all&username=lanyong&dpi=0&page=1&skin=0#200585147403442

http://www.htsoft.com/forum/all/showflat.php/Cat/0/Number/18355/an/0/page/0#18355

使用特权

评论回复
地板
程序匠人|  楼主 | 2008-7-1 17:25 | 只看该作者

抱歉俺说的定位,是指“寻址”,而不是分配地址

使用特权

评论回复
5
yewuyi| | 2008-7-1 17:26 | 只看该作者

我当时的回复!

yewuyi 发表于 2008-2-15 08:51 PIC 单片机 ←返回版面    

155楼:  

87X没有固化的BOOTLOAD,需要自己写。


‘表格的地址怎么确定’好象不是什么大问题把?

不能取得地址的话,你定的表格怎么查啊?!


如果你只是想修改一下表格的话,其实很好办啊,不需要什么BOOTLOAD:
1:程序中定义一个数组,用它存你的表格,这个数组可以在EE/FLASH/RAM中
   估计你的表格不能放在RAM中,那只能是EE和FLASH了
2:UART接受表格数据和表格地址,并把接受到的数据按照接受到的表格地址
   写入EE或FLASH中
3:写EE和FLASH的代码你自己已经在上面整出来了
4:程序中一定要防止写FLASH越界,否则把CHIP中代码冲掉了可和我没关系,呵呵,俺建议你还是放EE中把~~
 
-----------------------------------------------------------FLASH擦除是对整页操作的,所以,你定义的CONST数组依然要采用绝对定位的方式,否则,就不能保证擦除不出问题。
所以,个人感觉,这个东西依然需要自己判断是出现跨页越界发生。

使用特权

评论回复
6
lanyong| | 2008-7-1 17:26 | 只看该作者

o,又理解错了.

前段时间好象有个兄弟要定位,不知道搞定没有.

使用特权

评论回复
7
yewuyi| | 2008-7-1 17:27 | 只看该作者

前段时间的那个兄弟用的好象是PICC18

那个好象和PICC16又不一样了。

使用特权

评论回复
8
lanyong| | 2008-7-1 17:33 | 只看该作者

看我原来弄的!

http://www.htsoft.com/forum/all/showflat.php?Cat=0&Board=pic&Number=18429&Searchpage=1&Main=18429&Words=+lanyong&topic=&Search=true#Post18429

#include 

/* 
linker: 
-L-planyong0=400h -L-planyong1=500h 
*/ 

#pragma psect text=lanyong%%u 
void test(void){} 

#pragma psect text%%u=lanyong%%u 
void test1(void){} 

void main(void) 

test(); 
test1(); 

使用特权

评论回复
9
程序匠人|  楼主 | 2008-7-1 17:35 | 只看该作者

yewuyi的意思是不能对单个FLASH字节进行修改?

使用特权

评论回复
10
程序匠人|  楼主 | 2008-7-1 17:37 | 只看该作者

lanyong在picc下是否也有效?

使用特权

评论回复
11
yewuyi| | 2008-7-1 17:41 | 只看该作者

对这句话有疑惑……

当时,yewuyi 和martin 参与了讨论。并且,martin给出了一个不太理想的解决方案:在编译器命令行选项中进行设置,让编译器绝对避开某些区域。然后把这块区域开辟为表格。但是这个方案的缺点是,在烧芯片时,无法对表格内容初始化,必须通过串口下载,由单片机程序去修改。




在我见到的很多编程器软件中,似乎都支持对HEX文件绝对定位的调入,你使用MARTIN的方法生成一个应用程序的HEX文件,当然了,这个HEX文件肯定要保留出那块数据区域,然后把你的数据表格做成另外一个HEX文件,打开编译器软件,按照0X0000开始地址调入这个文件,然后再调入第二个HEX文件,在调入的时候把0X0000的开始地址修改为你的表格的目标开始地址,把结束地址修改为你的表格的目标结束地址,这样不就合并成功了吗?

以上描述是基于XELTEK280U编程器软件所做的推断。

如果使用ICD2烧写HEX,在MPLAB里面似乎也可以选择烧写的开始地址和结束地址的把?!
如果具备这个功能应该就可以方便的实现你想要的初始化想法了把?

使用特权

评论回复
12
yewuyi| | 2008-7-1 17:46 | 只看该作者

在我的**中

FLASH要想对单字节修改,一般是先把这个页的所有数据读到RAM中,然后在RAM中修改完那个字节,然后再整体给PIC写进去的。


以上判断仅是根据经验,并没有通过实际检验,我再翻一下手册看看那段是如何描述的,呵呵,如果上次我所讲过的,在PIC上我没有真正弄过写FLASH,只是看手册的感觉。


看样子,lanyong似乎真正操作过,不过从你给的那段代码看,好象是PICC18下的例子,请问是否如此?!

使用特权

评论回复
13
lanyong| | 2008-7-1 17:49 | 只看该作者

刚才又实验了,可以的,pic18的

#include <pic18.h>

/*
linker: 
-L-planyong0=400h -L-planyong1=500h 

*/

#pragma psect text=lanyong%%u 
void test(void){} 

#pragma psect text%%u=lanyong%%u 
void test1(void){} 

void main(void) 

test(); 
test1(); 


要把-L-planyong0=400h -L-planyong1=500h 弄到linker里去.

picc的我没有装,应该也是可以的.

使用特权

评论回复
14
程序匠人|  楼主 | 2008-7-1 17:54 | 只看该作者

刚才在网上找到这句话,匠人的心是哇凉哇凉的

FLASH也是可以存数据的,只是你在使用当中,FLASH就必须先擦除才能写入,而且是以页为单位擦的;而EEPROM就不用,但从成本上来说EEPROM就比FLASH贵多了。这个是一些表面的差别,大家有空的话,看看有关说明吧。

使用特权

评论回复
15
yewuyi| | 2008-7-1 17:57 | 只看该作者

嘿嘿,所有的FLASH都这样

刚看了一下,PIC是对页分的比较小的,一般似乎才8个字,嘿嘿,很多CHIP都是256个字或者更大。

使用特权

评论回复
16
程序匠人|  楼主 | 2008-7-1 17:57 | 只看该作者

回 yewuyi

是这样的,匠人想做的是:通过单片机的串口,传递新的数据给单片机并保存在表格区,替换原有的表格。


-------------------------------------
 yewuyi 发表于 2008-7-1 17:41 PIC 单片机 ←返回版面    

11楼: 对这句话有疑惑…… 

当时,yewuyi 和martin 参与了讨论。并且,martin给出了一个不太理想的解决方案:在编译器命令行选项中进行设置,让编译器绝对避开某些区域。然后把这块区域开辟为表格。但是这个方案的缺点是,在烧芯片时,无法对表格内容初始化,必须通过串口下载,由单片机程序去修改。




在我见到的很多编程器软件中,似乎都支持对HEX文件绝对定位的调入,你使用MARTIN的方法生成一个应用程序的HEX文件,当然了,这个HEX文件肯定要保留出那块数据区域,然后把你的数据表格做成另外一个HEX文件,打开编译器软件,按照0X0000开始地址调入这个文件,然后再调入第二个HEX文件,在调入的时候把0X0000的开始地址修改为你的表格的目标开始地址,把结束地址修改为你的表格的目标结束地址,这样不就合并成功了吗?

以上描述是基于XELTEK280U编程器软件所做的推断。

如果使用ICD2烧写HEX,在MPLAB里面似乎也可以选择烧写的开始地址和结束地址的把?!
如果具备这个功能应该就可以方便的实现你想要的初始化想法了把? 
 

使用特权

评论回复
17
lanyong| | 2008-7-1 17:58 | 只看该作者

table read write

从来没去看过.

感觉高深了哈.

一般做bootloader的人才去弄.

使用特权

评论回复
18
yewuyi| | 2008-7-1 17:58 | 只看该作者

上面是PIC16F88X系列中文手册的一页

使用特权

评论回复
19
yewuyi| | 2008-7-1 18:01 | 只看该作者

lanyong的那个方法可能在PICC16下实现有点难度

呵呵,俺真没找到PICC16的连接文件在哪里!?


PICC18下实现那个以前见到有人弄过,但PICC16下似乎一直没见到有人搞。

使用特权

评论回复
20
sz_kd| | 2008-7-1 18:01 | 只看该作者

顶下

使用特权

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

本版积分规则

734

主题

11156

帖子

678

粉丝