This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR2476:BSL 代码中的中断矢量表问题

Guru**** 1133960 points
Other Parts Discussed in Thread: MSP430FR2311, MSPBSL, MSP430FR2476
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1350322/msp430fr2476-interrupt-vector-table-issue-in-bsl-code

器件型号:MSP430FR2476
主题中讨论的其他器件:MSPBSL、MSP430FR2311、

大家好、

我正在处理 BSL 代码、并能够在存储器的同一位置(0x8004)正确刷写代码。但我有两个应用程序、这两个应用程序都使用 WDT、因此运行两个应用程序时是问题所在。

Application1在位置0x8004处刷写、Application2在位置0x81BE 处刷写。
还尝试了使用 《MSP430FRBoot 的双映像示例–适用于 MSP430 FRAM 大型存储器型号器件的主存储器引导加载程序和无线更新》进行编码。 不使用、因为生成的链接器文件都有单一矢量表。 此外、对于我的应用来说、双映像并不是必需的

两个应用的起始应用程序地址相同、即0x8004、因此对于 App2、我在此中将初始地址更改为0x81BE、我还必须更改矢量表。 我想知道如何为 App2添加矢量表。

我的应用的工作流程是、引导代码一开始运行、app1通过 UART 接收、然后验证并运行。 现在更新代码、即应用2、对于这一点、app1中的中断从 app1移动到引导代码、现在开始在这个过程中接受 App2。如果发生问题、我需要程序跳转到 app1。



