wdshuang09 发表于 2020-5-12 23:16:54

STM8S105 IAP中断向量表重定义问题

用STM8S105实现程序升级,想在bootloader里可以使用中断,参考网上写的资料,中断表放在RAM中实现bootloader和APP都可以中断,RAM区域0x0780~0x07FF放中断向量表(128字节);但bootloader里卡住,中断函数不正常;定义了TIM1和TIM4中断,只有TIM1会中断,TIM4不进中断,或者只定义一个TIM4,TIM4中断正常,只要定义了两个以上中断就只有前面一个中断正常,后面的中断都进不了中断函数。不知道是什么原因?一、main.c函数

#if 1
typedef void (*isr_type_t)(void);
typedef struct
{
    uint16_t      interrupt_instruction;
    isr_type_t    interrupt_handler;
}interrupt_vector;
#pragma location=0x0780
interrupt_vectorvector_table_={0};
#endif

#pragma vector=25
__interrupt void TIM1_UPD_OVF_TRG_BRK_IRQ(void)
{
if(TIM1_GetFlagStatus(TIM1_FLAG_UPDATE)==SET)
{
    TIM1_ClearITPendingBit(TIM1_IT_UPDATE);//清除中断标志
    Time1_Cnt.x1msFlag=1;
    if(++Time1_Cnt.x1msCnt>500)
    {
      Time1_Cnt.x1msCnt=0;
      LED_RUN=!LED_RUN;
    }
}
}
#pragma vector=26
__interrupt void TIM4_UPD_OVF_IRQ(void)
{
if(TIM4_GetFlagStatus(TIM4_FLAG_UPDATE)==SET)
{
    TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
    if(++Time4_Cnt.x1msCnt>1500)
    {
      Time4_Cnt.x1msCnt=0;
      LED2=!LED2;
    }

}
}



int main(void)
{

vector_table_.interrupt_instruction=0x8200;
vector_table_.interrupt_handler=(isr_type_t)&TIM1_UPD_OVF_TRG_BRK_IRQ;
vector_table_.interrupt_instruction=0x8200;
vector_table_.interrupt_handler=(isr_type_t)&TIM4_UPD_OVF_IRQ;

SystemClock_Init(HSE_Clock);
LED_Init();
Timer1_Init(16-1,1000);
Timer4_Init();

。。。
}

二、ICF文件修改
define memory with size = 16M;

define region TinyData = ;

//define region NearData = ;


define region NearData = ;

define region Eeprom = ;

define region BootROM = ;

define region NearFuncCode = ;

define region FarFuncCode = ;

define region HugeFuncCode =



三、stm8s_interrupt.s文件修改
__intvec:
      DC8   0x82
      DC24    __iar_program_start          ;; RESET    0x8000
      DC8   0x82
      DC24    0x0784
      DC8   0x82
      DC24    0x0788
      DC8   0x82
      DC24    0x078C
      DC8   0x82
      DC24    0x0790
      DC8   0x82
      DC24    0x0794
      DC8   0x82
      DC24    0x0798
      DC8   0x82
      DC24    0x079C
      DC8   0x82
      DC24    0x07A0
      DC8   0x82
      DC24    0x07A4
      DC8   0x82
      DC24    0x07A8
      DC8   0x82
      DC24    0x07AC
      DC8   0x82
      DC24    0x07B0
      DC8   0x82
      DC24    0x07B4
      DC8   0x82
      DC24    0x07B8
      DC8   0x82
      DC24    0x07BC
      DC8   0x82
      DC24    0x07C0
      DC8   0x82
      DC24    0x07C4
      DC8   0x82
      DC24    0x07C8
      DC8   0x82
      DC24    0x07CC
      DC8   0x82
      DC24    0x07D0
      DC8   0x82
      DC24    0x07D4
      DC8   0x82
      DC24    0x07D8
      DC8   0x82
      DC24    0x07DC
      DC8   0x82
      DC24    0x07E0
      DC8   0x82
      DC24    0x07E4
      DC8   0x82
      DC24    0x07E8
      DC8   0x82
      DC24    0x07EC
      DC8   0x82
      DC24    0x07F0
      DC8   0x82
      DC24    0x07F4
      DC8   0x82
      DC24    0x07F8
      DC8   0x82
      DC24    0x07FC

      END


butterflyspring 发表于 2020-5-18 11:47:38

STM8手册上应该没有提到向量重映射的功能,也就是基于ARM的STM32那种通过寄存器配置使得中断向量映射到其他区域。所以STM8产生中断时一定是先到0x08000那个区域(程序存贮区)去服务程序地址。所以这个是硬件必然的行为,通过软件在这个入口重新跳转到其他地址是可以的(就如同官方IAP的例程,但这是跳转到程序区,非RAM区)。RAM区提前拷贝好中断服务程序也是可以的。但是这就失去了bootloader的意义了,发生中断还是要经过程序存贮区。 因此,bootloader在RAM中执行程序使用查询方式就可以了,也是最方便的。并且BOOTLOADER本身目标就是通讯+烧录程序, 程序都要改变了,没有必要执行其他功能了。所以做中断重映射到RAM中意义不大了。:)
页: [1]
查看完整版本: STM8S105 IAP中断向量表重定义问题