OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4671|回复: 10

关于msp430的iap哪个大神可以指导一下

[复制链接]

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
发表于 2018-7-19 16:20:27 | 显示全部楼层 |阅读模式
1金钱
关于msp430的iap升级功能哪个大神可以指导一下:1怎么分别修改boot和app的.xcl文件?2中断向量表是如何重定义的?

最佳答案

查看完整内容[请看2#楼]

1.首先 ,你先写个正常的IAP程序 ,假设FLASH 地址范围是4000-FFFF 不去改任何地址。 假设你Code占用FLASH 为 4000-6000 ,然后 先写你的IAP程序, 把数据保存到 B000,用工具读取FLASH 查看写 没问题 没问题 没问题。。。这是最基本的FLASH写,先吧这个做好(用 FET MSP 软件)。 2.然后,你写个正常的点灯程序测试没问题之后。 3.你用IAP程序 ,你把link文件里面吧4000改成B000(把相关的 数据都要去修改) ,意思是 代码 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

193

帖子

0

精华

高级会员

Rank: 4

积分
708
金钱
708
注册时间
2014-7-2
在线时间
137 小时
发表于 2018-7-19 16:20:28 | 显示全部楼层
本帖最后由 qiousanxi 于 2018-8-20 15:02 编辑

1.首先 ,你先写个正常的IAP程序 ,假设FLASH 地址范围是4000-FFFF 不去改任何地址。 假设你Code占用FLASH 为 4000-6000 ,然后 先写你的IAP程序, 把数据保存到 B000,用工具读取FLASH 查看写 没问题 没问题 没问题。。。这是最基本的FLASH写,先吧这个做好(用 FET MSP 软件)。
2.然后,你写个正常的点灯程序测试没问题之后。

3.你用IAP程序 ,你把link文件里面吧4000改成B000(把相关的 数据都要去修改) ,意思是  代码存放位置是B000-FFFF。 这个是IAP程序的存储地址。
你打开生成的txt 程序 文件开头就是  @B000 这个是 程序的启动地址 ,最下面 @FFE0 这个是默认的中断地址对应-Z(CODE)INTVEC=FFE0-FFFF(中断区)-Z(CODE)RESET=FFFE-FFFF(复位)
这样,你把 你的程序用IAP下载到4000的地址,在查看是否成功。   


4.把点灯程序 地址改为 4000-AFFF(相关的也要改,先不要用任何中断),
你打开生成的txt 程序 文件开头就是 @4000 这个是 程序的启动地址 ,最下面 @AFE0 这个是默认的中断地址对应-Z(CODE)INTVEC=AFE0-AFFF(中断区)-Z(CODE)RESET=AFFE-AFFF(复位)

5.用你修改过地址的IAP 程序  下载这个点灯程序。下载完成后 mov 一下 PC 指向 AFFE ,正常情况下
指针指向 AFFE 后复位 PC 会指向 4000地址去运行,

6.都好了之后可以用中断了。


1)简单的东西可以使用位置定义,IAP和APP定义变量 在同一个地址,然后在IAP里面执行中断,例如计数什么的,你通过指针就可以在APP里面获取。(最好流出一段RAM 做地址定位)
例如:
//-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,DATA16_HEAP+_DATA16_HEAP_SIZE=1100-38FF (正常的)
-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,DATA16_HEAP+_DATA16_HEAP_SIZE=1300-38FF(例如保留1100-1300用代码去访问,程序 不会再这里面分配数据)

2)复杂点的 用中断调转 比如 FFE0出的中断 进入中断了 你直接 br &0xAFE0  跳转到你的虚拟中断地址,在APP里面 写处理函数就行了。其他中断都是一样的操作,只要你地址不写错。
回复

使用道具 举报

17

主题

193

帖子

0

精华

高级会员

Rank: 4

积分
708
金钱
708
注册时间
2014-7-2
在线时间
137 小时
发表于 2018-8-17 19:29:57 来自手机 | 显示全部楼层
向量表在顶头0xFFFF
回复

使用道具 举报

17

主题

193

帖子

0

精华

高级会员

Rank: 4

积分
708
金钱
708
注册时间
2014-7-2
在线时间
137 小时
发表于 2018-8-17 19:31:07 来自手机 | 显示全部楼层
这是真实地址,你把链接文件改成假设 DFFF你再boot里面做中断跳转
回复

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
 楼主| 发表于 2018-8-20 08:17:26 | 显示全部楼层
