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.
大家好、
我正在处理 BSL 代码、并能够在存储器的同一位置(0x8004)正确刷写代码。但我有两个应用程序、这两个应用程序都使用 WDT、因此运行两个应用程序时是问题所在。
Application1在位置0x8004处刷写、Application2在位置0x81BE 处刷写。
还尝试了使用 《MSP430FRBoot 的双映像示例–适用于 MSP430 FRAM 大型存储器型号器件的主存储器引导加载程序和无线更新》进行编码。 不使用、因为生成的链接器文件都有单一矢量表
此致、
帕拉维
您好、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 矢量实现
由于我有三个独立的文件、因此我在主文件和应用程序文件中创建了"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 来捕获矢量。 您如何操作取决于您、因为这在很大程度上取决于您的代码和要求。
对我来说太复杂了