搜索
bottom↓
回复: 9

开源PLC学习笔记06(再从51开始 IAP)——2013_11_11

[复制链接]

出0入0汤圆

发表于 2013-11-11 18:18:10 | 显示全部楼层 |阅读模式
在笔记05中遇到环形队列的狙击,还好网上资料丰富,完成了初步理解。

在FX1NProcessing函数中,调用了和IAP相关的函数,因为不影响理解,所以直接跳过了IAP的细节。现在要开始理解这些细节。什么是IAP?In Application Programming 是指在应用编程,单片机程序自己可以往程序存储器里写数据或修改程序!http://zhidao.baidu.com/link?url=Ob1__CoHYLCZZ1wd0PlwuxeaMSiDHMZiGbt3mdBu-BeF885lX4193TJw18RYiDhFZwZmJAAyxn_QVPamxxUZE_

51 IAP资料比较少,因为大多数需要IAP的设计都不会选51。

IAP编程和所选的MCU密切相关,不同MCU的IAP编程代码会不相同,不过原理和步骤大概类似。因为开源PLC选用的是MPC82g516,所以就以它的手册为辅助工具。点击此处下载 ourdev_428676.pdf(文件大小:1.56M) (原文件名:MPC82G516A  8位微处理器中文用户手册(第三版).pdf)
看一下结构


看了结构图,继续采用边看代码边理解功能方法。
*******************************
好在IAP.c中函数比较少,先捏软柿子,
// 函数名称: IAPFlashErasureMode
//
// 功能描述:  页面擦除模式
//
// 输 入:  unsigned int pageaddr
//         
// 输 出:  void
void IAPFlashErasureMode(unsigned int pageaddr)
{
    ISPCR=0x83;            // ISPCR.7=1,启用ISP
                        // ISPCR[2:0]=011, 假设MPC82系列运行在11.0592M
    IFMT=0x03;            // 选择页擦除模式
    IFADRH=pageaddr>>8;    // 这个页面必须在IAP存储区
    IFADRL=pageaddr;
    SCMD=0x46;            // 触发的ISP处理
    SCMD=0xb9;            // MCU将会停止运行.直到处理完成
}
我第一次看到上面的代码,不知所措,因为有许多和IAP相关的寄存器操作
一一看下,

ISPCR=0x83;            // ISPCR.7=1,启用ISP
振荡器频率6~12MHz,



    IFMT=0x03;            // 选择页擦除模式


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-11 18:39:29 | 显示全部楼层
本帖最后由 oldbeginner 于 2013-11-12 09:51 编辑



        IFADRH=pageaddr>>8;        // 这个页面必须在IAP存储区
        IFADRL=pageaddr;
pageaddr是个形参,unsigned int pageaddr,因为IFADRH和IFADRL是8位,所以用16位的赋值时,pageaddr向右移8位赋值给IFADRH是高8位。


        SCMD=0x46;                        // 触发的ISP处理
        SCMD=0xb9;                        // MCU将会停止运行.直到处理完成
根据手册也很好理解。
和手册上例子一样。


*********************************
// 函数名称: IAPFlashProgrem
//
// 功能描述:  单字节写入模式(无"检查是否写入成功")
//
// 输 入:  unsigned int codeaddr,unsigned char ucdata
//         
// 输 出:  void
void IAPFlashProgrem(unsigned int codeaddr,unsigned char ucdata)
{
    ISPCR=0x83;            // ISPCR.7=1,启用ISP
                        // ISPCR[2:0]=011, 假设MPC82系列运行在11.0592M
    IFMT=0x02;            // 进入编程模式
    IFADRH=codeaddr>>8;    // 这个字节必须在IAP存储区
    IFADRL=codeaddr;
    IFD=ucdata;            // 填写待编程的数据
    SCMD=0x46;            // 触发的ISP处理
    SCMD=0xb9;            // MCU将会停止运行.直到处理完成
}
是手册上的例子。


******************************************
//=======================================
// 函数名称: IAPFlashReadMode
//
// 功能描述:  单字节读取模式
//
// 输 入:  unsigned int codeaddr
//         
// 输 出:  unsigned char
unsigned char IAPFlashReadMode(unsigned int codeaddr)    // 读模式
{
    ISPCR=0x83;            // ISPCR.7=1,启用ISP
                        // ISPCR[2:0]=011, 假设MPC82系列运行在11.0592M
    IFMT=0x01;            // 进入读模式
    IFADRH=codeaddr>>8;    // 这个字节必须在IAP存储区
    IFADRL=codeaddr;
    SCMD=0x46;            // 触发的ISP处理
    SCMD=0xb9;            // MCU将会停止运行.直到处理完成    // 触发IAP
    return IFD;            // 读出的数据
}
也和手册一致。