qiousanxi 发表于 2018-8-17 19:31
这是真实地址,你把链接文件改成假设 DFFF你再boot里面做中断跳转

谢谢指导
回复

使用道具 举报

17

主题

193

帖子

0

精华

高级会员

Rank: 4

积分
708
金钱
708
注册时间
2014-7-2
在线时间
137 小时
发表于 2018-8-20 10:38:06 | 显示全部楼层
本帖最后由 qiousanxi 于 2018-8-20 10:40 编辑

这个是 IAP的
//-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=4000-FFDF
-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=F000-FFDF   


// -------------------------------------
// Code
//

//-Z(CODE)CSTART,ISR_CODE,CODE_ID=4000-FFDF
//-P(CODE)CODE=4000-FFDF
-Z(CODE)CSTART,ISR_CODE,CODE_ID=F000-FFDF            //数据 变量存储位置
-P(CODE)CODE=F000-FFDF                                           //代码 存储位置     


// -------------------------------------
// Interrupt vectors
//

-Z(CODE)INTVEC=FFE0-FFFF
-Z(CODE)RESET=FFFE-FFFF


这个是APP的
//-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=4000-FFDF
-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=4000-EFDF


// -------------------------------------
// Code
//

//-Z(CODE)CSTART,ISR_CODE,CODE_ID=4000-FFDF
//-P(CODE)CODE=4000-FFDF
-Z(CODE)CSTART,ISR_CODE,CODE_ID=4000-EFDF
-P(CODE)CODE=4000-EFDF

// -------------------------------------
// Interrupt vectors
//

-Z(CODE)INTVEC=EFE0-EFFF
-Z(CODE)RESET=EFFE-EFFF
回复

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
 楼主| 发表于 2018-8-20 11:18:26 | 显示全部楼层
qiousanxi 发表于 2018-8-20 10:38
这个是 IAP的
//-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=4000-FFDF
-Z(CONST)DATA16_C,DATA16_ID, ...

修改了link文件后,本身代码里面要添加什么东西吗?
回复

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
 楼主| 发表于 2018-8-20 11:22:44 | 显示全部楼层
[mw_shl_code=c,true]

#if __VER__ < 200
#pragma codeseg(UPDATECODE)    //在IAR2.0以下的程序定位函数
#endif


#include <msp430x14x.h>

#include "h\portini.h"

/*
warning:以下内容不能更改!!!!
*/
#define   Upadte_Mode_Usart         0x01
#define   Upadte_Mode_GPRS          0x02


#define   Upadte_USART0             0x10
#define   Upadte_USART1             0x11


#define   Upadte_XTL_4M             0x21
#define   Upadte_XTL_8M             0x22            


#define   Upadte_Port1       0x31
#define   Upadte_Port2       0x32
#define   Upadte_Port3       0x33
#define   Upadte_Port4       0x34
#define   Upadte_Port5       0x35
#define   Upadte_Port6       0x36

#define   Upadte_BIT0        BIT0
#define   Upadte_BIT1        BIT1
#define   Upadte_BIT2        BIT2
#define   Upadte_BIT3        BIT3
#define   Upadte_BIT4        BIT4
#define   Upadte_BIT5        BIT5
#define   Upadte_BIT6        BIT6
#define   Upadte_BIT7        BIT7

#define   Upadte_PortBaud_2400      0x90
#define   Upadte_PortBaud_4800      0x91
#define   Upadte_PortBaud_9600      0x92
#define   Upadte_PortBaud_19200     0x93
#define   Upadte_PortBaud_38400     0x94
#define   Upadte_PortBaud_57600     0x95
#define   Upadte_PortBaud_115200    0x96



#if __VER__ < 200
#include <update.h>
#else
#include "h\update.h"
#endif


#if   (Upadte_USARTx == Upadte_USART0)
  #define    Update_RXBUFx        RXBUF0
  #define    Update_TXBUFx        TXBUF0
  #define    Update_UCTLx         UCTL0
  #define    Update_UTCTLx        UTCTL0
  #define    Update_URCTLx        URCTL0
  #define    Update_UBR0x         UBR00
  #define    Update_UBR1x         UBR10
  #define    Update_UMCTLx        UMCTL0
  #define    Update_MEx           ME1
  #define    Update_UTXEx         UTXE0
  #define    Update_URXEx         URXE0
  #define    Update_IFGx          IFG1
  #define    Update_URXIFGx       URXIFG0
  #define    Update_Usart_PortIni    P3SEL|=(BIT4+BIT5); P3DIR|=BIT4; P3DIR&=~BIT5  
