搜索
bottom↓
回复: 9

资料分享:MQX中的函数从Flash中拷贝到RAM中的一种方法

[复制链接]

出0入0汤圆

发表于 2014-5-15 10:14:50 | 显示全部楼层 |阅读模式
这几天研究MQX的Flashx的驱动,在里面发现了一种函数拷贝的方法,以前没这么用过,觉得很有意思,发出来与大家分享,闲话少说,正题开始!

在Flash操作的时候,有需要在RAM中运行等待指令,在MQX中函数定义如下:

  1. /*FUNCTION*-------------------------------------------------------------------
  2. *
  3. * Function Name    : ftfl_ram_function
  4. * Returned Value   : void
  5. * Comments         :
  6. *   Code required to run in SRAM to perform flash commands.
  7. *   All else can be run in flash.
  8. *   Parameter is an address of flash status register.
  9. *
  10. *END*-----------------------------------------------------------------------*/
  11. static void ftfl_ram_function
  12. (
  13.     /* [IN] Flash info structure */
  14.     volatile uint8_t *ftfl_fstat_ptr
  15. )
  16. {
  17.     /* start flash write */
  18.     *ftfl_fstat_ptr |= FTFL_FSTAT_CCIF_MASK;

  19.     /* wait until execution complete */
  20.     while (0 == ((*ftfl_fstat_ptr) & FTFL_FSTAT_CCIF_MASK))
  21.     { /* void */ }
  22. }

  23. static void ftfl_ram_function_end(void)
  24. {}
复制代码


这么定义的函数,他保存肯定是在Flash中,怎么样能把它搬到RAM中呢?我们看看他的运输函数:
  1. /*FUNCTION*-------------------------------------------------------------------
  2. *
  3. * Function Name    : ftfl_init_ram_function
  4. * Returned Value   : pointer to allocated RAM function
  5. * Comments         :
  6. *   Allocate and copy flash RAM function.
  7. *
  8. *END*-----------------------------------------------------------------------*/
  9. char *ftfl_init_ram_function
  10. (
  11.     char *function_start,
  12.     char *function_end
  13. )
  14. {
  15.     char *ram_code_ptr;
  16.     _mem_size ftfl_ram_function_start;

  17.     /* remove thumb2 flag from the address and align to word size */
  18.     ftfl_ram_function_start = (_mem_size)function_start & ~3;

  19.     /* allocate space to run flash command out of RAM */
  20.     ram_code_ptr = _mem_alloc_align((char *)function_end - (char *)ftfl_ram_function_start, 4);

  21. #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
  22.     if (ram_code_ptr == NULL)
  23.     {
  24.         return NULL;
  25.     }
  26. #endif

  27.     /* aopy code to RAM buffer */
  28.     _mem_copy ((char *)ftfl_ram_function_start, ram_code_ptr, (char *)function_end - (char *)ftfl_ram_function_start);

  29.     /* adjust address with respect to the original alignment */
  30.     ram_code_ptr = (char *)((_mem_size)ram_code_ptr | ((_mem_size)function_start & 3));

  31.     return ram_code_ptr;
  32. }
复制代码


下面是开始搬运:
  1. flash_execute_code_ptr = ftfl_init_ram_function((char *)ftfl_ram_function, (char *)ftfl_ram_function_end);
复制代码


我分析了一下上面的代码,发现这是利用了编译器顺序排放函数的特点,首先先定义了一个ftfl_ram_function函数,然后在紧跟着它的后面再放一个名为ftfl_ram_function_end的空函数,这样在编译器编译完后,产生的BIN中ftfl_ram_function函数的代码范围就是从ftfl_ram_function地址开始,到ftfl_ram_function_end地址结束,这就给搬运时把起始位置与长度定义了,再要做的事情无非就是将这段代码拷贝到RAM中运行就可以了。

说起拷贝,我们看到ftfl_init_ram_function函数中一开始并没有直接拷贝,而是有下面这样的语句:
ftfl_ram_function_start = (_mem_size)function_start & ~3;
那么这个语句又是干什么的呢?呵呵,其实很简单,它是做对齐的,因为ARM的指令级是32位的,它产生的代码当然要按32位来存放才可以执行,而这条语句就是将低三位清零,得到一个对齐的地址,然后再操作!

其实说起来蛮简单的,但用起来很方便的,希望能给大家提提神!

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

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2014-5-15 10:43:57 | 显示全部楼层
楼主的经验分享都是经过实际验证的,非常好。

出0入0汤圆

发表于 2014-5-15 11:38:47 | 显示全部楼层
谢谢分亨哈,学习学习。

出0入0汤圆

 楼主| 发表于 2014-5-15 11:40:43 | 显示全部楼层
zndz410 发表于 2014-5-15 11:38
谢谢分亨哈,学习学习。

不用客气,呵呵,技术是公有的,产品是私有的,技术共享是应该的!

出100入101汤圆

发表于 2014-9-1 21:38:56 | 显示全部楼层
好文章,推荐!

出0入0汤圆

 楼主| 发表于 2014-9-1 21:42:30 | 显示全部楼层
本帖最后由 wangpengcheng 于 2014-9-1 21:45 编辑


我也觉得这个办法比较好玩,不用做数组,呵呵!

出0入0汤圆

发表于 2014-9-1 21:47:45 | 显示全部楼层
这个方法我也考虑过,没想到在这里找到了呢,很好!

出0入0汤圆

发表于 2014-9-1 21:48:05 | 显示全部楼层
学习啦,感谢楼主分享。

出0入0汤圆

 楼主| 发表于 2014-9-1 21:48:30 | 显示全部楼层
sunnyqd 发表于 2014-9-1 21:47
这个方法我也考虑过,没想到在这里找到了呢,很好!

MQX中的,呵呵,我也是现学现卖!

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-10-3 03:20

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

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