入坑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文件中添加函数实现。然后程序编译成功。