#elif (Upadte_USARTx == Upadte_USART1)
  #define    Update_RXBUFx        RXBUF1
  #define    Update_TXBUFx        TXBUF1
  #define    Update_UCTLx         UCTL1
  #define    Update_UTCTLx        UTCTL1
  #define    Update_URCTLx        URCTL1
  #define    Update_UBR0x         UBR01
  #define    Update_UBR1x         UBR11
  #define    Update_UMCTLx        UMCTL1
  #define    Update_MEx           ME2
  #define    Update_UTXEx         UTXE1
  #define    Update_URXEx         URXE1
  #define    Update_IFGx          IFG2
  #define    Update_URXIFGx       URXIFG1
  #define    Update_Usart_PortIni    P3SEL|=(BIT6+BIT7); P3DIR|=BIT6; P3DIR&=~BIT7  
#else
#error "Upadte_USARTx define error!"
#endif  



#if   (Upadte_CleDog_Portx == Upadte_Port1)
  #define    Upadte_CleDog_SEL    P1SEL
  #define    Upadte_CleDog_DIR    P1DIR
  #define    Upadte_CleDog_PxOUT  P1OUT
#elif (Upadte_CleDog_Portx == Upadte_Port2)
  #define    Upadte_CleDog_SEL    P2SEL
  #define    Upadte_CleDog_DIR    P2DIR
  #define    Upadte_CleDog_PxOUT  P2OUT
#elif (Upadte_CleDog_Portx == Upadte_Port3)
  #define    Upadte_CleDog_SEL    P3SEL
  #define    Upadte_CleDog_DIR    P3DIR
  #define    Upadte_CleDog_PxOUT  P3OUT
#elif (Upadte_CleDog_Portx == Upadte_Port4)
  #define    Upadte_CleDog_SEL    P4SEL
  #define    Upadte_CleDog_DIR    P4DIR
  #define    Upadte_CleDog_PxOUT  P4OUT
#elif (Upadte_CleDog_Portx == Upadte_Port5)
  #define    Upadte_CleDog_SEL    P5SEL
  #define    Upadte_CleDog_DIR    P5DIR
  #define    Upadte_CleDog_PxOUT  P5OUT
#elif (Upadte_CleDog_Portx == Upadte_Port6)
  #define    Upadte_CleDog_SEL    P6SEL
  #define    Upadte_CleDog_DIR    P6DIR
  #define    Upadte_CleDog_PxOUT  P6OUT
#else
#error "Upadte_CleDog_Portx define error!"
#endif



#if   (Upadte_485CS_Portx == Upadte_Port1)
  #define    Upadte_485CS_SEL    P1SEL
  #define    Upadte_485CS_DIR    P1DIR
  #define    Upadte_485CS_PxOUT  P1OUT
#elif (Upadte_485CS_Portx == Upadte_Port2)
  #define    Upadte_485CS_SEL    P2SEL
  #define    Upadte_485CS_DIR    P2DIR
  #define    Upadte_485CS_PxOUT  P2OUT
#elif (Upadte_485CS_Portx == Upadte_Port3)
  #define    Upadte_485CS_SEL    P3SEL
  #define    Upadte_485CS_DIR    P3DIR
  #define    Upadte_485CS_PxOUT  P3OUT
#elif (Upadte_485CS_Portx == Upadte_Port4)
  #define    Upadte_485CS_SEL    P4SEL
  #define    Upadte_485CS_DIR    P4DIR
  #define    Upadte_485CS_PxOUT  P4OUT
#elif (Upadte_485CS_Portx == Upadte_Port5)
  #define    Upadte_485CS_SEL    P5SEL
  #define    Upadte_485CS_DIR    P5DIR
  #define    Upadte_485CS_PxOUT  P5OUT
#elif (Upadte_485CS_Portx == Upadte_Port6)
  #define    Upadte_485CS_SEL    P6SEL
  #define    Upadte_485CS_DIR    P6DIR
  #define    Upadte_485CS_PxOUT  P6OUT