// 函数名称: IAPFlashProgremMode
//
// 功能描述:  单字节写入模式(含有"检查是否写入成功")
//
// 输 入:  unsigned int codeaddr,unsigned char ucdata
//         
// 输 出:  void
IAPFlashProgremMode是个比较繁琐的函数,要逐步分析,

1、首先,void IAPFlashProgremMode(unsigned int codeaddr,unsigned char ucdata)        // 编程模式
   codeaddr是地址,ucdata是待编程的数据。

2、        unsigned char checkdata=0;
               checkdata=IAPFlashReadMode(codeaddr);
        把所写的数据赋值给checkdata,因为ucdata是待编程数据,所以两者应该相等。(具体原理还不清楚)

3、while(checkdata!=ucdata)
     {
        纠正措施;
      }
     如果不相等,如何解决。暂时跳过。

**********************************

要返回FX1NProcessing函数,去了解当时略过的几个IAP函数。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-12 09:42:52 | 显示全部楼层
本帖最后由 oldbeginner 于 2013-11-12 11:39 编辑
oldbeginner 发表于 2013-11-11 18:39
IFADRH=pageaddr>>8;        // 这个页面必须在IAP存储区
        IFADRL=pageaddr;
pageaddr是 ...

在IAP中存储非易失性数据,
//    IAP 空间分配如下:(31K)                                         ----ASCII转HEX后存储.
//        1.IAP起始页 0x8000    ~    0xbfff                       存储PLC程序 -- 对应PLC 的0x8000~0xbfff 地址共8000步程序空间
//        2.IAP最后一页0 地址                                         存储    PLC类型标识核实标志    共 1 个字节
//        3.IAP最后一页1    ~    PLCTypeArrayLenMAX        存储    PLC类型标识            共 PLCTypeArrayLen 个字节 PLCTypeArrayLen
//        4.IAP倒数第二页                                               缓存空间    不许被其他数据占用!
//        5.其他                                                             保留



为什么这样分布还不是很清楚,先看代码,看是否能从中理解空间分布。

// 函数名称: WriteFlash
//FX1N.c
// 功能描述:  HEX 转 ASCII
//
// 输 入:  unsigned int WriteAddr,unsigned char *Buf,unsigned int WriteLen
//         
// 输 出:  void
void WriteFlash(unsigned int WriteAddr,unsigned char *Buf,unsigned int WriteLen)
{
    unsigned int i;
    unsigned char wrdata=0;
    for(i=0;i<WriteLen*2;i+=2)    //    由原来的每页写512字节,改为每页写256个字节.存储地址不连续; 由原来存储ASCII码格式,改为存储HEX格式.
    {
        wrdata=asctohex((unsigned char *)(Buf+i));
        IAPFlashProgremMode(WriteAddr++,wrdata);
    }
}

这里调用了(含有"检查是否写入成功")单字节写入模式,只看代码也比较难理解,画个图看看,


注释中:由原来的每页写512字节,改为每页写256个字节。感觉有问题,因为WriteAddr++,所以还是512个字节,而且还是连续的,反而被存储的内容不连续了。
如果改成i++,Writeaddr+=2,则好像符合1、由原来的每页写512字节,改为每页写256个字节。2、存储地址不连续。
感觉这里源程序的注释和代码不一致。

至于为何要改成256个字节,应该和页面缓冲区有关(由RAM决定),可以猜测MPC82G516的RAM是256字节。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-12 12:59:37 | 显示全部楼层
oldbeginner 发表于 2013-11-12 09:42
在IAP中存储非易失性数据,
//    IAP 空间分配如下:(31K)                                         ---- ...

// 函数名称: ErasurePLC
//
// 功能描述:  PLC擦除IAP空间
//
// 输 入:  unsigned char allorcode
//         
// 输 出:  void
这个函数的代码有点多,逐次了解,
********************************************

void ErasurePLC(unsigned char allorcode)
    unsigned int i;
    unsigned char ucdata=0;
*****************************************************************

1、全部擦除
    if(allorcode==ErasureALL)
    {
        for(i=0;i<MCUIAPFLASHSIZE;i+=512)            //    全部擦除    初始PLC程序为空
        {
            IAPFlashErasureMode(PLCIAPCODEAddr+i);
        }
    }

找到FX1N.c中的定义
#define    ErasureALL        0
#define ErasureCODE        1

#define MCUFLASHSIZE        64*1024                                //    64K
#define MCUIAPFLASHSIZE        31*1024                                //    31K
#define MCUISPFLASHSIZE        1*1024                                //    1K

而注释是
//    默认当前MPC82G516A的设置为
//    1K  ISP Code
//    31K    IAP Code
//    32K Flash Code
注释应该改为64K Flash(其中包括1K ISP和 31K IAP)

