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.

TM4C129的中断向量表起始地址是多少?

是0x00000004吗?

为什么库文件中这么定义呢:

#define NVIC_VTABLE             0xE000ED08  // Vector Table Offset                      在hw_nvic.h文件中

#define NVIC_BASE                  0xE000E000 // Nested Vectored Interrupt Ctrl    在hw_memmap.h文件中

如果要重新定义 中断向量表起始地址 又要怎么弄呢?主要是做IAP升级用的。

  •  0xE000E000是外设总线上SysTick, NVIC, MPU, FPU and SCB registers的起始地址

    芯片复位以后的地址才是0x00000004

    这些是由芯片的内核决定的。

  • 您好,

            那请问要如何设置中断向量表的偏移量呢?

           我是用TM4C129做IAP升级,分为bootloader程序和app程序,flash空间前64KB(0x00000000~0x00010000)分配给bootloader程序,其余给APP程序(0x00010000~0x00100000)。

    现在的情况是程序可以从bootloader程序跳转到app程序了,但是 跳转后执行一会儿就死机了(串口内容只打印了一半),目测是 APP程序的中断向量表没有设置好;因为当APP程序中有中断产生时,TM4C129的 PC 指针仍强制跳转到地址0X00000004 中断向量表处,而不是新程序的中断向量表(0x00010004),所以在APP程序开始处需要设置中断向量表的偏移量,在stm32中用  SCB->VTOR = FLASH_BASE | 0x10000; 来设置,不知道在TM4C129中要如何设置这个偏移量?

    我用  HWREG(NVIC_VTABLE) = 0x10000;  这一句不行。谢谢。

  • 这个没有用过。但是tiva ware中是有bootloader的代码的,可以参考看看。

  • 已经弄好了,APP的中断向量表可以不用设置,因为TI库函数里已经把 中断向量表复制到ram区了,那偏移地址在库函数里设置了。源码如下:

    void
    IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void))
    {
        uint32_t ui32Idx, ui32Value;

        //
        // Check the arguments.
        //
        ASSERT(ui32Interrupt < NUM_INTERRUPTS);

        //
        // Make sure that the RAM vector table is correctly aligned.
        //
        ASSERT(((uint32_t)g_pfnRAMVectors & 0x000003ff) == 0);

        //
        // See if the RAM vector table has been initialized.
        //
        if(HWREG(NVIC_VTABLE) != (uint32_t)g_pfnRAMVectors)
        {
            //
            // Copy the vector table from the beginning of FLASH to the RAM vector
            // table.
            //
            ui32Value = HWREG(NVIC_VTABLE);
            for(ui32Idx = 0; ui32Idx < NUM_INTERRUPTS; ui32Idx++)
            {
                g_pfnRAMVectors[ui32Idx] = (void (*)(void))HWREG((ui32Idx * 4) +
                                                                 ui32Value);//复制中断向量表
            }

            //
            // Point the NVIC at the RAM vector table.
            //
            HWREG(NVIC_VTABLE) = (uint32_t)g_pfnRAMVectors;  //重新定义偏移地址
        }

        //
        // Save the interrupt handler.
        //
        g_pfnRAMVectors[ui32Interrupt] = pfnHandler;
    }

    不过不懂为什么要把中断向量表复制到ram区,有什么好处吗?而且如果用flash区的中断向量表程序运行起来有点小问题(体现在复位后串口打印有时候会乱码,十次会出现5次这种情况)。

  • RAM够大  程序全部装进去 运行的更快

  •     你好,我也在做boot/app,请问下tm4c129如何从boot跳转到app的呢?在内核文件中并没有找到类似__set_MSP(*(volatile u32*)AppAddress)的跳转函数。

    谢谢!

  •     (*((void (*)(void))(*(uint32_t *)0x2c)))(); 

    类似用这样的函数,直接跳到app地址的吧。或者boot执行完毕,直接就到app了。

  • typedef  void (*iapfun)(void); 

    iapfun jump2app;

    iap_load_app(APP_START_ADDR);//程序跳转,一般在主程序调用。

    另外,程序升级完成后最好不要立即跳转,应该在eeprom或者flash写个标志位然后重启,,bootloard程序一开始先检查这些标志位,有升级完成的直接跳转,没升级完成的再进行以太网串口等一些外设初始化进入升级模式,不然bootloard和app的中断向量表容易打架,具体实现的方式得自己设计了。

  •       嗯,上个礼拜搞定了,在TivaWare中usb_stick_uupdate有类似的案例,非常感谢楼主的分享!

  • 您好,您这个最终是怎么实现的呢?我现在是使用串口接收到.bin文件后,写入flash中,然后再去运行新的程序,发现新的程序根本没运行。
  • 您好,您是怎么实现的呢?程序写入flash后怎么显示跳转。
  • 简单来说是这么几个步骤:
    1、把FLASH分成BootLoader和app两部分,以TM4C129为例,可以设置0~0x10000为BootLoader,其余为app。那么,你的BootLoader程序就跟普通程序一样,直接下载到0~0x10000区域内就行了(正常BootLoader不会超过这个范围的,这个片子空间还是很大的,严格来讲是范围是0~0xFFFF,0x10000是app程序的起始地址);然后利用BootLoader程序接收外界发送过来的app的bin文件(串口、网口都行),并且把这个文件数据写入从0x10000开始的flash地址。
    2、app程序是需要特殊设置的,主要就是中断向量表地址,在时钟初始化后加入这么一句HWREG(NVIC_VTABLE) = 0x10000;另外,在keil软件内IROM1起始地址要改为0x10000,size改为0xF0000(size比你的app固件大就行了)。
    3、剩下的就是BootLoader的跳转程序设置了,具体上面的楼层回复时已经贴出来了。需要注意的是,因为你在串口或者以太网接收bin文件时基本上都会开启中断的(直接跳转很容易出现问题),所以在跳转设置时应考虑用eeprom来设置标志位,这样,在BootLoader开始时先检查标志位,如果app程序写成功了就进行跳转,没有就进入升级模式,进行一些外设的初始化,也就意味着,app程序写入完成后弄个标志位然后直接复位系统。

    其实跟stm32是一样的,因为网上stm32资料比较多,你可以先弄stm32,成功了再来弄TM4C129,它们的差别就是FLASH的地址和中断向量表的地址,其它原理是一样的。资料的话直接百度搜索 第五十三章串口IAP实验战舰STM32开发板 就有了。这种事情还是要理解原理才有意义,不然即使成功了在实际部署产品时出现问题就会很麻烦的。
  • 感谢您的回答,谢谢。是这样的,STM32的我之前有做过的,现在的一些程序也是从32那边移植过来的。
    1、TI的这个TM4C129我是在CCS7.0下开发的,跳转程序参考的是ti例程里的程序:
    代码如下:
    #if defined(ccs)
    void call_application(uint_fast32_t ui32StartAddr)
    {
    // Set the vector table to the beginning of the app in flash.
    HWREG(NVIC_VTABLE) = ui32StartAddr;

    // Load the stack pointer from the application's vector table.
    __asm(" ldr r1, [r0]\n"
    " mov sp, r1\n");

    // Load the initial PC from the application's vector table and branch to
    // the application's entry point.
    __asm(" ldr r0, [r0, #4]\n"
    " bx r0\n");
    }
    #endif

    2、app程序的开头也做了向量处理。包括.CMD文件里面的内存分配也做了调整:代码如下:
    //app.cmd文件
    MEMORY
    {
    FLASH (RX) : origin = 0x00010000, length = 0x000F0000
    SRAM (RWX) : origin = 0x20000000, length = 0x00040000
    }

    /* The following command line options are set as part of the CCS project. */
    /* If you are building using the command line, or for some reason want to */
    /* define them here, you can uncomment and modify these lines as needed. */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone. */
    /* */
    /* --heap_size=0 */
    /* --stack_size=256 */
    /* --library=rtsv7M4_T_le_eabi.lib */

    /* Section allocation in memory */

    SECTIONS
    {
    .intvecs: > 0x00010000
    .text : > FLASH
    .const : > FLASH
    .cinit : > FLASH
    .pinit : > FLASH
    .init_array : > FLASH

    .vtable : > 0x20000000
    .data : > SRAM
    .bss : > SRAM
    .sysmem : > SRAM
    .stack : > SRAM
    }

    __STACK_TOP = __stack + 512;

    //main函数
    int main(void)
    {
    SystemConfigAndCheck();

    DeviceConfigandCheck();

    /*----------- 初始化os并指定cpu空闲任务 ---------------------------------*/
    os_initialise(idel_task);

    at_init();


    u_printf("app \r\n", NULL);
    //通信接收数据用任务
    // os_task_create(communication_recv_task, 5000, 10);
    HWREG(NVIC_VTABLE) = 0x00010000;
    for( ; ; )
    {
    if(g_sysSchedule._30ms > 500){
    g_sysSchedule._30ms = 0;
    led(1, cpuIdel);
    cpuIdel = !cpuIdel;
    }
    //os_dispatch_tasks();
    }
    //return(0);
    }

    现在跳转后程序根本不执行,bootloader实现流程描述如下:
    上电后运行bootloader,通过AT指令的模式接收.bin文件,接收完成后将文件写入Flash中。然后校验栈顶地址和程序开始运行地址,然后调用上面提到的call_application(uint_fast32_t ui32StartAddr)函数进行跳转:实现代码如下:
    void iap_load_app(unsigned int appxaddr)
    {
    //检查栈顶地址是否合法.
    if( ((HWREG(appxaddr))&0x2FF80000) == 0X20000000 &&
    ((HWREG(appxaddr+4))&0xFFFF0000) == FLASH_APP_ADDR){
    //用户代码区第二个字为程序开始地址(复位地址)
    g_jump2appfun = (iapfun_t)HWREG(appxaddr+4);
    //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
    call_application(HWREG(appxaddr));

    //跳转到APP执行
    g_jump2appfun();
    }
    }


    麻烦您帮忙看一下,谢谢。
  • CCS我还真没用过,不知道flash地址哪里设置,但这个肯定是要设置的。 另外,你这里有个错误,你先改了试下:call_application(HWREG(appxaddr)); 这里应该是call_application(appxaddr);才对吧?(HWREG(appxaddr)是取appxaddr上的内容了。
  • 好了,多谢,问题就在这,大意了。谢谢。
  • 你好,你知道怎么通过软件实现TM4C的cpu完全复位呢?
  • 有个窗口看门狗,启用后,想复位的时候停止喂狗就行了。
  • 没有其他办法吗?
  • 你用一个引脚去控制RST应该也行的,不过我还没这么试过,我都是用看门狗的。看门狗不能用吗?
  • 可以用的,我只想软件方式实现cpu所得初始化