OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6527|回复: 5

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

[复制链接]

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2014-5-25
在线时间
18 小时
发表于 2016-7-10 03:12:21 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 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变量所在地址与其内容的比较
无标题.png

最佳答案

查看完整内容[请看2#楼]

时隔多日再次回到这里,也不知道当时是不是脑抽了,这都没想明白。 0x82 0x9004 是一个语句,要跳到新建的中断向量表处,新建的中断向量表有0x82 IRQHander。 当然是要跳到0x9004了,0x9004刚好就是 0x82 IRQHander 这个语句中0x82的地址。 当时脑抽想着要跳到0x9005才对。。。然而这个0x9005不过是中断函数的地址的地址,而非中断中断函数的地址。。。当然了,也可以直接跳到中断函数的地址,毕竟中断函数地址的地址是已知的 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2014-5-25
在线时间
18 小时
 楼主| 发表于 2016-7-10 03:12:22 | 显示全部楼层
本帖最后由 stopshooting 于 2016-7-28 16:01 编辑

时隔多日再次回到这里,也不知道当时是不是脑抽了,这都没想明白。
0x82  0x9004 是一个语句,要跳到新建的中断向量表处,新建的中断向量表有0x82 IRQHander。
当然是要跳到0x9004了,0x9004刚好就是 0x82  IRQHander 这个语句中0x82的地址。
当时脑抽想着要跳到0x9005才对。。。然而这个0x9005不过是中断函数的地址的地址,而非中断中断函数的地址。。。当然了,也可以直接跳到中断函数的地址,毕竟中断函数地址的地址是已知的,不过还没有试过。
回复

使用道具 举报

8

主题

533

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2828
金钱
2828
注册时间
2016-5-13
在线时间
178 小时
发表于 2016-7-22 14:59:23 | 显示全部楼层
0x8000是bootloader开始执行的flash地址,0x9000是用户app的固件起始地址。
(0x9000可以修改的,我用的就是0xA000,没办法bootloader代码有些大)
因为用户app固件地址是从0x9000开始的,所以中断向量表要重定向到0x9000 。

在bootloader里不能使用中断处理函数,因为一中断就跑0x9000里去了,会死机的。
bootloader里串口接收数据就用while在哪里死等,没办法中断向量表给用户app了,没有处理函数呀,如下:
void Transmit(u8 Data){
//wait for Tx empty
        sr = UART1->SR;
  while(!(sr & 0x80/*TxNE*/)) sr = UART1->SR;
  //send data
   UART1->DR = Data;
  //wait for transmission complete
  sr = UART1->SR;
  while(!(sr & 0x40/*TxNE*/)) sr = UART1->SR;

u8 Receive_while(u8* ReceivedData){
  //wait for Rx full
        sr = UART1->SR;
  while(!(sr & 0x20 /*RXNE*/)) sr = UART1->SR;
  //check if overrun or parity error
        if((sr & 0x08/*OR*/)||(sr & 0x01/*PE*/))
  {
    //receive data to clear error
    *ReceivedData = UART1->DR ;
    //send NACK to host
    //Transmit(NACK);
    //and return error
    return 0;
  }
  //receive data
  *ReceivedData = UART1->DR;
  //and return no error
  return 1;
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

6

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
87
金钱
87
注册时间
2011-3-22
在线时间
3 小时
发表于 2016-9-1 10:04:19 | 显示全部楼层
电脑小白 发表于 2016-7-22 14:59
0x8000是bootloader开始执行的flash地址,0x9000是用户app的固件起始地址。
(0x9000可以修改的,我用的就 ...

bootload里不能中断,如果是usb升级怎么办?
回复

使用道具 举报

53

主题

167

帖子

0

精华

高级会员

Rank: 4

积分
839
金钱
839
注册时间
2016-8-23
在线时间
116 小时
发表于 2016-9-1 12:01:05 | 显示全部楼层
看起来好复杂啊,不懂
天道酬勤
回复

使用道具 举报

8

主题

533

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2828
金钱
2828
注册时间
2016-5-13
在线时间
178 小时
发表于 2016-9-1 15:43:41 | 显示全部楼层
dgdzov 发表于 2016-9-1 10:04
bootload里不能中断,如果是usb升级怎么办?

stm8没有这么强大吧,有usb通信接口? stm32见过有自带的usb接口,stm8上没有吧。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-9-29 05:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表