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.

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

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

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

器件型号:LP-MSP430FR2476
主题中讨论的其他器件:MSP430FR2476

大家好、

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

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


此致、
帕拉维

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    不能同时使用、因为生成的链接器文件具有单个矢量表

    我们提供了 python 脚本工具来帮助您生成 所 引用的链接文件。

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

    您好、Gary Gao、

    感谢您的回复、

    好的、我将尝试添加 RTOS 任务。 但要运行的主应用程序包含 WDT、我正在尝试对其进行此实验。 因此我需要 WDT  

    是的、我使用了 python 脚本来生成链接文件。 该文件具有 appl_vector (仅一个矢量表)、因此应用程序1和2都使用相同的矢量表并指向 WDT_Vector 的相同位置。
    但我希望 app1指向存储器的一个位置的 WDT_Vector、并希望 App2指向存储器的另一个位置(WDT_Vector)  

    下面是我正在处理的文件。 仅在目标和主机上放置所需的代码
    e2e.ti.com/.../4300.BSL.zip

    此致、

    帕拉维

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

    这是必需的、因为它用于 OTA 更新、因此其中一个应用程序正在运行、对于 OTA 更新、我们会首先收到更新的代码、如果代码未得到验证或在更新期间停止、我们必须返回应用程序1 并运行。 稍后、我们可以再次刷写更新的固件、

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

    这听起来对 SYSRIVECT 来说是一项工作。

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

    尊敬的 David:

    是、我尝试了 RAM 矢量实现

    参考此主题 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 此致、 帕拉维
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不知道这个混乱应该做什么,但你需要的是简单的。

    复位时、向量位于常规位置、并将在对引导加载程序代码进行编程时设置。 它将执行需要执行的操作、然后跳转到应用程序。

    应用程序的初始堆栈位置偏移量将低于其定制链接器脚本所用的 SRAM 矢量表区域。 它将设置所需的任何矢量、然后设置 SYSRIVECT。

    引导加载程序不需要知道应用程序在做什么。 这很好。

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

    我是否需要更改应用程序代码的链接器文件(Appl_Vector 位置)  

    或者、我应该在 App2中创建矢量表、并将其放置某个存储器位置并将 WDT 指向它。 如果是、如何创建  

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

    您可以让应用程序创建矢量表条目照常进行处理、并由引导加载程序处理它们。 假设任何与引导加载程序通信的内容都会发送向量。

    或者让应用程序在初始化期间写入这些代码。 如中所示、将 ISR 的地址写入一个特定的地址。 如果只有一个 ISR、这可能是最简单的。

    当然、作为一个 FRAM 部件、您可以轻松地将数据写入常规矢量表位置至 SRAM。 唯一棘手的部分是禁用任何存储器保护。

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

    尊敬的 David:

    感谢您的回复、

    我在初始化期间使用了第二种编写应用程序的方法

    #包含
    #包含
    #include "TI_NIC.h" Boot_Mgr_Vectors
    //定义 WDT ISR
    #pragma vector = WDT_vector
    __interrupt void App2_WDT_ISR (void)
    {
    P4OUT ^= BIT7;//在 P1.0中切换 LED1

    int main()
    {
    WDTCTL = WDT_ADLY_1000;
    SFRIE1 |= WDTIE;

    //*(volatile uint16_t *)(0xfa96)=(uint16_t) App2_WDT_ISR;

    *(volatile uintptr_t *)(0xf3a4)=(uintptr_t) App2_WDT_ISR;


    P1DIR |= BIT0;
    P1OUT |= BIT0;

    PM5CTL0 &=~μ A LOCKLPM5;

    __delay_cycles (500000);
    P1OUT &=~BIT0;
    __delay_cycles (500000);
    P1OUT |= BIT0;
    __delay_cycles (500000);
    P1OUT &=~BIT0;

    //将 P2.3 (S2按钮)配置为带有上拉的中断
    P2DIR &=~BIT3;
    P2REN |= BIT3;
    P2IES |= BIT3;
    P2IFG &=~BIT3;
    P2IE |= BIT3;

    __ bis_SR_register (GIE);

    while (1)
    {
    ___ no_operation();


    #pragma vector = port2_vector
    __interrupt void Port2_ISR (void)
    {
    P2IFG &=~BIT3;//清除中断标志
    TI45200_BOOT Boot_Jump ();//跳转至引导加载程序(假设存在此函数)

    但没有得到 WDT 中断。 但最初在 P1.0开启和关闭时应用程序代码已正确输入。

    这是将 ISR 初始化为特定地址的方法吗? 我在网上搜索过它  

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

    很可能。 我从未尝试用 C 语言实现它、仅使用汇编语言。 但我可以看到您未使用正确的地址。 矢量从0xFF80运行到0xFFFF、包括在内。 嗯、有点像。 该空间的开头用于其他目的。

    看看链接器脚本、我看到 WDT 是 VECT32、它的位置是0xFFE2。

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

    上述所有问题都与此相关、即有两个 WDT 和一个存储器、两者都指向同一位置、因此只能放入一个代码、而不能放入另一个代码。 应用程序1和2的 WDT 是 VECT32、因此我想更改一个应用程序的地址、以便两个程序都能放入内存、并检查 App2错误。一旦无错误、运行 App2.如果存在错误、则运行 app1。

    我尝试了搜索语法、以便将 WDT_VECTOR 初始化为不同的地址。因为存储在 ROM 中的矢量不能添加另一个位置 、所以尝试了实现 RAM 矢量但是有错误。

    我没有获得初始化 it.please 的正确方法来帮助我初始化两个 WDT 中断。 两个 WDT ISR 都 将存储在存储器中、但在某些情况下、一次只执行一个 WDT ISR。 我需要在 C 语言中使用此语法 for CCS

    正如您在中看到的、链接器文件 矢量从 F3A2运行、所以我指定了 F3A4作为地址。

    /* RAM 内存地址*/
    _RAM_Start = 0x2000;/* RAM Start */
    _RAM_END = 0x3fff;/* RAM 结束*/
    /*应用程序和引导加载程序之间共享的 RAM、必须保留*/
    passwd = 0x2000;/*应用程序发送用于强制启动模式的密码*/
    StatCtrl = 0x2002;/* Comm 使用的状态和控制字节*/
    CI_Comm = 0x2003;/* State_Machine 使用的状态机变量*/
    CI_Callback_ptr = 0x2004;/*指向 Comm 回调结构的指针*/
    /*用于引导加载程序或应用程序用途的非保留 RAM */
    _nonreserved_RAM_Start = 0x2008;/*非保留 RAM */

    /*闪存地址*/
    __ Flash_Start = 0x8000;/*应用程序区域开始*/
    /*引导加载程序区域的保留闪存位置*/
    __ Boot_Start = 0xf400;/*引导闪存*/
    __FFFE = Boot_Reset;/*引导复位向量*/
    __SCR= Boot_Vector 0xFFA2;/*引导矢量表*/
    __MSP430_Len = 0x10;/*共享回调的长度(2次调用=4B (Boot_Shared)或8B (msp430x)*/
    __ Boot_Shared backs = 0xFF70;/*共享回调的开始*/
    _BOOT_APPVECTOR =___ Boot_Shared backs;/*应用程序表的定义*/
    Appl_Vector_Start = 0xf3a2;/*中断表*/
    /*为应用领域保留的闪存位置*/

    /*内存定义,根据上面的定义进行调整*/
    内存
    {
    SFR:origin = 0x0000、length = 0x0010
    peripherals_8bit:origin = 0x0010、length = 0x00F0
    peripherals_16BIT:origin = 0x0100、length = 0x0100
    // RAM from _nonreserved_RAM_Start -_RAM_END
    RAM:origin = 0x2008、length = 0x1ff8
    //从_vectors->闪存 App_Start (APP_Vectors-1)
    Flash : origin = 0x8003, length = 0x739f
    FLASH2:origin = 0x10000、length = 0x8000
    //中断表从_RESET-1 (App_Vector_Start)
    int00:origin = 0xf3a2、length = 0x0002
    INT01:origin = 0xf3a4、length = 0x0002
    INT02:origin = 0xf3a6、length = 0x0002
    int03:origin = 0xf3a8、length = 0x0002
    INT04:origin = 0xf3aa、length = 0x0002
    INT05:origin = 0xf3ac、length = 0x0002
    INT06:origin = 0xf3ae、length = 0x0002
    INT07:origin = 0xf3b0、length = 0x0002
    int08:origin = 0xf3b2、length = 0x0002
    INT09:origin = 0xf3b4、length = 0x0002
    int10:origin = 0xf3b6、length = 0x0002
    int11:origin = 0xf3b8、length = 0x0002
    int12:origin = 0xf3ba、length = 0x0002
    int13:origin = 0xf3bc、length = 0x0002
    int14:origin = 0xf3be、length = 0x0002
    INT15:origin = 0xf3c0、length = 0x0002
    int16:origin = 0xf3c2、length = 0x0002
    INT17:origin = 0xf3c4、length = 0x0002
    INT18:origin = 0xf3c6、length = 0x0002
    INT19:origin = 0xf3c8、length = 0x0002
    INT20:origin = 0xf3ca、length = 0x0002
    int21:origin = 0xf3cc、length = 0x0002
    int22:origin = 0xf3ce、length = 0x0002
    int23:origin = 0xf3d0、length = 0x0002
    int24:origin = 0xf3d2、length = 0x0002
    int25:origin = 0xf3d4、length = 0x0002
    int26:origin = 0xf3d6、length = 0x0002
    int27:origin = 0xf3d8、length = 0x0002
    int28:origin = 0xf3da、length = 0x0002
    INT29:origin = 0xf3dc、length = 0x0002
    int30:origin = 0xf3de、length = 0x0002
    int31:origin = 0xf3e0、length = 0x0002
    int32:origin = 0xf3e2、length = 0x0002
    int33:origin = 0xf3e4、length = 0x0002
    int34:origin = 0xf3e6、length = 0x0002
    int35:origin = 0xf3e8、length = 0x0002
    INT36:origin = 0xf3ea、length = 0x0002
    int37:origin = 0xf3ec、length = 0x0002
    int38:origin = 0xf3ee、length = 0x0002
    int39:origin = 0xf3f0、length = 0x0002
    int40:origin = 0xf3f2、length = 0x0002
    int41:origin = 0xf3f4、length = 0x0002
    int42:origin = 0xf3f6、length = 0x0002
    int43:origin = 0xf3f8、length = 0x0002
    INT44:origin = 0xf3fa、length = 0x0002
    int45:origin = 0xf3fc、length = 0x0002

    //通过_App App_Reset_Vector 进行重置
    复位:origin = 0xf3fe、length = 0x0002

    */李启明 /
    /*指定段分配到存储器中*/
    */李启明 /

    部分
    {
    .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


    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复位向量*/

    */李启明 /
    /*包含外设内存映射*/
    */李启明 /

    -l msp430fr2476.cmd

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

    似乎是说您有两个不同的 ISR 代码位、并且您希望 CPU 选择一个。 不能。 您可以更改向量以指向您想要运行的代码、但仅此而已。

    或者、您正在以奇怪的方式尝试多任务处理。

    至于矢量表、特定代码可能会将矢量表存储在0xf3a2、但 CPU 无关紧要。 您的程序必须将程序从该位置复制到 CPU 预期的位置。 默认位置、位于低 FRAM 顶部或 SRAM 的顶部。 具体取决于您如何使用 SYSRIVECT。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您可以将向量更改为指向要运行的代码,但仅此而已。

    可以。 我怎么能做到。 两者都被存储、我希望在条件上使矢量指向该代码

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

    我想您可以启用 SRAM 中断表、为此器件支持通过设置 SYSCTL 寄存器中的 SYSRIVECT 位将中断矢量重映射到 RAM 的结束区域。 您可以根据需要将中断表加载到 SRAM 的末尾、使其成为活动的中断表。

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

    什么情况?

    引导加载程序通常采用的是单一的应用程序。 足够容易。 但您似乎有两个。 因此、无论哪个正在运行并且需要 WDT 来捕获矢量。 您如何操作取决于您、因为这在很大程度上取决于您的代码和要求。

    对我来说太复杂了