在我的**中

[复制链接]
11475|40
 楼主| 程序匠人 发表于 2008-7-1 17:07 | 显示全部楼层 |阅读模式
<br />&nbsp;如何实现对PIC芯片ROM中的程序地址的精确定位。<br />一个悬而未决的问题,历时4个月终于获解。大块人心。<br />事情要从4个月前的一场讨论说起。详细情况见:天梯&nbsp;之&nbsp;从零开始玩PIC——11.关于FLASH操作的讨论&nbsp;<br /><br />问题的实质,就是如何实现对ROM中的程序地址的精确定位。因为只有精确定位了,才能通过对FLASH的写操作来修改表格中的数据。(甚至可以修改程序!)。<br /><br />当时,yewuyi&nbsp;和martin&nbsp;参与了讨论。并且,martin给出了一个不太理想的解决方案:在编译器命令行选项中进行设置,让编译器绝对避开某些区域。然后把这块区域开辟为表格。但是这个方案的缺点是,在烧芯片时,无法对表格内容初始化,必须通过串口下载,由单片机程序去修改。<br /><br />这个问题被悬置了很久,今天,终于在网上看到一篇贴(参见:PICC中如何用指针访问const&nbsp;数组?),匠人由此受到启发。找到了问题的解决方案,总结如下:<br /><br /><font color=#FF0000>1、在定义const数组的同时,定义const指针:</font><br /><br />const&nbsp;tU08&nbsp;LED_TAB[]=<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//。。。。内容略。。。。&nbsp;<br />};<br />const&nbsp;tU08&nbsp;*romPtr;&nbsp;//定义指向ROM&nbsp;的指针<br /><br /><font color=#FF0000>2、程序中可以对上面的指针变量赋值和实现取数操作:</font><br /><font color=#FF0000><br /></font>tU08&nbsp;i&nbsp;;<br />romPtr&nbsp;=&nbsp;LED_TAB;<br />i=*romPtr++;&nbsp;//取指针指向的一个数,然后指针加1<br /><br /><font color=#FF0000>3、同样的,我们也可以把romPtr&nbsp;指针值传递给其他变量:</font><br /><br />tU16&nbsp;m;<br />romPtr&nbsp;=&nbsp;LED_TAB;<br />m=romPtr;<br /><br /><font color=#FF0000>4、更神奇的是,我们可以通过这种方式,找到任意一个函数的起始PC地址:</font><br /><br />romPtr&nbsp;=&nbsp;temp_cnt;&nbsp;&nbsp;&nbsp;//说明:“temp_cnt”为一个函数。<br /><br /><font color=#FF0000>5、找到了地址,再要修改该地址所在的FLASH,自然应该没有问题了吧。呵呵。<br /></font><br /><br /><br /><br /><br />&nbsp;
lanyong 发表于 2008-7-1 17:14 | 显示全部楼层

?

我要把<br />&nbsp;<br />void&nbsp;led();&nbsp;放在0x0800处.<br /><br />void&nbsp;lcd();放在0x0fff处.<br /><br />怎么弄,请给个例子,我编下.<br /><br />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<br /><br />http://www.htsoft.com/forum/all/showflat.php/Cat/0/Number/18355/an/0/page/0#18355
 楼主| 程序匠人 发表于 2008-7-1 17:25 | 显示全部楼层

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

  
yewuyi 发表于 2008-7-1 17:26 | 显示全部楼层

我当时的回复!