#else
#error "Upadte_485CS_Portx define error!"
#endif



#define    Update_485CS_high     Upadte_485CS_PxOUT |=Upadte_485CS_BITx
#define    Update_485CS_low      Upadte_485CS_PxOUT &=(~Upadte_485CS_BITx)


monitor void Port_Update(void);
monitor void Update_init_comm(void);
monitor void Update_Erase_Flash(unsigned short Flash_Start,unsigned char Times);
monitor void Update_Time_Control(unsigned char Timer);
monitor void Upadte_WriteYB(char *str,unsigned char strlen);
monitor void Update_Delay(char dd);
monitor void Update_Cle_Dog(void);





#if __VER__ < 200
monitor void RTU_Update_Usart(void)
#else
__monitor void RTU_Update_Usart(void)@"UPDATECODE"
#endif
{
  IE1=0;
  IE2=0;
//--------------
   P1SEL &=~BIT2;
   P1DIR |=BIT2;//输出
//---------------
  WDTCTL = WDTPW + WDTHOLD;             // Stop WDT
Update_Erase_Flash(0xFF00,1);//擦中断向量
FCTL1 = FWKEY + WRT;
FCTL3 = FWKEY;

//为防止更新过程中 传输终止,把初始PC改成 Port_Update()的入口
//这样当传输终止或者突然断电导致程序重新启动的 程序将从 Net_Update() 开始执行
*(int *)0xFFFE=0xFFD0;//此数据为Net_Update()的入口
//*(long *)0xFFD0=0x0A004031;//mov.w  #0A00,SP;
*(long *)0xFFD0=0x39004031;
//*(long *)0xFFD4=0x115A12B0;//CALL   Update_Upadte;
*(long *)0xFFD4=0x406E12B0;
while ((FCTL3 & BUSY) == BUSY);
FCTL3 = FWKEY + LOCK;
Port_Update();
}



