not_at_all 发表于 2019-12-8 11:23:40

求助,关于GCCAVR扩展中断向量地址问题(已解决)

本帖最后由 not_at_all 于 2019-12-9 19:06 编辑

某款兼容AVR的国产芯片,增加了中断向量。   我在iomxxx.h 头文件增加相关定义,但是中断地址还是没有扩展


// 增加中断定义
#define PCI3_vect_num    27
#define PCI3_vect    _VECTOR(27)/* 引脚电平中断3 */

#define PCI4_vect_num    28
#define PCI4_vect    _VECTOR(28)/* 引脚电平中断4 */

#define TC3_vect_num    29      
#define TC3_vect    _VECTOR(29)/* 定时器3中断*/

#define _VECTORS_SIZE(30 * 4)   // 原来是 _VECTORS_SIZE(26 * 4)
--------------------------------

生成汇编
5c:        0c 94 51 00         jmp        0xa2        ; 0xa2 <__bad_interrupt>
60:        0c 94 51 00         jmp        0xa2        ; 0xa2 <__bad_interrupt>
64:        0c 94 51 00         jmp        0xa2        ; 0xa2 <__bad_interrupt>

00000068 <__ctors_end>:
68:        11 24               eor        r1, r1
6a:        1f be               out        0x3f, r1        ; 63
6c:        cf ef               ldi        r28, 0xFF        ; 255
6e:        d8 e0               ldi        r29, 0x08        ; 8
70:        de bf               out        0x3e, r29        ; 62
72:        cd bf               out        0x3d, r28        ; 61


另外我注释了   _VECTORS_SIZE(30 * 4)   ,也没有报错,这个没起到保留中断地址的作用    无论怎么改,到了0x0068就执行程序初始化

我对比过其他型号的头文件,没找到头绪。还要修改哪里吗?

-----------------------------------------
8楼有一个简便的解决方案

另外,今天我在国产兼容的芯片供应商开发的用GCC的编译器建立一个工程文件编译(客服没有回复,自己动手),找到另外一个简便的解决方案,如下

建立一个.s文件,文件名随便,加入工程中 (类似于amr编译器的启动文件)

.s文件内容如下:

#ifdef __GNUC__

#ifdef __AVR_MEGA__
#define XJMP jmp
#define XCALL call
#else
#define XJMP rjmp
#define XCALL rcall
#endif

      .section .vectors, "ax", @progbits
      .weak __vector_26
      ;.set __vector_26, __bad_interrupt
      XJMP__vector_26
      .weak __vector_27
      ;.set __vector_27, __bad_interrupt
      XJMP__vector_27
      .weak __vector_28
      ;.set __vector_28, __bad_interrupt
      XJMP__vector_28
      .weak __vector_29
      ;.set __vector_29, __bad_interrupt
      XJMP__vector_29
#endif



// 生成如下汇编:

58:      0c 94 59 00         jmp      0xb2      ; 0xb2 <__bad_interrupt>
5c:      0c 94 59 00         jmp      0xb2      ; 0xb2 <__bad_interrupt>
60:      0c 94 59 00         jmp      0xb2      ; 0xb2 <__bad_interrupt>
64:      0c 94 59 00         jmp      0xb2      ; 0xb2 <__bad_interrupt>
#endif
//以下为扩展后的中断向量
      .section .vectors, "ax", @progbits
      .weak __vector_26
      ;.set __vector_26, __bad_interrupt
      XJMP__vector_26
68:      0c 94 00 00         jmp      0      ; 0x0 <__vectors>
      .weak __vector_27
      ;.set __vector_27, __bad_interrupt
      XJMP__vector_27
6c:      0c 94 00 00         jmp      0      ; 0x0 <__vectors>
      .weak __vector_28
      ;.set __vector_28, __bad_interrupt
      XJMP__vector_28
70:      0c 94 00 00         jmp      0      ; 0x0 <__vectors>
      .weak __vector_29
      ;.set __vector_29, __bad_interrupt
      XJMP__vector_29
74:      0c 94 ba 00         jmp      0x174      ; 0x174 <__vector_29>
//下面是程序初始化
00000078 <__ctors_end>:
78:      11 24               eor      r1, r1
7a:      1f be               out      0x3f, r1      ; 63
7c:      cf ef               ldi      r28, 0xFF      ; 255
7e:      d8 e0               ldi      r29, 0x08      ; 8
80:      de bf               out      0x3e, r29      ; 62
82:      cd bf               out      0x3d, r28      ; 61

