Eclipse GD32 环境下无法进入中断问题解决

入坑eclipse

由于公司业务与市场环境的一些原因,我们公司使用了GD32的这款国产芯片.在国家的大力支持下,经过这两三年的发展国产芯片无论是性能方面还是稳定性方面都达到了很好的水平.但是芯片配套的IDE发展的却比较缓慢.一般开发STM32与GD的开发人员,都会使用KEIL或IAR.但是经过测试使用,发现编译速度都不太理想.但凡项目源代码改动稍大,都得经过很长时间的编译才能开始调试.而且上述两款软件还都是收费软件.根据网上的搜索,发现使用eclipse与gcc可以完美替代,随后开始亲身测试,但是由于用户很少,所以资料很少,有不少的坑.

环境搭建

根据这篇文章https://blog.csdn.net/weixin_41537558/article/details/126459115的教程,我搭建好了GD32的Eclipse开发环境。

程序测试

根据上述网友的文章搭建好环境后,惊讶的发现,这套开发环境的编译速度让人非常满意.于是兴冲冲的开始进行点灯等测试,发现没有什么问题.

问题解决

但是悲催的是在我使用串口中断时,发现程序无法进入中断,一旦触发中断,程序就会死掉。经过几轮的测试,判断是由于串口服务函数的向量不正确导致的。

随开始查找中断向量表的位置,Eclipse中断向量表,不像Keil一样在.s启动文件中,而是在文件system\src\cmsis\vectors_DEVICE.c中。

/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2014 Liviu Ionescu.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

// ----------------------------------------------------------------------------

#include "cortexm/exception-handlers.h"
#include "gd32f30x_it.h"

// ----------------------------------------------------------------------------

void __attribute__((weak))
Default_Handler(void);

// Forward declaration of the specific IRQ handlers. These are aliased
// to the Default_Handler, which is a 'forever' loop. When the application
// defines a handler (with the same name), this will automatically take
// precedence over these weak definitions
//
// TODO: Rename this and add the actual routines here.

void __attribute__ ((weak, alias ("Default_Handler")))
DeviceInterrupt_Handler(void);

// ----------------------------------------------------------------------------

extern unsigned int _estack;

typedef void
(* const pHandler)(void);

// ----------------------------------------------------------------------------

// The vector table.
// This relies on the linker script to place at correct location in memory.

__attribute__ ((section(".isr_vector"),used))
pHandler __isr_vectors[] =
  { //
    (pHandler) &_estack,                          // The initial stack pointer
        Reset_Handler,                            // The reset handler

        NMI_Handler,                              // The NMI handler
        HardFault_Handler,                        // The hard fault handler

#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
        MemManage_Handler,                        // The MPU fault handler
        BusFault_Handler,// The bus fault handler
        UsageFault_Handler,// The usage fault handler
#else
        0, 0, 0,				  // Reserved
#endif
        0,                                        // Reserved
        0,                                        // Reserved
        0,                                        // Reserved
        0,                                        // Reserved
        SVC_Handler,                              // SVCall handler
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
        DebugMon_Handler,                         // Debug monitor handler
#else
        0,					  // Reserved
#endif
        0,                                        // Reserved
        PendSV_Handler,                           // The PendSV handler
        SysTick_Handler,                          // The SysTick handler
		
        // ----------------------------------------------------------------------
        // DEVICE vectors
        DeviceInterrupt_Handler,                  // Device specific
    // TODO: rename and add more vectors here
    };

// ----------------------------------------------------------------------------

// Processor ends up here if an unexpected interrupt occurs or a specific
// handler is not present in the application code.

void __attribute__ ((section(".after_vectors")))
Default_Handler(void)
{
  while (1)
    {
	  ;
    }
}

// ----------------------------------------------------------------------------

文件中有几个中断函数,但是不完整。随参照GD32 KEIL工程的.s文件中的中断向量表,修改该文件如下:

__attribute__ ((section(".isr_vector"),used))
pHandler __isr_vectors[] =
  { //
    (pHandler) &_estack,                          // The initial stack pointer
        Reset_Handler,                            // The reset handler

        NMI_Handler,                              // The NMI handler
        HardFault_Handler,                        // The hard fault handler

#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
        MemManage_Handler,                        // The MPU fault handler
        BusFault_Handler,// The bus fault handler
        UsageFault_Handler,// The usage fault handler
#else
        0, 0, 0,				  // Reserved
#endif
        0,                                        // Reserved
        0,                                        // Reserved
        0,                                        // Reserved
        0,                                        // Reserved
        SVC_Handler,                              // SVCall handler
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
        DebugMon_Handler,                         // Debug monitor handler
#else
        0,					  // Reserved
#endif
        0,                                        // Reserved
        PendSV_Handler,                           // The PendSV handler
        SysTick_Handler,                          // The SysTick handler
		/* external interrupts handler */
		WWDGT_IRQHandler,                  // 16:Window Watchdog Timer
		LVD_IRQHandler,                    // 17:LVD through EXTI Line detect
		TAMPER_IRQHandler,                 // 18:Tamper through EXTI Line detect
		RTC_IRQHandler,                    // 19:RTC through EXTI Line
		FMC_IRQHandler,                    // 20:FMC
		RCU_CTC_IRQHandler,                // 21:RCU and CTC
		EXTI0_IRQHandler,                  // 22:EXTI Line 0
		EXTI1_IRQHandler,                  // 23:EXTI Line 1
		EXTI2_IRQHandler,                  // 24:EXTI Line 2
		EXTI3_IRQHandler,                  // 25:EXTI Line 3
		EXTI4_IRQHandler,                  // 26:EXTI Line 4
		DMA0_Channel0_IRQHandler,          // 27:DMA0 Channel0
		DMA0_Channel1_IRQHandler,          // 28:DMA0 Channel1
		DMA0_Channel2_IRQHandler,          // 29:DMA0 Channel2
		DMA0_Channel3_IRQHandler,          // 30:DMA0 Channel3
		DMA0_Channel4_IRQHandler,          // 31:DMA0 Channel4
		DMA0_Channel5_IRQHandler,       // 32:DMA0 Channel5
		DMA0_Channel6_IRQHandler,             // 33:DMA0 Channel6
		ADC0_1_IRQHandler,                 // 34:ADC0 and ADC1
		USBD_HP_CAN0_TX_IRQHandler,        // 35:USBD HP and CAN0 TX
		USBD_LP_CAN0_RX0_IRQHandler,       // 36:USBD LP and CAN0 RX0
		CAN0_RX1_IRQHandler,               // 37:CAN0 RX1
		CAN0_EWMC_IRQHandler,              // 38:CAN0 EWMC
		EXTI5_9_IRQHandler,                // 39:EXTI5 to EXTI9
		TIMER0_BRK_IRQHandler,             // 40:TIMER0 Break
		TIMER0_UP_IRQHandler,              // 41:TIMER0 Update
		TIMER0_TRG_CMT_IRQHandler,         // 42:TIMER0 Trigger and Commutation
		TIMER0_Channel_IRQHandler,         // 43:TIMER0 Channel Capture Compare
		TIMER1_IRQHandler,                 // 44:TIMER1
		TIMER2_IRQHandler,                 // 45:TIMER2
		TIMER3_IRQHandler,                 // 46:TIMER3
		I2C0_EV_IRQHandler,                // 47:I2C0 Event
		I2C0_ER_IRQHandler,                // 48:I2C0 Error
		I2C1_EV_IRQHandler,                // 49:I2C1 Event
		I2C1_ER_IRQHandler ,               // 50:I2C1 Error
		SPI0_IRQHandler,                   // 51:SPI0
		SPI1_IRQHandler,                   // 52:SPI1
		USART0_IRQHandler,                 // 53:USART0
		USART1_IRQHandler,                 // 54:USART1
		USART2_IRQHandler,                 // 55:USART2
		EXTI10_15_IRQHandler,              // 56:EXTI10 to EXTI15
		RTC_Alarm_IRQHandler,              // 57:RTC Alarm
		USBD_WKUP_IRQHandler,              // 58:USBD Wakeup
		TIMER7_BRK_IRQHandler,             // 59:TIMER7 Break
		TIMER7_UP_IRQHandler,              // 60:TIMER7 Update
		TIMER7_TRG_CMT_IRQHandler,       // 61:TIMER7 Trigger and Commutation
		TIMER7_Channel_IRQHandler,           // 62:TIMER7 Channel Capture Compare
		ADC2_IRQHandler,                   // 63:ADC2
		EXMC_IRQHandler,                   // 64:EXMC
		SDIO_IRQHandler,                   // 65:SDIO
		TIMER4_IRQHandler,                 // 66:TIMER4
		SPI2_IRQHandler,                   // 67:SPI2
		UART3_IRQHandler,                  // 68:UART3
		UART4_IRQHandler,                  // 69:UART4
		TIMER5_IRQHandler,                 // 70:TIMER5
		TIMER6_IRQHandler,                 // 71:TIMER6
		DMA1_Channel0_IRQHandler,          // 72:DMA1 Channel0
		DMA1_Channel1_IRQHandler,          // 73:DMA1 Channel1
		DMA1_Channel2_IRQHandler,          // 74:DMA1 Channel2
		DMA1_Channel3_4_IRQHandler,        // 75:DMA1 Channel3 and Channel4
        // ----------------------------------------------------------------------
        // DEVICE vectors
        DeviceInterrupt_Handler,                  // Device specific
    // TODO: rename and add more vectors here
    };

完成修改后,发现无法编译通过。原因是这些函数没有定义导致的。于是在gd32f30x_it.h文件中添加定义。在gd32f30x_it.c文件中添加函数实现。然后程序编译成功。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值