/*
//////////////////////////串口更新说明//////////////////////////////
程序入口只有一个:输入"+LANDSLANDS"\"+LANDSTESTA"\"U"之后进入

一旦进入此程序则只有一个出口:当程序更新完成并校验通过!
要求更新过程中不能断电:当用户收到"115200!
Ready!"字样后一直到出现"Sucess!"字样期间断电则程序不能恢复!!!!
当程序传输过程中丢数了,即传输完成后没有出现"Sucess!"字样则需要等待约 1.5 分钟,出现 "Afresh!115200!
Ready!"后再发送文件!
当传输完成后显示 "Fail"字样则直接再次发送文件
如果更新一次成功,一般情况下,115200只需要 5S 时间
*/
#if __VER__ < 200
monitor void Port_Update(void)
#else
__monitor void Port_Update(void)@"UPDATECODE"
#endif
{unsigned char bt,i;
unsigned short crc,flag,flash,j,num;
char Str[7];
char Int_[32];

IE1=0;
IE2=0;
WDTCTL=WDTPW+WDTHOLD;

  /* IO脚初始化 喂狗脚 */
  Upadte_CleDog_SEL &= ~Upadte_CleDog_BITx;
  Upadte_CleDog_DIR |= Upadte_CleDog_BITx;
  
  /* 485 片选引脚初始化 */
  Upadte_485CS_SEL &= ~Upadte_485CS_BITx;
  Upadte_485CS_DIR |= Upadte_485CS_BITx;
  
  
  BCSCTL1 &= ~XTS;                       // ACLK = LFXT1 = low XTAL 32768
  BCSCTL2  = 0;  
  //init_port();
  //Open_4M();
  BCSCTL1 &= 0x7f;                       // xt2 on
  j=10;
  do
{
  j--;
  IFG1 &= ~OFIFG;                       // Clear OSCFault flag
  Update_Cle_Dog();
  for (i = 0xFF; i > 0; i--);           // Time for flag to set
}while((j!=0)&&((IFG1 & OFIFG) != 0));  // OSCFault flag still set?               
  //if (j==0)  WDTCTL=0;  //晶体失败
  BCSCTL2 |= SELM1+SELS;                // MCLK = SMCLK = XT2
  
  
  
Update_init_comm();
//发送 "Ready!"
Str[0]=0x0A;
Str[1]=82;
Str[2]=101;
Str[3]=97;
Str[4]=100;
Str[5]=121;
Str[6]=33;
Upadte_WriteYB(Str,7);
Update_Erase_Flash(0x4400,93);//0x4400-0xFE00

flag=0;
flash=0;
crc=0x0003;//防止接收2个数就跳出 while 循环

FCTL1 = FWKEY + WRT;
FCTL3 = FWKEY;

//接收数据 , 写到FLASH 里
/*
数据结构:
数据长度2个字节 + @2000~@FFDF若干字节 + @ffe0~@ffff中断向量32个字节 + crc校验两个字节
////////////////数据长度\\\\\\\\\\\\\\
*/
  Update_Time_Control(0x90); //??长时间收不到串口数据就重新启动,大约1分钟
      do
        {bt=Update_RXBUFx;
         //接收程序的长度
         switch(flag)
           {case 0:num=(bt<<8)&0xff00;break;
            case 1:num=num | bt;crc=num+32;break;//num长度是 @2000~@ffe0 之间字节个数 + 数据长度2
            default:if(flag<num)
                       {while ((FCTL3 & BUSY) == BUSY);
                        *(char*)(0x43FE+flag)=bt;//从0x4E00开始写入(定义的数据区)
                       }
                    else Int_[flash++]=bt;//中断向量
                    break;
           }
         flag++;
         Update_Time_Control(0x5);
        }while(flag<crc);//中断向量32字节  crc两个字节
  
  while ((FCTL3 & BUSY) == BUSY);
  FCTL3 = FWKEY + LOCK;
  
  //CRC校验是否相等,相等了退出,否则重新更新
  flash=Update_RXBUFx;
  Update_Time_Control(0x5);
  bt=Update_RXBUFx;
  flash =((flash<<8)&0xFF00)|(bt&0x00FF);
  
  crc=0xffff;     //预置16位寄存器为十六进制FFFF(即全为1)。称此寄存器为CRC寄存器
       //计算CRC校验
  for(j=0;j<num;j++)
     {  Update_Cle_Dog();
        //bt=*(char*)(0x1FFE+j);
                bt=*(char*)(0x43FE+j);
        if(j==0) bt=(num>>8)&0x00ff;
        if(j==1) bt=num&0x00ff;
         crc^= bt;  //把第一个8位数据与16位CRC寄存器的低位相异或,把结果放于CRC寄存器
         for(i=0;i<8;i++)
          {
           flag=crc & 0x0001;  //检查最低位
           crc>>=1;        // 把寄存器的内容右移一位(朝低位),用0填补最高位
           if(flag==0x0001)  crc ^= 0xa001; //*如果最低位为1:CRC寄存器与多项式A001(1010 00000000 0001)进行异或
          }
      }
   for(j=0;j<32;j++)
      {bt=Int_[j];
       crc^= bt;  //把第一个8位数据与16位CRC寄存器的低位相异或,把结果放于CRC寄存器
         for(i=0;i<8;i++)
          {
           flag=crc & 0x0001;  //检查最低位
           crc>>=1;        // 把寄存器的内容右移一位(朝低位),用0填补最高位
           if(flag==0x0001)  crc ^= 0xa001; //S如果最低位为1:CRC寄存器与多项式A001(1010 00000000 0001)进行异或
          }
      }   
      
  if(crc==flash)
   {Str[0]=83;
    Str[1]=117;
    Str[2]=99;
    Str[3]=101;
    Str[4]=115;
    Str[5]=115;
    Str[6]=33;
    Upadte_WriteYB(Str,7);
    Update_Erase_Flash(0xFFE0,1);//一旦传输结束则将中断向量的32字节恢复
    FCTL1 = FWKEY + WRT;
    FCTL3 = FWKEY;
    flash=0xFFE0;
    for(i=0;i<32;i++)
    {       
                Update_Cle_Dog();
            while ((FCTL3 & BUSY) == BUSY);
            *(char*)(flash++)=Int_;
     }
    while ((FCTL3 & BUSY) == BUSY);
    FCTL3 = FWKEY + LOCK;
    Update_Delay(10);
   }
  else
   {
    Str[0]=70;
    Str[1]=97;
    Str[2]=105;
    Str[3]=108;
    Str[4]=33;
    Str[5]=0x0A;
    Str[6]=0x0A;
    Upadte_WriteYB(Str,7);
    Update_Delay(10);
   }
///////////////////////////////////////////////////////////////////////////////////////////////////
/////////////看门狗重新启动////////////////
    WDTCTL &= 0xA57E;//~WDTPW  ~WDTHOLD  OPEN WDT TO RESTART
        while(1);
}