如果是无效中断,GCC的方案是跳转到某个位置,再复位;而用这种方案,它是直接复位的
000000b2 <__bad_interrupt>:
b2:      0c 94 00 00         jmp      0      ; 0x0 <__vectors>

funnynypd 发表于 2019-12-9 05:35:11

>某款兼容AVR的国产芯片

What it is? LGT?

Himem 发表于 2019-12-9 06:45:58

本帖最后由 Himem 于 2019-12-9 06:49 编辑

gcc最后处理时应该是会根据芯片型号去选一个crtXXXXX.o的模板去link,从这里入手看看,应该是这里没有对应扩展向量的symbol

not_at_all 发表于 2019-12-9 06:48:52

funnynypd 发表于 2019-12-9 05:35
>某款兼容AVR的国产芯片

What it is? LGT?

不必拘泥于哪个芯片这里只讨论技术问题

not_at_all 发表于 2019-12-9 06:51:47

Himem 发表于 2019-12-9 06:45
gcc最后处理时应该是会根据芯片型号去选一个crtXXXXX.o的模板去link,从这里入手看看,应该是这里没有对应 ...

是一个存在的文件吗? 我找找看

Himem 发表于 2019-12-9 07:03:17

本帖最后由 Himem 于 2019-12-9 07:48 编辑

not_at_all 发表于 2019-12-9 06:51
是一个存在的文件吗? 我找找看

以gcc为相对路径.\bin\avr-gcc-5.4.0.exe
的.\avr\lib\crt*.o

随便objdump了一个型号,感觉应该有关系



H:\arduino-1.8.8\hardware\tools\avr\avr\lib\avr5\crtatmega168p.o:   file format elf32-avr
H:\arduino-1.8.8\hardware\tools\avr\avr\lib\avr5\crtatmega168p.o
architecture: avr:5, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File offAlgn
0 .text         000000040000000000000000000000342**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data         000000000000000000000000000000382**0
                  CONTENTS, ALLOC, LOAD, DATA
2 .bss          000000000000000000000000000000382**0
                  ALLOC
3 .debug_abbrev 000005a20000000000000000000000382**0
                  CONTENTS, READONLY, DEBUGGING
4 .debug_info   000005f40000000000000000000005da2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
5 .debug_line   0000001a000000000000000000000bce2**0
                  CONTENTS, READONLY, DEBUGGING
6 .debug_str    00000208000000000000000000000be82**0
                  CONTENTS, READONLY, DEBUGGING
7 .vectors      00000068000000000000000000000df02**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .init0      00000000000000000000000000000e582**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
9 .init2      0000000c000000000000000000000e582**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .init9      00000008000000000000000000000e642**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
11 .note.gnu.avr.deviceinfo 00000040000000000000000000000e6c2**2
                  CONTENTS, READONLY
SYMBOL TABLE:
00000000 l    d.text        00000000 .text
00000000 l    d.data        00000000 .data
00000000 l    d.bss        00000000 .bss
00000000 l    d.debug_abbrev        00000000 .debug_abbrev
00000000 l    d.debug_info        00000000 .debug_info
00000000 l    d.debug_line        00000000 .debug_line
00000000 l    d.debug_str        00000000 .debug_str
00000000 l    d.vectors        00000000 .vectors
00000000 l    d.init0        00000000 .init0
00000000 l    d.init2        00000000 .init2
00000000 l    d.init9        00000000 .init9
00000000 l    d.note.gnu.avr.deviceinfo        00000000 .note.gnu.avr.deviceinfo
00000000 g       .vectors        00000000 __vectors
00000000w      .init0        00000000 __init
00000000w      .text        00000000 __vector_1
00000000 g       .text        00000000 __bad_interrupt
00000000w      .text        00000000 __vector_2
00000000w      .text        00000000 __vector_3
00000000w      .text        00000000 __vector_4
00000000w      .text        00000000 __vector_5
00000000w      .text        00000000 __vector_6
00000000w      .text        00000000 __vector_7
00000000w      .text        00000000 __vector_8
00000000w      .text        00000000 __vector_9
00000000w      .text        00000000 __vector_10
00000000w      .text        00000000 __vector_11
00000000w      .text        00000000 __vector_12
00000000w      .text        00000000 __vector_13
00000000w      .text        00000000 __vector_14
00000000w      .text        00000000 __vector_15
00000000w      .text        00000000 __vector_16
00000000w      .text        00000000 __vector_17
00000000w      .text        00000000 __vector_18
00000000w      .text        00000000 __vector_19
00000000w      .text        00000000 __vector_20
00000000w      .text        00000000 __vector_21
00000000w      .text        00000000 __vector_22
00000000w      .text        00000000 __vector_23
00000000w      .text        00000000 __vector_24
00000000w      .text        00000000 __vector_25
00000000w      .vectors        00000000 __vector_default
000004ffw      *ABS*        00000000 __stack
00000000w      *ABS*        00000000 __heap_end
00000000         *UND*        00000000 main
00000000         *UND*        00000000 exit
00000003w      *ABS*        00000000 __FUSE_REGION_LENGTH__