首先,查看#define MCUIAPFLASHSIZE        31*1024                 //    31K
可知 IAP code容量为31K。

然后,#define PLCIAPCODEAddr        (MCUFLASHSIZE-MCUIAPFLASHSIZE-MCUISPFLASHSIZE)
根据字面意思就是,PLC IAP地址为,64*1024 - 31*1024 - 1*1024 = 32 * 1024 =64 * 512
地址的格式没见到过,是不是相对地址,先继续。

调用            IAPFlashErasureMode(PLCIAPCODEAddr+i);  来执行擦除。
又由于一个循环  for(i=0;i<62 * 512 ;i+=512)
                                  IAPFlashErasureMode(64 * 512 + i);
从第64页开始,一共擦除62页。最后2页没有擦除。
*********************************************************

2、else if(allorcode==ErasureCODE),只擦除程序

3、擦除IAP缓存备份空间
  IAPFlashErasureMode(PLCTempAddr);
查看 #define PLCTempAddr        (MCUFLASHSIZE-MCUISPFLASHSIZE-1024)    //    IAP倒数第二页地址
PLCTempAddr= 64 * 1024 - 1 * 1024 - 1024 = 62 * 1024 = 124 * 512,IAP倒数第二页是第124页。

4、备份PLC 0x8000~0x805c 地址的数据,0x8000 =40 * 512  第40页上的数据
           for(i=0;i<0x5c;i++)                            //    备份PLC 0x8000~0x805c 地址的数据
        {
            ucdata=IAPFlashReadMode(i+0x8000);
            IAPFlashProgremMode(i+PLCTempAddr,ucdata);
        }
0x5c小于512字节,所以IAP倒数第二页可以放下。


5、擦除PLC程序空间
        for(i=PLCIAPCODEAddr;i<PLCTempAddr;i+=512)    //    擦除PLC程序空间
        {
            IAPFlashErasureMode(i);
        }

6、还原PLC 0x8000~0x805c 地址的数据
        for(i=0;i<0x5c;i++)                            //    还原PLC 0x8000~0x805c 地址的数据
        {
            ucdata=IAPFlashReadMode(i+PLCTempAddr);
            IAPFlashProgremMode(i+0x8000,ucdata);
        }
**************************************
上述IAP更新步骤遵循了手册上说明。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-12 14:45:48 | 显示全部楼层
oldbeginner 发表于 2013-11-12 12:59
// 函数名称: ErasurePLC
//
// 功能描述:  PLC擦除IAP空间

Read code中涉及IAP的代码

Readdat=IAPFlashReadMode(ReadAddr+i-1);    //    读FlashData
其中,ReadAddr是通过接收到的报文获得的,详细理解在笔记04中。这里复习一下,

*******************************************
                    //    计算得到读取地址:
                    for(i=4;i<8;i++)
                          Buffer=ascto0F(UartReceiveBuffer);

                    ReadAddr =Buffer[4]<<12;
                    ReadAddr+=Buffer[5]<<8;
                    ReadAddr+=Buffer[6]<<4;
                    ReadAddr+=Buffer[7];
*********************************************
把i=1带入,看看结果
Readdat=IAPFlashReadMode(ReadAddr+i-1);

即Readdat=IAPFlashReadMode(ReadAddr);
然后调用IAP函数
    IFADRH=ReadAddr>>8;    // 这个字节必须在IAP存储区
    IFADRL=ReadAddr;
然后
    Readdat=IFD;

IFD保存着对应地址的数值,赋值给Readdat。
************************************************
1、首先,WriteAddr是通过报文得到的
                    //    计算得到写入地址:
                    for(i=4;i<8;i++)Buffer=ascto0F(eBuffer);
                    WriteAddr =Buffer[4]<<12;
                    WriteAddr+=Buffer[5]<<8;
                    WriteAddr+=Buffer[6]<<4;
                    WriteAddr+=Buffer[7];

*************************************************
2、Write code中涉及IAP的代码
                    if(WriteAddr==0x8000)
                                     ErasurePLC(ErasureCODE);    //    擦除PLC程序区
                   刚理解过如何擦除程序区
***************************************************

3、WriteFlash(WriteAddr,(unsigned char *)Buffer+10),(unsigned char)WriteLen);    //    写 flash
                  
        Buffer+10,指向报文的指令,是是由上位机发送的。

存储格式及报文发送格式说明:http://www.amobbs.com/thread-3303497-1-1.html