此致、
帕拉维

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嘿 Pallavi、

    我不完全理解这个问题、因为该器件的矢量表位于固定地址。  似乎你正在尝试执行一个主存储器 BSL、正确吗?  MSPBSL 页面上提供了大量信息、其中会将您链接到 MSP430FRBoot 主存储器 BSL 示例 、该示例听起来与您尝试执行的操作类似。   

    这是您提到的 OTA 更新示例吗?   

    谢谢。

    JD

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Crutchfield:
    很抱歉没有正确解释此问题。
    我正在编写 BSL 代码、具体做法是参考  《 适用于 MSP430 FRAM 大型存储器型号器件的 MSP430FRBoot–主存储器引导加载程序和无线更新》中提到的示例的 MSP430 FRAM 器件引导加载程序(BSL)和 OTA 更新。  
    主机:MSP430FR2311

    目标:MSP430FR2476
    App1: 使用 WDT 使 MSP430FR2476的 P1.0 LED 闪烁

    App2:  使用 WDT 使 MSP430FR2476的 P4.7 LED 闪烁

    工作流程:

    主机将 App1发送为应用程序0x8004的起始地址  

    运行引导代码的目标接收 app1处理它、并验证并跳转到位置0x8004。当 app1在运行时、P2.3端口中断会禁用所有中断并跳回引导代码的起始位置。

    现在我必须发送 App2 (不覆盖 app1)。在引导代码中保持运行目标、在主机中添加 App2代码并连接到 PC。

    主机将向 App2发送包含应用程序0x81BE 的起始地址、目标会接收并处理该应用程序并跳转到0x81BE 位置。

    此处 App2已输入、且包含开启和关闭 LED、但 WDT 未被调用、因为 #pragma vector = WDT_vector 指向 app1 P1.0 LED。 因此、用于使 P4.7闪烁的 WDT 无法正常工作。
    基于此处的观察结果、我们需要两个矢量表、一个表用于 app1 P1.0LED、另一个矢量表用于 p4.7

    以下是所有文件的参考。 正如我们正在实验的那样、仅在主机和目标中添加所需的代码部分

    e2e.ti.com/.../3223.BSL.zip

    此致、

    帕拉维  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嘿 Pallavi、

    好的、那么您要尝试管理器件上的两个单独的固件映像、并能够在它们之间来回切换、对吗?  我们目前指的是您尝试编写的"Boot Image Manager"或 BIM。  我们有一些适用于我们的无线器件和 MSPM0的 BIM 示例、但我不知道任何适用于 MSP430的示例。  我不确定它们是如何工作的、但也许他们的文档和代码可以帮助您了解它们是如何实现此功能的。   

    MSPM0 BIM 用户指南如下: https://software-dl.ti.com/msp430/esd/MSPM0-SDK/1_20_00_05/docs/english/middleware/boot_manager/doc_guide/doc_guide-srcs/index.html# 

    这里是 BIM 应用程序本身以及可以加载的示例固件映像的 BIM 示例: https://dev.ti.com/tirex/explore/node?node=A__AG-cEnMMa1GfTvRDf4FAuA__MSPM0-SDK__a3PaaoK__LATEST 

    谢谢。

    JD

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嘿 Pallavi、

    我与一位熟悉 MSPM0 BIM 的软件工程师交谈过、他们使用的是"矢量表偏移寄存器"、这是我们在 MSP430中没有的一个新功能。   

    基本上、您必须根据要运行的固件映像更新矢量表。 TRM 包含备用中断向量表以及如何将其移动到 RAM。   这样、BIM 就会以某种方式确定哪个图像是正确的、并相应地设置矢量表。   然后、如果加载了较新的映像、例如、可以稍后对其进行更新。   

    希望这对您有所帮助。  

    JD

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、JD:

    谢谢你的答复。

    好了,您可以尝试在设备上管理两个单独的固件映像,并能够在两个映像之间来回切换,对吗?  [/报价]

    可以。 因为主应用程序将在运行。 返回引导加载程序代码和 现场固件更新过程将启动 、如果出现某些问题、我们的应用的现场工作不应停止、因此应返回到之前的版本(应用程序1)并继续进行  

    此外、我浏览了相关文档、发现 RAM Vector 非常有用、因此我可以着手实施该算法。 我在这些中遇到了错误。

    参考此主题 https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/399114/how-to-use-sysrivect-bit-in-register-sysctl



    由于我有三个独立的文件、因此我在主文件和应用程序文件中创建了"vector_table.h"文件。

    #ifndef vector_table_H_
    #define vector_table_H_

    extern void app1_WDT_ISR ();
    extern void App2_WDT_ISR ();


    #define RAM_MAX_ADDRESS 0x1FFF
    #define MAP_Vector_BASE (RAM_MAX_ADDRESS-1-RESET_VECTOR)
    #define NUM_VECTOR ( 1+((reset_vector-RTC_VECTOR )>>1)


    __interrupt void app1_WDT_ISR (void);
    __interrupt void App2_WDT_ISR (void);

    #endif /* vector_table_H_*/

    main.c

    #include "MSP430.h"
    #include "TI_NIC.h" Boot_Common
    #include "TI_MSPBoot_CI.h"
    #include "TI_MSPBoot_MI.h"
    #include "TI_scholee.45" Boot_App
    #include "vector_table.h"


    //局部函数原型


    void Software_Trim ();//获得最佳 DCOFTRIM 值的软件调整
    #define MCLK_FREQ_MHz 8 // MCLK = 8MHz

    静态空 clock_init (void);
    tBOOL TI_Apparti_appis Boot_App id (void);


    char JmpToApp、jumpToApp2;
    unsigned char * addr = NULL;
    char app1_downloaded、app2_start、app2_end;

    //#pragma NOINIT unsigned int map_vector[ NUM_vector ]@map_vector_BASE


    __no_init unsigned int map_vector[ NUM_vector ]@map_vector_BASE;
    */李启










































































    明 * *@简介主要功能 *-初始化 MCU *-选择是运行应用程序还是引导加载程序 *-如果是引导加载程序: *-初始化外设接口 *-等待命令 *-发送相应的响应 *-如有申请: *-跳转到应用程序 * *@返回无 * / void main_boot (void) { WDTCTL = WDTPW + WDTHOLD; PM5CTL0 &=~μ A LOCKLPM5; Clock_init(); __ bis_SR_register (GIE); P4DIR |= BIT7; P4OUT |= BIT7; __ delay_cycles (5000); P4OUT &=~BIT7; MAP_VECTOR [(WDT_VECTOR - RTC_VECTOR)/2]= app1_WDT_ISR; MAP_VECTOR [(WDT_VECTOR - RTC_VECTOR)/2]= App2_WDT_ISR; SYSCTL |= SYSRIVECT; addr =(unsigned char*) 0x1804; JmpToApp =*地址; //if ((* JmpToApp)== 1) 如果(JmpToApp == 1) { _disable_interrupt (); ((void (*)()) 0x8004)(); } if (JmpToApp == 2) { //jumpToApp2 = 0; _disable_interrupt (); (void (*)()) 0x81BE)(); } //验证应用程序,并在需要时跳转 如果(TI_SCPHIN_Validate() Boot_App == true_t) { ___ no_operation(); TI_MSPBoot_APPMGR_JUMPTOAPP (); } TI_MSPBoot_CI_Init ();//初始化通信接口 while (1) { //轮询新数据包的 PHY 和数据链路接口 TI_MSPBoot_CI_PHYDL_Poll (); 如果(app1_downloaded ==1&& App2_start ==1&& App2_End == 0) { _disable_interrupt (); ((void (*)()) 0x8004)(); } //如果检测到新的数据包,则对其进行处理 如果(TI_MSPBoot_CI_Process ()== RET_JUMP_TO_APP) { //如果数据包表示跳转到应用程序 //* JmpToApp = 1; //JmpToApp = 1; 如果(app1_downloaded == 1) { addr =(unsigned char*) 0x1804; SYSCFG0 = FRWPPW | PFWP; *addr = 2; SYSCFG0 = FRWPPW | DFWP | PFWP; } 否则、如果(app1_downloaded!= 1) { addr =(unsigned char*) 0x1804; SYSCFG0 = FRWPPW | PFWP; *addr = 1; SYSCFG0 = FRWPPW | DFWP | PFWP; } App1_DOWNLOADED = 1; TI_452002_Jump Boot_App App (); } #ifdef NDEBUG //~每隔1000毫秒喂狗 watchdog_fed(); #endif } } 错误: 也尝试了 noint、但出现相同的错误。 我不知道这里的帽子是 MAP_Vector 此致、 帕拉维
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嘿 Pallavi、

    我可能已经差你走了错误的方向。  我发现这条很好的线索始于几年前、为移植 MSPBOOT 的人们提出了很多要点。  Caleb 重点指出了在 FRAM 器件中、不需要移动矢量表、因为我们只需像 RAM 一样简单地写入 FRAM。   https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/592033/msp430fr2311-custom-bsl-mapping-proxy-interrupt-vector-table-in-msp430fr-issue 

    查看该主题和链接的主题、看看 Caleb 的见解是否能帮助您实现这一目标。   

    谢谢。

    JD

      

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、JD:

    我了解 FR 模型需要代理矢量表或 RAM 矢量。

    已更改 WDT 的链接器文件

    部分
    {
    .bss :{}> RAM /*全局和静态 VARS */
    .data :{}> RAM /*全局和静态 VARS */
    .sysmem:{}> RAM /*动态内存分配区*/
    .stack:{}> RAM (高)/*软件系统堆栈*/

    .text:_isr:{}> FLASH /* Code ISR */
    #ifndef __large_data_model__
    .text :{}>> FLASH /* code */
    #else
    .text :{}>> FLASH | FLASH2 /*代码*/
    #endif
    .cinit :{}> FLASH /*初始化表*/
    #ifndef __large_data_model__
    .const :{}>> FLASH /*常量数据*/
    #else
    .const :{}>> FLASH2| FLASH /*常量数据*/
    #endif

    .cio:{}> RAM /* C I/O 缓冲器*/

    /* MSP430中断矢量*/
    .int00:{}> int00
    .int01:{}> int01
    .int02 :{}> INT02
    .int03:{}> int03
    .int04 :{}> int04
    .int05 :{}> INT05
    .int06 :{}> INT06
    .int07 :{}> INT07
    .int08 :{}> INT08
    .int09 :{}> INT09
    .int10:{}> int10
    .int11:{}> int11
    .int12:{}> int12
    .int13:{}> int13
    .int14:{}> int14
    .int15 :{}> int15
    .int16 :{}> int16
    .int17 :{}> int17
    .int18 :{}> int18
    .int19 :{}> int19
    ECOMP0 :{*(.int20 )}> INT20 TYPE = VECT_INIT
    PORT6 :{*(.int21 )}> INT21 type = VECT_init
    PORT5 :{*(.int22 )}> INT22 TYPE = VECT_INIT
    Port4 :{*(.int23 )}> int23 type = VECT_init
    PORT3 :{*(.int24 )}> int24 type = VECT_init
    port2 :{*(.int25 )}> int25 type = VECT_init
    Port1 :{*(.int26 )}> int26 type = VECT_init
    ADC :{*(.int27 )}> int27 type = VECT_init
    EUSCI_B1 :{*(.int28 )}> INT28 TYPE = VECT_INIT
    EUSCI_B0:{*(.int29 )}> INT29 TYPE = VECT_INIT
    EUSCI_A1:{*(.int30 )}> INT30 TYPE = VECT_INIT
    EUSCI_A0 :{*(.int31 )}> INT31 TYPE = VECT_INIT
    //WDT:{*(.int32 )}> int32 type = VECT_init

    WDT:{}>0xF400 type = VECT_init                 //此处更改

    RTC :{*(.int33 )}> int33 type = VECT_init
    TIMER0_B1 :{*(.int34 )}> INT34 TYPE = VECT_INIT
    TIMER0_B0:{*(.int35 )}> int35 type = VECT_init
    TIMER3_A1:{*(.int36 )}> INT36 TYPE = VECT_INIT
    TIMER3_A0 :{*(.int37 )}> INT37 type = VECT_init
    TIMER2_A1:{*(.int38 )}> INT38 TYPE = VECT_INIT
    TIMER2_A0 :{*(.int39 )}> INT39 type = VECT_init
    Timer1_A1:{*(.int40)}> int40 type = VECT_init
    Timer1_A0:{*(.int41 )}> INT41 TYPE = VECT_INIT
    TIMER0_A1:{*(.int42 )}> INT42 TYPE = VECT_INIT
    TIMER0_A0:{*(.int43 )}> INT43 TYPE = VECT_INIT
    UNMI :{*(.int44 )}> INT44 TYPE = VECT_INIT
    SYSNMI :{*(.int45 )}> INT45 TYPE = VECT_INIT

    .reset:{}> reset /* MSP430复位向量*/

    但是 LED 闪存无法正常工作。 如果我的理解有误、您能告诉我需要编辑哪个位置吗?  
    这是 app1.c

    #include "MSP430.h"
    #包含
    #include "TI_NIC.h" Boot_Mgr_Vectors


    int main()
    {

    WDTCTL = WDT_ADLY_1000;//每1秒调用一次看门狗
    SFRIE1 |= WDTIE;

    //在 P1.0中切换 LED1
    P1DIR |= BIT0;
    P1OUT |= BIT0;
    PM5CTL0 &=~μ A LOCKLPM5;
    __delay_cycles (500000);
    P1OUT &=~BIT0;
    __delay_cycles (500000);
    P1OUT |= BIT0;
    __delay_cycles (500000);
    P1OUT &=~BIT0;

    P4DIR |= BIT7;

    //通过上拉启动 P2.3 (S2按钮)作为中断
    P2DIR &=~BIT3;
    P2REN |= BIT3;
    P2IES |= BIT3;
    P2IFG &=~BIT3;
    P2IE |= BIT3;

    __ bis_SR_register (GIE);

    while (1)
    {
    ___ no_operation();

    //返回0;

    #pragma vector = WDT_vector
    __interrupt void App2_WDT_ISR (void)
    {
    P4OUT ^= BIT7;


    #pragma vector = port2_vector
    __interrupt void Port2_ISR (void)
    {
    P2IFG = 0;
    Boot_Jump Boot ();



    我想我必须更改 WDT_vector 位置。 当前它指向 0xFFE2