打印

高分请教香斑竹和STM32高手几个问题

[复制链接]
楼主: 程序匠人
手机看帖
扫描二维码
随时随地手机跟帖
21
反盗版:lol

使用特权

评论回复
22
香水城| | 2012-2-24 10:24 | 只看该作者
本帖最后由 香水城 于 2012-2-24 10:27 编辑

呵呵,匠人果然与众不同,一出手就是一堆**弹。

先捡俺知道的问题尝试回答一下:

关于问题1:
首先,不知道匠人对程序区和数据区怎么划分的,在STM32中并没有对Flash做这样的区分。

关于你碰到的问题是因为,STM32在对Flash编程时会检测目标地址的内容是不是0xFFFF,如果不是,则编程失败。证据如下:


关于第2、3个问题,这是有关IAR的设置,抱歉我没有接触过,但以前有很多网友提出过设置方法,您老人家可以去看看,如果找不到,我再找人帮你解决。

第4个问题:我也没有接触过,但记得IAR中有一个RAM Function的选项,可以找找看。

第5个问题:这个问题比较简单,如果知道如何获取函数的首地址,则下一个函数的首地址就是前一个函数的尾地址。

使用特权

评论回复
23
程序匠人|  楼主 | 2012-2-24 10:49 | 只看该作者
第1个问题还要看看Flash_Write的返回值。是否真的是写入成功
第5个问题其实是这样的
假如定义的代码段起始地址为ADDR_START, 结束地址为ADDR_END,把funA-funE都放在这个代码段中
然后再定义一个函数的地址表
typed ...
lxyppc 发表于 2012-2-24 10:15


问题1,我是通过查看仿真器里的值来判断改写是否成功
问题5,我明白了你的意思,就是收集所有函数的地址,排序,然后相邻函数地址做减法,求函数长度。原理上貌似可行,唯一的缺陷是,函数太多。。。。:)

使用特权

评论回复
24
香水城| | 2012-2-24 10:58 | 只看该作者
问题1:我的意思是说:STM32中不能对Flash内容进行改写,也就是说,如果一个WORD内容不是0xFFFF,则在擦除之前,不能再对这个WORD执行写操作。

问题5:一般在C程序中相邻的函数,编译之后也是相邻的,因此你不必收集所有函数的地址,只需要知道你要找的函数的下一个函数是谁就可以了。
例如:在main.c中有如下函数:

void FuncA()
{
......
}

void FuncB()
{
......
}

void FuncC()
{
......
}

编译后在内存中FuncB紧跟FuncA,FuncC紧跟FuncB,这一点可以通过察看.map文件验证。

使用特权

评论回复
25
程序匠人|  楼主 | 2012-2-24 11:23 | 只看该作者
刚才发帖没注意,把“问题5”写成了“问题2”。连累香斑竹也跟着错了。为了避免讨论时混淆,订正一下。:lol

使用特权

评论回复
26
程序匠人|  楼主 | 2012-2-24 11:24 | 只看该作者
刚才发帖没注意,把“问题5”写成了“问题2”。连累香斑竹也跟着错了。为了避免讨论时混淆,订正一下。:lol

使用特权

评论回复
27
程序匠人|  楼主 | 2012-2-24 11:39 | 只看该作者
呵呵,匠人果然与众不同,一出手就是一堆**弹。

先捡俺知道的问题尝试回答一下:

关于问题1:
首先,不知道匠人对程序区和数据区怎么划分的,在STM32中并没有对Flash做这样的区分。

关于你碰到的问题是因为,STM3 ...
香水城 发表于 2012-2-24 10:24



关于问题1:答复香斑:
我说的数据区就是const数组,代码区就是指函数。
如果说是因为写保护,那我可以理解。不过如此一来,问题1就转变成了:同样是存放在FLASH中,为什么const数组可以被改写?

为了说明问题,我把相关的程序挑有用的放上来,请注意红色字体。


//--------------------------------------------------------
//数据表
//--------------------------------------------------------
const u32 R_tab[]=
{
0x12345678, //0
  //更多数据省略……
}
//--------------------------------------------------------
//函数
//--------------------------------------------------------
u32 CNT_v1(u32 data)  
{
    //代码省略……  
}

改写数据区:
  FLASH_Unlock();                             //解锁FLASH编程擦除控制器
  Address=(vu32)&(R_tab);                     //获取表格地址
  FLASH_ProgramWord ((Address), 0);           //写32位数据(调用《stm32f10x_flash.c》的函数)(这一步能够成功
  FLASH_Lock();                               //锁定FLASH编程擦除控制器

改写代码区:
  FLASH_Unlock();                             //解锁FLASH编程擦除控制器
  Address=(vu32)&(CNT_v1);                   //获取某个函数函数地址
  FLASH_ProgramWord ((Address), 0);           //写32位数据(调用《stm32f10x_flash.c》的函数)(这一步失败
  FLASH_Lock();                               //锁定FLASH编程擦除控制器

使用特权

评论回复
28
程序匠人|  楼主 | 2012-2-24 11:45 | 只看该作者
24# 香水城

关于问题5,我也注意到大多数情况下函数都是按顺序编译摆放的。但const数组除外。

我担心的是编译器的优化会不会擅自把我的函数挪动位置或合并,呵呵。

这个问题不大,可以就此不再讨论。

---------------
我比较关心是问题2和问题4.

使用特权

评论回复
29
香水城| | 2012-2-24 11:55 | 只看该作者
第1个问题:关键是写的时候,目标地址原有的内容是否为0xFFFF,如果不是则写入失败。