//comport 1 init:
#if __VER__ < 200
monitor void Update_init_comm(void)
#else
__monitor void Update_init_comm(void)@"UPDATECODE"
#endif
{
  
#if   (Upadte_XTL == Upadte_XTL_4M)
  #if   (Upadte_PortBaud == Upadte_PortBaud_9600)//波特率设置
    Update_UBR0x = 0xA0;
    Update_UBR1x = 0x01;
    Update_UMCTLx = 0xC0;
  #elif (Upadte_PortBaud == Upadte_PortBaud_19200)
        Update_UBR0x = 0xd0;        
    Update_UBR1x = 0x0;                       
    Update_UMCTLx = 0x3;  
  #elif (Upadte_PortBaud == Upadte_PortBaud_115200)
    Update_UBR0x = 0x22;
    Update_UBR1x = 0x00;
    Update_UMCTLx = 0xED;
  #else
    #error "Upadte_PortBaud define error!"
  #endif
#elif (Upadte_XTL == Upadte_XTL_8M)
  #if   (Upadte_PortBaud == Upadte_PortBaud_9600)//波特率设置
    Update_UBR0x = 0x41;
    Update_UBR1x = 0x03;
    Update_UMCTLx = 0x00;
  #elif (Upadte_PortBaud == Upadte_PortBaud_115200)
    Update_UBR0x = 0x45;
    Update_UBR1x = 0x00;
    Update_UMCTLx = 0x4A;
  #else
    #error "Upadte_PortBaud define error!"
  #endif
#else
  #error "Upadte_XTL define error!"
#endif
  Update_UCTLx = CHAR+SWRST ;
  Update_UTCTLx = SSEL0+SSEL1;
  Update_URCTLx = 0x00;
  Update_MEx = Update_UTXEx+Update_URXEx;
  Update_UCTLx &=~ SWRST;
  Update_Usart_PortIni;
}




// 1100~19FF 存放升级程序
#if __VER__ < 200
monitor void Update_Erase_Flash(unsigned short Flash_Start,unsigned char Times)
#else
__monitor void Update_Erase_Flash(unsigned short Flash_Start,unsigned char Times)@"UPDATECODE"
#endif
{unsigned short i;
unsigned char bt;
   i=Flash_Start;
   FCTL2 = FWKEY + FSSEL0 +FN0; //分频
   FCTL3 = FWKEY;
   for(bt=0;bt<Times;bt++)
    {Update_Cle_Dog();
     FCTL1 = FWKEY + ERASE;            //擦除一段,因为多段擦除会把 UPDATECODE 段也一起擦除
     while ( (FCTL3 & BUSY) == BUSY);  //等待FLASH空闲*********************************
     *((char*)i)=0;                    //段内地址任意写,启动擦除
     i+=0x200;
    }
  while ((FCTL3 & BUSY) == BUSY);
  FCTL3 = FWKEY + LOCK;
}




#if __VER__ < 200
monitor void Update_Time_Control(unsigned char Timer)
#else
__monitor void Update_Time_Control(unsigned char Timer)@"UPDATECODE"
#endif
{    unsigned int Time_tt;
     unsigned char Str[7];
     while(Timer--)
       {Time_tt=0xFFFF;
        while(Time_tt!=0)
           {Update_Cle_Dog();
            if((Update_IFGx&Update_URXIFGx)==0x00) Time_tt--;
              else  {Update_IFGx&=~Update_URXIFGx;return;}
           }
       }
   //规定时间内没有数据收到,则要求用户重新发送,终端重新就绪
   //Afresh!
    Str[0]=65;
    Str[1]=102;
    Str[2]=114;
    Str[3]=101;
    Str[4]=115;
    Str[5]=104;
    Str[6]=33;
    Upadte_WriteYB(Str,7);
    Update_Delay(10);
        WDTCTL &= 0xA57E;//~WDTPW  ~WDTHOLD  OPEN WDT TO RESTART
        while(1);
}