yewuyi&nbsp;发表于&nbsp;2008-2-15&nbsp;08:51&nbsp;PIC&nbsp;单片机&nbsp;←返回版面&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />155楼:&nbsp;&nbsp;<br /><br />87X没有固化的BOOTLOAD,需要自己写。<br /><br /><br />‘表格的地址怎么确定’好象不是什么大问题把?<br /><br />不能取得地址的话,你定的表格怎么查啊?!<br /><br /><br />如果你只是想修改一下表格的话,其实很好办啊,不需要什么BOOTLOAD:<br />1:程序中定义一个数组,用它存你的表格,这个数组可以在EE/FLASH/RAM中<br />&nbsp;&nbsp;&nbsp;估计你的表格不能放在RAM中,那只能是EE和FLASH了<br />2:UART接受表格数据和表格地址,并把接受到的数据按照接受到的表格地址<br />&nbsp;&nbsp;&nbsp;写入EE或FLASH中<br />3:写EE和FLASH的代码你自己已经在上面整出来了<br />4:程序中一定要防止写FLASH越界,否则把CHIP中代码冲掉了可和我没关系,呵呵,俺建议你还是放EE中把~~<br />&nbsp;<br />-----------------------------------------------------------FLASH擦除是对整页操作的,所以,你定义的CONST数组依然要采用绝对定位的方式,否则,就不能保证擦除不出问题。<br />所以,个人感觉,这个东西依然需要自己判断是出现跨页越界发生。<br />
lanyong 发表于 2008-7-1 17:26 | 显示全部楼层

o,又理解错了.

前段时间好象有个兄弟要定位,不知道搞定没有.
yewuyi 发表于 2008-7-1 17:27 | 显示全部楼层

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

那个好象和PICC16又不一样了。
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<br /><br />#include&nbsp;<br /><br />/*&nbsp;<br />linker:&nbsp;<br />-L-planyong0=400h&nbsp;-L-planyong1=500h&nbsp;<br />*/&nbsp;<br /><br />#pragma&nbsp;psect&nbsp;text=lanyong%%u&nbsp;<br />void&nbsp;test(void){}&nbsp;<br /><br />#pragma&nbsp;psect&nbsp;text%%u=lanyong%%u&nbsp;<br />void&nbsp;test1(void){}&nbsp;<br /><br />void&nbsp;main(void)&nbsp;<br />{&nbsp;<br />test();&nbsp;<br />test1();&nbsp;<br />}&nbsp;<br />
 楼主| 程序匠人 发表于 2008-7-1 17:35 | 显示全部楼层

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

  
 楼主| 程序匠人 发表于 2008-7-1 17:37 | 显示全部楼层

lanyong在picc下是否也有效?

  
yewuyi 发表于 2008-7-1 17:41 | 显示全部楼层

对这句话有疑惑……

当时,yewuyi&nbsp;和martin&nbsp;参与了讨论。并且,martin给出了一个不太理想的解决方案:在编译器命令行选项中进行设置,让编译器绝对避开某些区域。然后把这块区域开辟为表格。但是这个方案的缺点是,在烧芯片时,无法对表格内容初始化,必须通过串口下载,由单片机程序去修改。<br /><br /><br /><br /><br />在我见到的很多编程器软件中,似乎都支持对HEX文件绝对定位的调入,你使用MARTIN的方法生成一个应用程序的HEX文件,当然了,这个HEX文件肯定要保留出那块数据区域,然后把你的数据表格做成另外一个HEX文件,打开编译器软件,按照0X0000开始地址调入这个文件,然后再调入第二个HEX文件,在调入的时候把0X0000的开始地址修改为你的表格的目标开始地址,把结束地址修改为你的表格的目标结束地址,这样不就合并成功了吗?<br /><br />以上描述是基于XELTEK280U编程器软件所做的推断。<br /><br />如果使用ICD2烧写HEX,在MPLAB里面似乎也可以选择烧写的开始地址和结束地址的把?!<br />如果具备这个功能应该就可以方便的实现你想要的初始化想法了把?<br />
yewuyi 发表于 2008-7-1 17:46 | 显示全部楼层

在我的**中

FLASH要想对单字节修改,一般是先把这个页的所有数据读到RAM中,然后在RAM中修改完那个字节,然后再整体给PIC写进去的。<br /><br /><br />以上判断仅是根据经验,并没有通过实际检验,我再翻一下手册看看那段是如何描述的,呵呵,如果上次我所讲过的,在PIC上我没有真正弄过写FLASH,只是看手册的感觉。<br /><br /><br />看样子,lanyong似乎真正操作过,不过从你给的那段代码看,好象是PICC18下的例子,请问是否如此?!
lanyong 发表于 2008-7-1 17:49 | 显示全部楼层

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