第5个问题:可以通过检查.map验证,编译器的优化会不会擅自把函数挪动位置或合并,这个验证只要在需要的时候做就可以,比如第一次使用某种优化选项时、出现问题时、项目结束之前等。

使用特权

评论回复
30
香水城| | 2012-2-24 12:16 | 只看该作者
关于问题2:应该是在存储配置文件(好像是ICF文件)中定义一个新的段(好像叫SECTION),然后在程序中指定特定的函数或数据到这个SECTION中。

建议看看外设寄存器的分配方式作为参考。外设寄存器都是成组的,每组之间都不是连续的。

使用特权

评论回复
31
香水城| | 2012-2-24 12:19 | 只看该作者
关于问题4:在IAR手册中应该可以找到有关RAM Function的说明,记得有一个ramfunction的Pragma就是用来说明某个函数需要在RAM中运行,这样制定之后,编译器会使用相对寻址指令,运行时自己把它拷贝到某个预先定义好的数组中运行,运行结束后把数组内容清除即可。

使用特权

评论回复
32
程序匠人|  楼主 | 2012-2-24 12:36 | 只看该作者
第1个问题:关键是写的时候,目标地址原有的内容是否为0xFFFF,如果不是则写入失败。

第5个问题:可以通过检查.map验证,编译器的优化会不会擅自把函数挪动位置或合并,这个验证只要在需要的时候做就可以,比如第一 ...
香水城 发表于 2012-2-24 11:55


香斑竹“回击”的**弹火力也很猛啊,让我“应接不暇”。我喜欢这种火力,让**弹来得更猛烈些吧……:P

关于问题1:请留意我27贴,我再复制一下:
//--------------------------------------------------------
//数据表
//--------------------------------------------------------
const u32 R_tab[]=
{
0x12345678, //0
  //更多数据省略……
}

请注意我的数据不是0xffffffff,照样被写成了全0.

使用特权

评论回复
33
Windmill_CN| | 2012-2-24 13:19 | 只看该作者
用自己的编译器,让别人去**吧!

使用特权

评论回复
34
香水城| | 2012-2-24 13:38 | 只看该作者
香斑竹“回击”的**弹火力也很猛啊,让我“应接不暇”。我喜欢这种火力,让**弹来得更猛烈些吧……:P

关于问题1:请留意我27贴,我再复制一下:
//--------------------------------------------------------
// ...
程序匠人 发表于 2012-2-24 12:36


不好意思,没有仔细注意内容。

这个问题我还无法解释,能打开.map文件看看,你的R_tab[]和CNT_v1()分别在什么位置吗? 如果怀疑是写保护的问题,你可以看看选项字节区的设置。

还有一种可能是:因为你是通过仿真器操作的,会不会是仿真器作了什么限制?这只是猜想而已。你可以独立运行一下看看。

又想到一个可能,你的R_tab[],实际被分配到RAM区,这肯定是可以被更改的,所以还是要看.map文件。

使用特权

评论回复
35
程序匠人|  楼主 | 2012-2-24 16:11 | 只看该作者
进展汇报:
问题2:已经解决。欧耶!
问题3:和问题2本质一样,所以也可以认为已经解决了。欧耶!
问题1:原本是作为问题2得不到解决时的预备方案。既然问题2已经解决,问题1就不再是问题了。欧耶!
问题5:原本是为了配合问题1的,既然问题1不再是问题,那么问题5就也不是问题了。欧耶!
问题4:如果你还没有被我前面几句话的逻辑关系绕迷糊,那么现在的问题就是要去解决问题4啦。欧耶!

使用特权

评论回复
36
香水城| | 2012-2-24 18:02 | 只看该作者
刚刚问了一下同事,有一个方法,估计不能完全满足匠人的需要,但确是在RAM中运行一个函数的方法。

在某个需要在RAM中运行的函数前,使用__ramfunc前缀,IAR的启动文件在main函数运行之前,自动把这个函数拷贝到RAM中,程序的其他部分可以直接用函数名调用。详细方案最好看看手册。

但这个方法好像不可以把2个以上的函数放到同一个RAM区运行,而且要擦除这个函数也需要使用问题5的方法,找到它的地址再消灭之。

使用特权

评论回复
37
dianzi56| | 2012-2-24 19:13 | 只看该作者
不错

使用特权

评论回复
38
nongfuxu| | 2012-2-24 19:13 | 只看该作者
路过围观!
在深挖洞广积粮, IAR+STM32,二者都是一流的好东西,互相绝配.

使用特权

评论回复
39
caiwenbin| | 2012-2-24 19:28 | 只看该作者
搬个板凳,坐着受教

使用特权

评论回复
40
程序匠人|  楼主 | 2012-2-24 20:12 | 只看该作者
刚刚问了一下同事,有一个方法,估计不能完全满足匠人的需要,但确是在RAM中运行一个函数的方法。

在某个需要在RAM中运行的函数前,使用__ramfunc前缀,IAR的启动文件在main函数运行之前,自动把这个函数拷贝到RAM ...
香水城 发表于 2012-2-24 18:02


先谢谢香斑竹提供的思路。

关于 __ramfunc ,我还没有仔细研究。不过,我所担心的是,它所加载的函数的原型是在FLASH中存放的,可能不受控。

我说的不受控,是指,我无法为这个函数加密。那么,对于“有心人”来说,岂不春光大泄了去?

我最最希望的就是,我可以自己往RAM中指定的地址写数据,然后让这些数据合成代码,然后调用执行,然后销毁。因为如果这样,我可以尽量加密、伪装函数的原型。

使用特权

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

本版积分规则