存储格式为字型,低在先,高在后(如指令END,指令码为00 0F,存储为0F 00。指令LD  X002,指令码为24 02,存储为02 24)。
在报文发送时,以字为单位传送,低字节在先。在字节传送过程中,高位在先,低位在后,转换成 ASCII 码 后传送(即以存储格式传送)。
指令LD  X002,指令码为24 02,存储格式为02 24,转换成 ASCII 码传送为30 32 32 34

以 LD X002为例,则Buffer[10]='0' ,Buffer[11]='2',Buffer[12]='2',Buffer[13]='4',并且WriteLen=4。




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-12 16:28:59 | 显示全部楼层
本帖最后由 oldbeginner 于 2013-11-12 16:54 编辑
oldbeginner 发表于 2013-11-12 14:45
Read code中涉及IAP的代码

Readdat=IAPFlashReadMode(ReadAddr+i-1);    //    读FlashData




从上图中可以看出,FX1NProcessing是把三菱命令映射到相应Flash的核心。
从中也可看出,FX1NProcessing有两个关键功能,
1、接收电脑来的报文;
2、将报文写入Flash。

虽然main函数中也涉及到IAP功能,放在后面再理解。因为IAP的步骤是规定的,所以发挥空间不大。第1遍理解暂时到这里,因为芯片原因,后面还要移植,必定需要把IAP理解一清二楚。

下一步分析指令LD OUT SET RST是如何传递和实现功能的。
http://www.amobbs.com/thread-5558798-1-1.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-15 19:35:08 | 显示全部楼层
oldbeginner 发表于 2013-11-12 16:28
从上图中可以看出,FX1NProcessing是把三菱命令映射到相应Flash的核心。
从中也可看出,FX1NProcessing ...

IAP主要补充相关硬件知识,不同芯片操作过程不太一致。

*******************************************************
先搜一下简单区别,http://zhidao.baidu.com/question ... l=relate_question_1
ISP(In-system programmable)是在系统可编程:
指的是不需要把单片机从目标系统板上取下来就可以直接从PC往单片机里面烧录程序。

IAP(In-Application programmable)是在应用可编程:
指的是可以通过单片机自身的程序修改单片机该程序区的内容;

EEPROM功能是:
在程序区1中的程序可以修改程序区2中的内容;通常程序区2中的内容不可以执行,只能当数据使用,功能相当于EEPROM;

区别:
ISP:从PC机修改单片机程序区的内容(即烧录)
IAP:单片机自己修改自己程序区的内容
EEPROM:单片机程序区1中的程序可以修改程序区2中的内容
****************************************************************
http://www.ndiy.cn/archiver/tid-5836.html
ISP是指可以在板级上进行编程,也就是不用拆芯片下来,写的是整个程序,一般是通过ISP接口线来写。
IAP虽然同样也是在板级上进行编程,但是是自已对自已进行编程,在应用中进行编程,也即可以只是更改某一部分而不影响系统的其它部分,另外接口程序是自已写的,这样可以进行远程升级而不影响应用。
打个比喻吧:
1、ISP是把房子拆了再重造一间,那么在造好之前当然是不能住人的啦!
2、IAP是在造好的房子里边进行一些装修,当然人可以继续住啦!

*******************************************************
    通常在用户需要实现IAP功能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,第一个项目程序不执行正常的功能操作,而只是通过某种通信管道(如USB、USART)接收程序或数据,执行对第二部分代码的更新;第二个项目代码才是真正的功能代码。这两部分项目代码都同时烧录在User Flash中,当芯片上电后,首先是第一个项目代码开始运行,它作如下操作:
1)检查是否需要对第二部分代码进行更新
2)如果不需要更新则转到4)
3)执行更新操作
4)跳转到第二部分代码执行

    对于STM32来说,因为它的中断向量表位于程序存储器的最低地址区,为了使第一部分代码能够正确地响应中断,通常会安排第一部分代码处于Flash的开始区域,而第二部分代码紧随其后。
   在第二部分代码开始执行时,首先需要把CPU的中断向量表映像到自己的向量表,然后再执行其他的操作。
**********************************************************



出0入0汤圆

 楼主| 发表于 2013-11-15 20:11:40 | 显示全部楼层
本帖最后由 oldbeginner 于 2013-11-15 20:16 编辑
oldbeginner 发表于 2013-11-15 19:35
IAP主要补充相关硬件知识,不同芯片操作过程不太一致。

********************************************* ...

考虑到资料的丰富程度和通用性,STM32是用来理解IAP比较好的入门芯片,而不是51。
第四十八章 串口IAP实验
http://www.openedv.com/posts/list/11494.htm

STM32 IAP   设计实例 (一)
http://blog.csdn.net/qq236106303/article/details/9977191



出0入0汤圆

发表于 2017-4-20 13:30:47 | 显示全部楼层
谢谢楼主!学习了!

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-19 19:23

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

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