求指导msp430的iap升级功能

2019-07-15 15:08发布

关于msp430的iap升级功能哪个大神可以指导一下:1怎么分别修改boot和app的.xcl文件?2中断向量表是如何重定义的?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
tuiming817
1楼-- · 2019-07-16 08:02
[C] 纯文本查看 复制代码
#if __VER__ < 200#pragma codeseg(UPDATECODE)    //在IAR2.0以下的程序定位函数#endif#include <msp430x14x.h>#include "hportini.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 "hupdate.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__ < 200monitor 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__ < 200monitor 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__ < 200monitor 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__ < 200monitor 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__ < 200monitor 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__ < 200monitor 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__ < 200monitor 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__ < 200monitor 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; }
ctwywjer
2楼-- · 2019-07-16 09:15
 精彩回答 2  元偷偷看……
BJJRTD
3楼-- · 2019-07-16 15:15
[C] 纯文本查看 复制代码
//为防止更新过程中 传输终止,把初始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;
另一个帖子中这三句话比较难理解,下面是作者说的话:
这个不难,思路就是把你的更新程序强制编译到固定地址空间,主程序判断条件进入更新程序后,更新程序擦除主程序区,然后外部接收要更新的代码往里写就行了,当然,更新程序所在空间是不能擦除的。
如果考虑更新过程中更新失败的情况,那你就要了解430的启动过程,在进入更新程序的时候,先将要复位要执行的指令写到中断向量区,如果更新不成功,那么每次上电让它强制进你的更新程序,知道更新完毕。
你需要了解的有启动过程、中断向量等。给你三句关键程序,结合启动过程好好研究研究吧
*(int *)0xFFFE=0xFFD0;//430复位去0XFFFE取指令,这地址值是多少就跳到多少地址执行下一条指令,即复位后去0XFFFD取指令
*(long *)0xFFD0=0x0A004031;//mov.w  #0A00,SP;//在下一条指令的地方写入要执行的指令,这是固定的,执行完后地址偏移4继续执行
*(long *)0xFFD4=0x117c12B0;//这句的意思就是第三条指令要调用更新程序了,117c就是更新程序的主函数所在的地址,12B0是调用函数指令
下面就开始IAP吧......
这样即使更新过程断了,下次上电还是会进入更新程序的直到更新完毕,细节地方自行研究
pipompipom
4楼-- · 2019-07-16 16:06
谢谢大神的指导,写的非常详细,步骤也很清晰,再次感谢您的回答,让我学到了很多

一周热门 更多>