#if __VER__ < 200
monitor void Upadte_WriteYB(char *str,unsigned char strlen)
#else
__monitor void Upadte_WriteYB(char *str,unsigned char strlen)@"UPDATECODE"
#endif
{
unsigned char i;

  Update_485CS_high;
  for(i=0;i<strlen;i++){
    Update_TXBUFx=str;
      while ((Update_UTCTLx&0x01)==0);
    }
  Update_485CS_low;
}




#if __VER__ < 200
monitor void Update_Delay(char dd)
#else
__monitor void Update_Delay(char dd)@"UPDATECODE"
#endif
{int j;
char i;
for(i=0;i<dd;i++)
  {
   for(j=0;j<0xFFFF;j++);
   Update_Cle_Dog();
  }
}




#if __VER__ < 200
monitor void Update_Cle_Dog(void)
#else
__monitor void Update_Cle_Dog(void)@"UPDATECODE"
#endif
{ Upadte_CleDog_PxOUT|=Upadte_CleDog_BITx; //车机的喂狗IO是6.3   //rtu  6.0
  _NOP();  
  Upadte_CleDog_PxOUT&=~Upadte_CleDog_BITx;
}


[/mw_shl_code]
回复

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
 楼主| 发表于 2018-8-20 11:23:59 | 显示全部楼层
本帖最后由 ssssssssssss 于 2018-8-20 11:32 编辑

7楼里面关于iap的代码是哪些呢?函数前面monitor 和__monitor 是把函数放特定地址的意思吗?







#if __VER__ < 200

monitor void RTU_Update_Usart(void)
#else

__monitor void RTU_Update_Usart(void)@"UPDATECODE"

#endif



回复

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
 楼主| 发表于 2018-8-20 11:34:41 | 显示全部楼层
qiousanxi 发表于 2018-8-20 10:38
这个是 IAP的
//-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=4000-FFDF
-Z(CONST)DATA16_C,DATA16_ID, ...




[mw_shl_code=c,true] //为防止更新过程中 传输终止,把初始PC改成 Port_Update()的入口
//这样当传输终止或者突然断电导致程序重新启动的 程序将从 Net_Update() 开始执行
*(int *)0xFFFE=0xFFD0;//此数据为Net_Update()的入口
//*(long *)0xFFD0=0x0A004031;//mov.w  #0A00,SP;
*(long *)0xFFD0=0x39004031;
//*(long *)0xFFD4=0x115A12B0;//CALL   Update_Upadte;
*(long *)0xFFD4=0x406E12B0;[/mw_shl_code]

另一个帖子中这三句话比较难理解,下面是作者说的话:
这个不难,思路就是把你的更新程序强制编译到固定地址空间,主程序判断条件进入更新程序后,更新程序擦除主程序区,然后外部接收要更新的代码往里写就行了,当然,更新程序所在空间是不能擦除的。
如果考虑更新过程中更新失败的情况,那你就要了解430的启动过程,在进入更新程序的时候,先将要复位要执行的指令写到中断向量区,如果更新不成功,那么每次上电让它强制进你的更新程序,知道更新完毕。
你需要了解的有启动过程、中断向量等。给你三句关键程序,结合启动过程好好研究研究吧
*(int *)0xFFFE=0xFFD0;//430复位去0XFFFE取指令,这地址值是多少就跳到多少地址执行下一条指令,即复位后去0XFFFD取指令
*(long *)0xFFD0=0x0A004031;//mov.w  #0A00,SP;//在下一条指令的地方写入要执行的指令,这是固定的,执行完后地址偏移4继续执行
*(long *)0xFFD4=0x117c12B0;//这句的意思就是第三条指令要调用更新程序了,117c就是更新程序的主函数所在的地址,12B0是调用函数指令
下面就开始IAP吧......
这样即使更新过程断了,下次上电还是会进入更新程序的直到更新完毕,细节地方自行研究

回复

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
 楼主| 发表于 2018-8-20 16:21:17 | 显示全部楼层
qiousanxi 发表于 2018-8-20 14:26
1.首先 ,你先写个正常的IAP程序 ,假设FLASH 地址范围是4000-FFFF 不去改任何地址。 假设你Code占用FLASH  ...

谢谢大神的指导,写的非常详细,步骤也很清晰,再次感谢您的回答,让我学到了很多
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 16:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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