#include&nbsp;&ltpic18.h&gt<br /><br />/*<br />linker:&nbsp;<br />-L-planyong0=400h&nbsp;-L-planyong1=500h&nbsp;<br /><br />*/<br /><br />#pragma&nbsp;psect&nbsp;text=lanyong%%u&nbsp;<br />void&nbsp;test(void){}&nbsp;<br /><br />#pragma&nbsp;psect&nbsp;text%%u=lanyong%%u&nbsp;<br />void&nbsp;test1(void){}&nbsp;<br /><br />void&nbsp;main(void)&nbsp;<br />{&nbsp;<br />test();&nbsp;<br />test1();&nbsp;<br />}&nbsp;<br /><br />要把-L-planyong0=400h&nbsp;-L-planyong1=500h&nbsp;弄到linker里去.<br /><br />picc的我没有装,应该也是可以的.<br />
 楼主| 程序匠人 发表于 2008-7-1 17:54 | 显示全部楼层

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

FLASH也是可以存数据的,只是你在使用当中,FLASH就必须先擦除才能写入,而且是以页为单位擦的;而EEPROM就不用,但从成本上来说EEPROM就比FLASH贵多了。这个是一些表面的差别,大家有空的话,看看有关说明吧。
yewuyi 发表于 2008-7-1 17:57 | 显示全部楼层

嘿嘿,所有的FLASH都这样

刚看了一下,PIC是对页分的比较小的,一般似乎才8个字,嘿嘿,很多CHIP都是256个字或者更大。
 楼主| 程序匠人 发表于 2008-7-1 17:57 | 显示全部楼层

回 yewuyi

是这样的,匠人想做的是:通过单片机的串口,传递新的数据给单片机并保存在表格区,替换原有的表格。<br /><br /><br />-------------------------------------<br />&nbsp;yewuyi&nbsp;发表于&nbsp;2008-7-1&nbsp;17:41&nbsp;PIC&nbsp;单片机&nbsp;←返回版面&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />11楼:&nbsp;对这句话有疑惑……&nbsp;<br /><br />当时,yewuyi&nbsp;和martin&nbsp;参与了讨论。并且,martin给出了一个不太理想的解决方案:在编译器命令行选项中进行设置,让编译器绝对避开某些区域。然后把这块区域开辟为表格。但是这个方案的缺点是,在烧芯片时,无法对表格内容初始化,必须通过串口下载,由单片机程序去修改。<br /><br /><br /><br /><br />在我见到的很多编程器软件中,似乎都支持对HEX文件绝对定位的调入,你使用MARTIN的方法生成一个应用程序的HEX文件,当然了,这个HEX文件肯定要保留出那块数据区域,然后把你的数据表格做成另外一个HEX文件,打开编译器软件,按照0X0000开始地址调入这个文件,然后再调入第二个HEX文件,在调入的时候把0X0000的开始地址修改为你的表格的目标开始地址,把结束地址修改为你的表格的目标结束地址,这样不就合并成功了吗?<br /><br />以上描述是基于XELTEK280U编程器软件所做的推断。<br /><br />如果使用ICD2烧写HEX,在MPLAB里面似乎也可以选择烧写的开始地址和结束地址的把?!<br />如果具备这个功能应该就可以方便的实现你想要的初始化想法了把?&nbsp;<br />&nbsp;<br />
lanyong 发表于 2008-7-1 17:58 | 显示全部楼层

table read write

从来没去看过.<br /><br />感觉高深了哈.<br /><br />一般做bootloader的人才去弄.
yewuyi 发表于 2008-7-1 17:58 | 显示全部楼层

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

  
yewuyi 发表于 2008-7-1 18:01 | 显示全部楼层

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

呵呵,俺真没找到PICC16的连接文件在哪里!?<br /><br /><br />PICC18下实现那个以前见到有人弄过,但PICC16下似乎一直没见到有人搞。
sz_kd 发表于 2008-7-1 18:01 | 显示全部楼层

顶下

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

734

主题

11156

帖子

682

粉丝
快速回复 在线客服 返回列表 返回顶部