查看: 2859|回复: 2

[已解决] 飞思卡尔8位单片机FLASH处理函数是否必须放在RAM空间来执行

[复制链接]
  • TA的每日心情
    无聊
    2019-8-29 13:37
  • 签到天数: 6 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    18

    主题

    88

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    251
    最后登录
    2022-1-14
    发表于 2016-9-26 15:42:13 | 显示全部楼层 |阅读模式
    本帖最后由 jinandawei 于 2016-9-30 16:27 编辑

      这两天在做8位单片机DZ60的BOOTLOADER,因为之前做过S12单片机的BOOTLOADER,所以做的时候没有多大困难。开始做的时候,考虑到FLASH处理函数之前都是放到RAM区来执行,或者把函数复制到RAM里来执行。我之前认为这样做是为了防止FLASH处理函数本身被擦除,所以如果我处理BOOTLOADER的时候如果应用程序控制做好处理,只对应用程序区域进行sector的擦除和写处理,那么FLASH处理函数就无需在RAM里面来执行。但是这样做的后果就是无论仿真调试还是上电后让BOOTLOADER自动运行,FLASH处理函数都会出现莫名其妙的错误,比如返回的错误代码并非程序中错误代码,或者擦除sector后,读取相应地址的FLASH发现数据为非擦除数据(不是0xFF).....
      无奈之下,把FLASH处理函数再次放到RAM区来执行,结果没有问题了。

      我这里总结就是,FLASH处理,是不是单片机内部的处理机制,要求必须在RAM里来进行相应操作呢,目前看是这样的。但是我并没有在相应文档里找到相应说明。
      欢迎比较了解的朋友留言探讨,谢谢。

    FLASH处理函数举例(这是通过pragma 把此函数放到RAM区):


    1.     FRAM                     =  READ_ONLY    0x0C80 TO 0x107F;//1024
    2. .....
    3. PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */
    4.     DEFAULT_RAM                        /* non-zero page variables */
    5.                                         INTO  RAM;
    6.     FLASH_RAM                           INTO FRAM;
    复制代码

    1. #pragma CODE_SEG FLASH_RAM

    2. /******************************************************************************
    3. Function Name        :        Sector_Erase_Routine
    4. Parameters                :        *Addr
    5. Returns                          :        result
    6. Notes                            : Erases flash sector starting at 0xD000
    7. ******************************************************************************/
    8. byte Sector_Erase(byte *Addr)
    9. {
    10.   byte result=FLASH_OK;

    11.   if (FSTAT_FACCERR)        /* Check for access error */
    12.   {                        
    13.   FSTAT_FACCERR = 1;        /* Clear access error flag */
    14.   }
    15.   
    16.   while (!FSTAT_FCBEF);     /* Wait here if command buffer is full */
    17.   
    18.   *Addr = 0xFF;             /* Write to flash */
    19.   
    20.   FCMD = SECTOR_ERASE;      /* Write sector erase command */
    21.   
    22.   FSTAT_FCBEF = 1;          /* Write 1 to FCBEF to launch the command */
    23.   
    24.   asm
    25.   {                         /* Wait 4 cycles */
    26.   nop
    27.   nop
    28.   nop
    29.   nop
    30.   }
    31.   
    32.   if (FSTAT_FACCERR)        /* Check for access error */
    33.   {                        
    34.   FSTAT_FACCERR = 1;        /* Clear access error flag */
    35.   result |= FLASH_FACCERR;  /* Set error code */
    36.   }

    37.   if (FSTAT_FPVIOL)
    38.   {                         /* Check for protection violation */
    39.   FSTAT_FPVIOL = 1;         /* Clear protection violation flag */
    40.   result |= FLASH_FPVIOL;   /* Set error code */
    41.   }
    42.   
    43.   while (!FSTAT_FCCF);      /* Wait for command to complete  */

    44.   return result;
    45. }
    复制代码
    或者是通过把FLASH处理函数复制到数组中(也就是RAM里)来执行:
    1. ////////////////////////////data define////////////////
    2. uchar proonram[70] ={0,};
    3. word  pro_words = 0;
    4. uchar pro_ppage = 0;
    5. word  pro_loc_adress = 0;


    6. //#pragma CODE_SEG RAM
    7. void run_cmdcopy(uchar(*s)(void),uchar cnt)
    8. {
    9.   uchar *ss;
    10.   uchar *pp;
    11.   pp = proonram;
    12.   ss = (uchar*)((dword)s >> 8);
    13.   for(;cnt>0;cnt--)
    14.   {
    15.     *pp = *ss;
    16.     pp++;
    17.     ss++;
    18.   }
    19. }


    20. uchar flash_cmd(void)
    21. {
    22.   uchar ppage;
    23.   ppage = PPAGE;
    24.   PPAGE = pro_ppage;
    25.   *(word*)(pro_loc_adress) = pro_words;
    26.         FCMD=0x20;
    27.         //Launch CMD

    28.         FSTAT_CBEIF = 1;
    29.         asm
    30.         {
    31.             nop
    32.             nop
    33.             nop
    34.         };  
    35.         while(!FSTAT_CCIF) //wait 4 cmd end
    36.         {
    37.                 if(FSTAT_PVIOL)//protection violation detected
    38.     {
    39.       PPAGE = ppage;
    40.       return 0;
    41.                 }
    42.         }
    43.         if(FSTAT_ACCERR)
    44.         {
    45.     PPAGE = ppage;
    46.     return 0;
    47.         }
    48.         PPAGE = ppage;
    49.         return 1;   
    50. }

    51. //功能函数如果正确执行,则返回1,执行不成功返回0
    52. uchar CFM_mass_erase (byte byPpage)
    53. {
    54.   uchar(*runonstack)(void);
    55.   pro_words = 0x4567;            //赋值
    56. //////block0
    57.   pro_ppage = byPpage;//0xe0;              //页地址
    58.   pro_loc_adress = 0x8000;       //16位逻辑地址  

    59.   run_cmdcopy(flash_cmd,70);    //将擦除程序搬到RAM中
    60.   proonram[17] = MASS_ERASE;           //命令字
    61.   runonstack = (uchar(*)(void))((dword)proonram << 8);
    62.         return(runonstack());                   //执行命令
    63. }
    复制代码


    我知道答案 目前已有2人回答
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2019-8-29 13:37
  • 签到天数: 6 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    18

    主题

    88

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    251
    最后登录
    2022-1-14
     楼主| 发表于 2016-9-26 15:57:03 | 显示全部楼层
    好朋友告诉我原因是这样的:

    原因是飞思卡尔执行擦写时候flash电压不稳,容易丢失数据
    必须拷贝到ram
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2019-8-29 13:37
  • 签到天数: 6 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    18

    主题

    88

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    251
    最后登录
    2022-1-14
     楼主| 发表于 2016-9-30 16:23:04 | 显示全部楼层
    很多技术手册上也明说必须把FLASH处理函数放到RAM中处理才行
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-18 10:03 , Processed in 0.086271 second(s), 23 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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