Disassembly of section .text:

00000000 <__bad_interrupt>:
   0:        0c 94 00 00         jmp        0        ; 0x0 <__bad_interrupt>
                        0: R_AVR_CALL        __vector_default

Disassembly of section .vectors:

00000000 <__vectors>:
   0:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        0: R_AVR_CALL        __init
   4:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        4: R_AVR_CALL        __vector_1
   8:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        8: R_AVR_CALL        __vector_2
   c:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        c: R_AVR_CALL        __vector_3
10:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        10: R_AVR_CALL        __vector_4
14:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        14: R_AVR_CALL        __vector_5
18:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        18: R_AVR_CALL        __vector_6
1c:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        1c: R_AVR_CALL        __vector_7
20:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        20: R_AVR_CALL        __vector_8
24:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        24: R_AVR_CALL        __vector_9
28:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        28: R_AVR_CALL        __vector_10
2c:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        2c: R_AVR_CALL        __vector_11
30:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        30: R_AVR_CALL        __vector_12
34:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        34: R_AVR_CALL        __vector_13
38:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        38: R_AVR_CALL        __vector_14
3c:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        3c: R_AVR_CALL        __vector_15
40:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        40: R_AVR_CALL        __vector_16
44:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        44: R_AVR_CALL        __vector_17
48:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        48: R_AVR_CALL        __vector_18
4c:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        4c: R_AVR_CALL        __vector_19
50:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        50: R_AVR_CALL        __vector_20
54:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        54: R_AVR_CALL        __vector_21
58:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        58: R_AVR_CALL        __vector_22
5c:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        5c: R_AVR_CALL        __vector_23
60:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        60: R_AVR_CALL        __vector_24
64:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
                        64: R_AVR_CALL        __vector_25

Disassembly of section .init2:

00000000 <.init2>:
   0:        11 24               eor        r1, r1
   2:        1f be               out        0x3f, r1        ; 63
   4:        c0 e0               ldi        r28, 0x00        ; 0
                        4: R_AVR_LO8_LDI        __stack
   6:        d0 e0               ldi        r29, 0x00        ; 0
                        6: R_AVR_HI8_LDI        __stack
   8:        de bf               out        0x3e, r29        ; 62
   a:        cd bf               out        0x3d, r28        ; 61

Disassembly of section .init9:

00000000 <.init9>:
   0:        0e 94 00 00         call        0        ; 0x0 <.init9>
                        0: R_AVR_CALL        main
   4:        0c 94 00 00         jmp        0        ; 0x0 <.init9>
                        4: R_AVR_CALL        exit

Himem 发表于 2019-12-9 07:47:43

本帖最后由 Himem 于 2019-12-9 07:53 编辑

大致搞明白了,要下载avr-libc的源码,
修改iomXXX.h中_VECTORS_SIZE定义(在gcrt1.S引用)后重新编译并安装avr-libc即可,或者编译后只替换对应的crtXXXX.o

not_at_all 发表于 2019-12-9 18:38:46

本帖最后由 not_at_all 于 2019-12-9 18:57 编辑

Himem 发表于 2019-12-9 07:47
大致搞明白了,要下载avr-libc的源码,
修改iomXXX.h中_VECTORS_SIZE定义(在gcrt1.S引用)后重新编译并安装a ...

谢谢!

另外,今天我在国产兼容的芯片供应商开发的用GCC的编译器建立一个工程文件编译(客服没有回复,自己动手),找到另外一个简便的解决方案,如下

建立一个.s文件,文件名随便,加入工程中 (类似于amr编译器的启动文件)

.s文件内容如下:

#ifdef __GNUC__

