关于stm8 iap 中断向量表的重定向问题

2019-07-19 21:05发布

本帖最后由 stopshooting 于 2016-7-10 03:11 编辑

在STM8 IAP的官方bootloader例程中, 中断向量表的重定向是这样的。
[mw_shl_code=c,true]/*        Redirected interrupt vector table
*        Copyright (c) 2008 STMicroelectronics
*/

#include "main.h"

typedef void @far (*interrupt_handler_t)(void);

struct interrupt_vector {
        unsigned char interrupt_instruction;
        interrupt_handler_t interrupt_handler;
};

@far @interrupt void NonHandledInterrupt (void)
{
        /* in order to detect unexpected events during development,
           it is recommended to set a breakpoint on the following instruction
        */
        return;
}

extern void _stext();     /* startup routine */
struct interrupt_vector const UserISR_IRQ[32] @ MAIN_USER_RESET_ADDR;

//redirected interrupt table
struct interrupt_vector const _vectab[] = {
    {0x82, (interrupt_handler_t)_stext}, /* reset */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 1)}, /* trap  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 2)}, /* irq0  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 3)}, /* irq1  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 4)}, /* irq2  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 5)}, /* irq3  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 6)}, /* irq4  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 7)}, /* irq5  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 8)}, /* irq6  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+ 9)}, /* irq7  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+10)}, /* irq8  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+11)}, /* irq9  */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+12)}, /* irq10 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+13)}, /* irq11 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+14)}, /* irq12 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+15)}, /* irq13 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+16)}, /* irq14 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+17)}, /* irq15 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+18)}, /* irq16 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+19)}, /* irq17 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+20)}, /* irq18 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+21)}, /* irq19 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+22)}, /* irq20 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+23)}, /* irq21 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+24)}, /* irq22 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+25)}, /* irq23 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+26)}, /* irq24 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+27)}, /* irq25 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+28)}, /* irq26 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+29)}, /* irq27 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+30)}, /* irq28 */
    {0x82, (interrupt_handler_t)(UserISR_IRQ+31)}, /* irq29 */
};
[/mw_shl_code]

其中MAIN_USER_RESET_ADDR 为0x9000,也就是说用户APP的中断向量表是放在0x9000上的
我的问题是,为什么重定向的地址是(interrupt_handler_t)(UserISR_IRQ+xx)?
根据上面的程序,
(UserISR_IRQ+ 1)表示0x9004,(UserISR_IRQ+ 2)表示0x9008,
(UserISR_IRQ+ 3)表示0x900c,
(UserISR_IRQ+ 4)表示0x9010,
(UserISR_IRQ+ N)表示(0x9000+N*4),而bootloader的的中断向量表是放在0x8000上的,
从这个表格中可以看出,bootloader的中断向量表_vectab中的interrupt_handler_t变量的地址明明就是0x8005, 0x8009, 0x800d, 0x8011, ((0x8000+N*4)+1)啊。。
难道重定向后的地址不应该0x9005, 0x9009, 0x900d, 0x9011, (0x9000+N*4+1)吗?
也就是 (interrupt_handler_t)((void*) (interrupt_handler_t)(UserISR_IRQ+xx)+(void*)1)吗?
用STVD仿真看到附件的图片:
可以看到中断向量表的interrupt_handler_t变量所在地址与其内容的比较
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。