#ifdef __AVR_MEGA__
#define XJMP jmp
#define XCALL call
#else
#define XJMP rjmp
#define XCALL rcall
#endif

        .section .vectors, "ax", @progbits
        .weak __vector_26
        ;.set __vector_26, __bad_interrupt
        XJMP__vector_26
        .weak __vector_27
        ;.set __vector_27, __bad_interrupt
        XJMP__vector_27
        .weak __vector_28
        ;.set __vector_28, __bad_interrupt
        XJMP__vector_28
        .weak __vector_29
        ;.set __vector_29, __bad_interrupt
        XJMP__vector_29
#endif



// 生成如下汇编:

58:        0c 94 59 00         jmp        0xb2        ; 0xb2 <__bad_interrupt>
5c:        0c 94 59 00         jmp        0xb2        ; 0xb2 <__bad_interrupt>
60:        0c 94 59 00         jmp        0xb2        ; 0xb2 <__bad_interrupt>
64:        0c 94 59 00         jmp        0xb2        ; 0xb2 <__bad_interrupt>
#endif
//以下为扩展后的中断向量
        .section .vectors, "ax", @progbits
        .weak __vector_26
        ;.set __vector_26, __bad_interrupt
        XJMP__vector_26
68:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
        .weak __vector_27
        ;.set __vector_27, __bad_interrupt
        XJMP__vector_27
6c:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
        .weak __vector_28
        ;.set __vector_28, __bad_interrupt
        XJMP__vector_28
70:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>
        .weak __vector_29
        ;.set __vector_29, __bad_interrupt
        XJMP__vector_29
74:        0c 94 ba 00         jmp        0x174        ; 0x174 <__vector_29>
//下面是程序初始化
00000078 <__ctors_end>:
78:        11 24               eor        r1, r1
7a:        1f be               out        0x3f, r1        ; 63
7c:        cf ef               ldi        r28, 0xFF        ; 255
7e:        d8 e0               ldi        r29, 0x08        ; 8
80:        de bf               out        0x3e, r29        ; 62
82:        cd bf               out        0x3d, r28        ; 61

如果是无效中断,GCC的方案是跳转到某个位置,再复位;而用这种方案,它是直接复位的
000000b2 <__bad_interrupt>:
b2:        0c 94 00 00         jmp        0        ; 0x0 <__vectors>


以后大家遇到类似问题可以考虑这种方案

-------------------------
题外话,如果改用汇编,GCC就要修改 .inc文件的相关定义
; ***** INTERRUPT VECTORS ***************************
.equ        INT0addr        = 0x0002        ; External Interrupt Request 0
.equ        INT1addr        = 0x0004        ; External Interrupt Request 1
.equ        PCI0addr        = 0x0006        ; Pin Change Interrupt Request 0
.equ        PCI1addr        = 0x0008        ; Pin Change Interrupt Request 0
.equ        PCI2addr        = 0x000a        ; Pin Change Interrupt Request 1
.equ        WDTaddr        = 0x000c        ; Watchdog Time-out Interrupt
.equ        OC2Aaddr        = 0x000e        ; Timer/Counter2 Compare Match A
.equ        OC2Baddr        = 0x0010        ; Timer/Counter2 Compare Match A
.equ        OVF2addr        = 0x0012        ; Timer/Counter2 Overflow
.equ        ICP1addr        = 0x0014        ; Timer/Counter1 Capture Event
.equ        OC1Aaddr        = 0x0016        ; Timer/Counter1 Compare Match A
.equ        OC1Baddr        = 0x0018        ; Timer/Counter1 Compare Match B
.equ        OVF1addr        = 0x001a        ; Timer/Counter1 Overflow
.equ        OC0Aaddr        = 0x001c        ; TimerCounter0 Compare Match A
.equ        OC0Baddr        = 0x001e        ; TimerCounter0 Compare Match B
.equ        OVF0addr        = 0x0020        ; Timer/Couner0 Overflow
.equ        SPIaddr        = 0x0022        ; SPI Serial Transfer Complete
.equ        URXCaddr        = 0x0024        ; USART Rx Complete
.equ        UDREaddr        = 0x0026        ; USART, Data Register Empty
.equ        UTXCaddr        = 0x0028        ; USART Tx Complete
.equ        ADCCaddr        = 0x002a        ; ADC Conversion Complete
.equ        ERDYaddr        = 0x002c        ; EEPROM Ready
.equ        ACIaddr        = 0x002e        ; Analog Comparator
.equ        TWIaddr        = 0x0030        ; Two-wire Serial Interface
.equ        SPMRaddr        = 0x0032        ; Store Program Memory Read

.equ        INT_VECTORS_SIZE        = 52        ; size in words



页: [1]
查看完整版本: 求助,关于GCCAVR扩展中断向量地址问题(已解决)