替代STM32的GD32,替代KEIL的Eclipse配置---连载1
前言
GD32替代STM32原因:
(1)前段时间stm32系列芯片涨价厉害,只能用国产替代,管脚兼容的并且做的不错的只有兆易创新的GD32;
(2)国产化是个趋势,最好在stm32禁止之前替代掉,符合现在的困境。
Eclipse替代KEIL原因:
(1)KEIL和IAR都是商业软件,用的久了就会收钱,没有办法的事情,关键是还很贵;
(2)还是国产化的原因,将来软件不让用了,你也是干着急。
所以:STM32替换成了国产的GD32,KEIL替换成了开源的eclipse。
不用ST自带的IDE原因:
(1)用途有限。ST自带的IDE(编译软件)用起来也很方便,但是仅仅支持ST的芯片,如果换个芯片还是卡脖子。
(2)ST自带的IDE也是基于eclipse的,所以抱薪救火不如釜底抽薪,直接用开源的得了。加上eclipse在LINUX上也能用,将来WINDOWS不让用了,也可以搞定这个东西。
写文章的原因:
(1)网上搜寻到的GD32的配置eclipse的文章很少,能搜寻到的都是直接配置的,不能解决其他芯片问题,比如配置GD32F407,做一次得找一次文件,不如直接釜底抽薪,修改底层文件,将修改变为一种普遍使用的方法。
(2)配置过程中会遇到很多问题,可以和小伙伴们交流。也希望小伙伴关注下以前文章的公众号。电力电子嵌入式,图片没有办法发上来,希望小伙伴们能翻看以前的文章,加下关注,以后还会有后续文章。
在下面这篇文章里有具体的图片,可以关注一波:QT串口动态实时显示大量数据波形曲线(四)========“界面的美化与处理”_透明的光的博客-CSDN博客_qt实时显示曲线
第一章:处境
替代过程必须将以前的代码再做一次,但是还是需要有改动的地方。内部东西都不一样,基于的东西也不一样,所以思维方式还是得改变。STM32用久了,KEIL用久了都会产生依赖,感觉这个东西不错,用着还方便。但是网上说其他的用着也不错,感觉仅仅是习惯问题。改变习惯也是不得已的事情,充满无奈和心酸。
STM32替代成GD32,这个过程还是比较舒服点,毕竟上层软件还是KEIL。用的方式还是一样的。但是将编译软件替换掉,这个就比较累。
GD32写的程序还是比较人性化,什么东西又封装了一层,调用起来还算可以。这部分前段时间已经做了一下,出来的东西还是能用的。
其实STM32的程序直接烧写到GD32上也没什么大的问题,已经试验过了。但是就是害怕将来某个时间点出现不知道的BUG,那就不好解决了。
至于eclipse替代KEIL这个事情,现在正在做,估计要花费2周的时间,反正以最快的速度做出来吧。弄一次估计就没啥问题了,并且将来用其他芯片的时候也可以直接怼上去。
不过真是难。一点一点的做吧。
第二章:STM和GD文件架构
原因:eclipse的文件架构以前没见过,所以必须对每个东西都得很熟悉才行。
下面分别介绍下KEIL下的STM32和GD32的架构,然后再介绍下eclipse下的架构。
注意1:架构都是以103为硬件基础,至于407的,看了下,都用了HAL库,这个等103的基础版的弄完了,再给介绍下。
注意2:eclipse的安装和配置,这个东西等做完之后再说,我试着在不同的电脑上装了2次,都可以用,所以按照介绍的步骤应该没什么问题。需要的小伙伴可以关注下,等程序做完之后就写这篇文章。这个东西属于不定因素,按照网上的教程,有的说不行,有的说行。所以按照我自己的步骤也真是不一定能装上。所以还得需要小伙伴自己努力的装下软件,并且配置好能正确编译的配置。
第1节:STM32F103文件架构
STM32的文件架构非常固定。其中红色部分是.h文件,蓝色部分是.C文件。
包含四部分:
(1)main文件,当然这里还会包含自己写的全部文件;
(2)内核文件,这部分会是cm3 或者cm4,这个看你用的什么片子;
(3)stm32f103对应的配置文件,一共有四个;
(4)103的库函数,在main文件夹里自己写的文件就是调用了这部分库函数。
还有一个文件不属于任何部分,就是.s文件。这个文件很重要,咱们后面再说。
第2节:GD103文件架构
GD32的文件架构和STM32的类似。
也包含四部分:
(1)main文件,当然这里还会包含自己写的全部文件;再有GD32独有的systick文件,这个在编程的时候用不到,只是在程序初始化的时候用到,不用管。
(2)内核文件,这部分会是cm3 或者cm4,这个看你用的什么片子;里面还包含了内核需要的其他文件,怎么调用也不用管,放进去就好。
(3)GD32f103对应的配置文件,一共有六个;功能和STM的一样,只是多了eval文件,这个文件是自己配置用的,用到了就配置进去,不用就不用配置。这点比较人性化,自己编写的东西都放到一起,将来修改的时候就只看这一个文件就行。
(4)103的库函数,在main文件夹里自己写的文件就是调用了这部分库函数。
第3节:对比
对比两个芯片用的文件,大体上类似,并且文件里面的内容也是大同小异。只不过GD32用的函数又在STM32的基础上包含了一层。更加的符合使用习惯。
编写心得:GD32程序编写开始时会不太习惯,用的多了就感觉编写的还是很不错的。只不过是和STM32的不太一样罢了。用的多了就知道多香了!这个还是看自己的习惯,每个人有不同的感受,我自己的感觉是还挺好。
第4节:启动文件.s
重点介绍下这个文件,因为在移植到eclipse的时候,这个文件挺重要,并且挺麻烦。这部分STM32和GD32是一样的,小伙伴可以自己逐行去看看。
Stack_Size EQU 0x00000400AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>Heap_Size EQU 0x00000200AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
先是堆和栈的大小设置,这个是每个软件必须要定义的。至于多少,看自己心情,别超出范围就行了,当然也不能太小,太小了不够自己用的,会出错的。
; Vector Table Mapped to Address 0 at ResetAREA RESET, DATA, READONLYEXPORT __VectorsEXPORT __Vectors_EndEXPORT __Vectors_Size__Vectors DCD __initial_sp ; Top of StackDCD Reset_Handler ; Reset HandlerDCD NMI_Handler ; NMI HandlerDCD HardFault_Handler ; Hard Fault HandlerDCD 0 ; ReservedDCD PendSV_Handler ; PendSV HandlerDCD SysTick_Handler ; SysTick Handler; External InterruptsDCD WWDG_IRQHandler ; Window WatchdogDCD PVD_IRQHandler ; PVD through EXTI Line detectDCD TAMPER_IRQHandler ; TamperDCD RTC_IRQHandler ; RTCDCD FLASH_IRQHandler ; FlashDCD RCC_IRQHandler ; RCCDCD EXTI0_IRQHandler ; EXTI Line 0DCD EXTI1_IRQHandler ; EXTI Line 1DCD EXTI2_IRQHandler ; EXTI Line 2DCD EXTI3_IRQHandler ; EXTI Line 3DCD EXTI4_IRQHandler ; EXTI Line 4
然后就是中断的端口,也就是中断向量表。用不准确的话说也就是自己系统自己的中断的地址。这部分每个芯片不一样,有中断多的,有中断少的,不过中断的端口就放在这里。
; Reset handler
Reset_Handler PROCEXPORT Reset_Handler [WEAK]IMPORT __mainIMPORT SystemInitLDR R0, =SystemInitBLX R0LDR R0, =__mainBX R0ENDP
然后是启动引导,先系统的初始化,然后进入main函数。这部分知道就行,知道程序是从这里进,然后才到自己看到的while(1)那里的main函数。
; Dummy Exception Handlers (infinite loops which can be modified)NMI_Handler PROCEXPORT NMI_Handler [WEAK]B .ENDP
HardFault_Handler\PROCEXPORT HardFault_Handler [WEAK]B .ENDPPendSV_Handler PROCEXPORT PendSV_Handler [WEAK]B .ENDP
SysTick_Handler PROCEXPORT SysTick_Handler [WEAK]B .ENDPDefault_Handler PROCEXPORT WWDG_IRQHandler [WEAK]EXPORT PVD_IRQHandler [WEAK]EXPORT TAMPER_IRQHandler [WEAK]EXPORT RTC_IRQHandler [WEAK]EXPORT FLASH_IRQHandler [WEAK]EXPORT RCC_IRQHandler [WEAK]EXPORT EXTI0_IRQHandler [WEAK]EXPORT EXTI1_IRQHandler [WEAK]EXPORT EXTI2_IRQHandler [WEAK]EXPORT EXTI3_IRQHandler [WEAK]EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]EXPORT USART3_IRQHandler [WEAK]EXPORT EXTI15_10_IRQHandler [WEAK]EXPORT RTCAlarm_IRQHandler [WEAK]EXPORT USBWakeUp_IRQHandler [WEAK]WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_IRQHandler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandlerCAN1_SCE_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
再然后是弱定义。这部分的作用呢,类似于前面声明了中断函数,后面来了函数的主体,也就是.h里面先声明下,然后.c里面的函数主体。当然这里的弱定义的意思就是:中断函数给你写好了,你自己想加自己的中断就加,不想加也不会报错,因为已经先定义了一下函数主体。
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************IF :DEF:__MICROLIB EXPORT __initial_spEXPORT __heap_baseEXPORT __heap_limitELSEIMPORT __use_two_region_memoryEXPORT __user_initial_stackheap__user_initial_stackheapLDR R0, = Heap_MemLDR R1, =(Stack_Mem + Stack_Size)LDR R2, = (Heap_Mem + Heap_Size)LDR R3, = Stack_MemBX LR
最后是堆和栈的开始点,和上面main的入口一样,定位到堆和栈的开始,并且还计算着大小之类的,别使用超了。
总结下启动文件的内容:(1)堆和栈的大小设定,指向堆和栈的开始;(2)程序所有的中断定义和中断主体;(3)程序main的开始入口,也就是启动入口。
至于后面怎么运行的不用管,只看到c代码就行,至于怎么编译成汇编,然后再怎么编译成01代码,然后怎么再在单片机里面跑的不用管,只需要知道顶层这样设计就好。
注意:这里强调一点,不用管下层怎么弄的,上层这样弄,下层就会这样执行。并且就是这个格式。其他格式行不行,行,但是别人这样做的,大家都这样做了,咱们就按照这个格式来。就类似于电视,知道开关机、选台就行了,至于信号怎么传输的,都不用管,别人做好了,就可以用。自己只需要接好线,接好电源,然后点遥控器就行。
第三章:ECLIPSE文件架构
第1节:文件架构
采用eclipse生成STM32F10x的文件架构如下:
一共分为5个部分:
(1)与上章介绍的共同的部分,main文件,103库函数文件,103系统文件,core相同文件;
(2)core不同部分,有cmsisdevice,cmsisgcc,还有另外三个core的文件,这部分只是系统的文件,可以不用涉及。具体里面也看不懂,知道是内核文件就好。
(3)内核调用文件:-cxx,-exit,-sbrk,-startup,-syscalls,assert这几个文件,这部分和core是配套的,在其他函数中也会调用,里面内容看不懂,也不用管。
(4)其余不同文件:三个ld文件,verctor_stm32f10x,_initializehardware,_resethardware,exceptionhander;
(5)debug和跟踪文件:semihosting和trace文件。这几个文件是调试和断点用的,这部分作用还不知道,网上说是这样。目前还不太清楚具体作用,当删除之后对原有编程没有影响,应该就是debug或者数据传输用的。可以不用管。
这5个部分的第1部分可以参看前面的介绍,都是原有的程序,第235部分都是不用管的程序,其中第4部分需要很注意。这部分和上一章介绍的.s文件有很大关联,所以必须单独介绍,并且这部分是修改程序必须看懂的程序,所以需要和小伙伴们分享下。
第2节:不同启动文件对比
只介绍前文的第4个部分,先看vector文件:
void __attribute__((weak))
Default_Handler(void);void __attribute__ ((weak, alias ("Default_Handler")))
WWDG_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
PVD_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
TAMPER_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
RTC_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
FLASH_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
RCC_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
EXTI0_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
EXTI1_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
EXTI2_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
EXTI3_IRQHandler(void);
void __attribute__ ((weak, alias ("Default_Handler")))
EXTI4_IRQHandler(void);(pHandler) &_estack, // The initial stack pointerReset_Handler, // The reset handlerNMI_Handler, // The NMI handlerHardFault_Handler, // The hard fault handlerBusFault_Handler, // The bus fault handlerPendSV_Handler, // The PendSV handlerSysTick_Handler, // The SysTick handlerWWDG_IRQHandler, // Window WatchDogPVD_IRQHandler, // PVD through EXTI Line detectionTAMPER_IRQHandler, // Tamper through the EXTI lineRTC_IRQHandler, // RTC Wakeup through the EXTI lineFLASH_IRQHandler, // FLASHRCC_IRQHandler, // RCCEXTI0_IRQHandler, // EXTI Line0EXTI1_IRQHandler, // EXTI Line1EXTI2_IRQHandler, // EXTI Line2EXTI3_IRQHandler, // EXTI Line3EXTI4_IRQHandler, // EXTI Line4
这个文件和前面.s文件里面的中断向量弱定义对应,所以如果需要修改中断种类和数量的话,必须从这里修改。
再看看resethardware文件:
extern void
__attribute__((noreturn))
NVIC_SystemReset(void);void
__reset_hardware(void);void
__attribute__((weak,noreturn))
__reset_hardware()
{NVIC_SystemReset();
}
这部分应该是对应中断向量表的指向,也就是中断初始化执行入口。
再看看initializehardware文件:
extern unsigned int __vectors_start;// Forward declarations.void
__initialize_hardware_early(void);void
__initialize_hardware(void);void
__attribute__((weak))
__initialize_hardware_early(void)
{// Call the CSMSIS system initialisation routine.SystemInit();
}void
__attribute__((weak))
__initialize_hardware(void)
{// Call the CSMSIS system clock routine to store the clock frequency// in the SystemCoreClock global RAM location.SystemCoreClockUpdate();
}
这部分是初始化系统的,也就是是执行main函数的入口,里面的函数和前面的.s是对应起来的,先初始化硬件,然后再进入系统的入口:systeminit,从这个地方进入main程序。
再看看exceptionhandler文件:
extern void
__attribute__((noreturn,weak))
_start (void);
void __attribute__ ((section(".after_vectors"),noreturn))
Reset_Handler (void)
{_start ();
}void __attribute__ ((section(".after_vectors"),weak))
NMI_Handler (void)
{
#if defined(DEBUG)__DEBUG_BKPT();
#endifwhile (1){}
}
void __attribute__ ((section(".after_vectors"),weak,naked))
HardFault_Handler (void)
{asm volatile(" tst lr,#4 \n"" ite eq \n"" mrseq r0,msp \n"" mrsne r0,psp \n"" mov r1,lr \n"" ldr r2,=HardFault_Handler_C \n"" bx r2": /* Outputs */: /* Inputs */: /* Clobbers */);
}
里面具体定义了中断函数,其中都是一些汇编的语言,具体的对比了eclipse生成的其他芯片的文件,发现这部分都是一样的,应该是向量表的地址都一样。并且里面有很多sem文件的函数,应该是发生错误的时候能在上位机的地方看到错误。
然后看三个ld文件:
section文件:
__stack = ORIGIN(RAM) + LENGTH(RAM);_estack = __stack; /* STM specific definition */__Main_Stack_Size = 1024 ;PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;__Main_Stack_Limit = __stack - __Main_Stack_Size ;PROVIDE ( _Heap_Begin = _end_noinit ) ;
PROVIDE ( _Heap_Limit = __stack - __Main_Stack_Size ) ;
对比下,这部分定义了堆和栈的大小,已经文件的存储位置,里面有code段,data段还有bss段的位置,具体的位置全部都是全局变量,具体变量的值在mem的ld文件里,具体:
MEMORY
{RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20KCCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 0FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128KFLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0MEMORY_ARRAY (xrw) : ORIGIN = 0x00000000, LENGTH = 0
}
里面定义了ram和其他文件的存储地址等,这部分是在KEIL里面通过魔法棒定义的,里面有内存分配的一个文件,通过下载器下载进去的。
第3节:总结
通过上述介绍,小伙伴应该对eclipse产生的文件有个大概的了解,其文件也是一一对应的,只不过放到了不同的c文件和h文件里。
第四章:修改原则
现有条件:
已做:将STM32F103的程序修改为STM32F407的HAL库程序。
步骤:(1)生成103程序;(2)删除不用函数和文件夹;(3)407文件代替103文件;(4)编译;(5)下载。
结果:认真点话可以将103的程序修改成407的程序,编译没有任何错误和警告,下载到407开发板中可以运行,具体的灯可以中断点亮,串口可以中断发送。
问题:观察波形发现了问题。串口发送会影响灯的翻转,这个问题有点大啊!不知道是不是串口发送的HAL库发送的时候必须等发送完才能出中断,如果是的话就没啥问题。
编写程序:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim==(&TIM3_Handler)){ LED0_Toggle;}if(htim==(&TIM4_Handler)){ gnUartTxTemp1++;HAL_UART_Transmit(&UART1_Handler, &gnUartTxTemp1, 1, 1000);}
}
按照程序的话,两个定时器中断执行时间都很短,串口发送不应该影响灯的翻转,但是现在影响了,不知道是什么问题。到时候还的分析下。
原则:
(1)ST103移植到ST407,成功的话说明移植地方正确;
(2)ST103移植到GD103,看看这个能不能成功,如果能成功证明修改的地方正确;
(3)ST103移植到STH730,和ST103移植到STH750,如果都可以移植,证明方法正确,可以总结出移植点。
(4)换其他厂家的芯片,看是否能移植成功。
(5)后续使用LINUX虚拟机上的eclipse,初步摆脱windows的平台。
第五章:结论与展望
涉及到一个新的东西,学习和修改都是需要勇气的。其实移植前我也很害怕,担心自己做不成功,并且移植本身就是需要在错误上修正错误,这个过程很煎熬。但是没有办法的事,总需要去接受新的东西。现在做到的程度仅仅是移植差不多的STM系列的东西,真的到GD上面不知道会出现什么情况,但愿生活对我好点,能快点移植出来。
正在做这方面的小伙伴可以持续关注,后续文章将会陆续发出。
替代STM32的GD32,替代KEIL的Eclipse配置---连载1相关推荐
- 用GD32替代STM32,是什么体验?
一. 前言 大家好,我是张巧龙,最近ST涨价厉害,单位的物料成本也是频频告急.网上一直传,什么完美替代,直接就能用.说不心动吧,那是假的. 看到嵌入式ARM这篇关于GD32替代STM32的文章,特此分 ...
- STM32的国产替代,盘点下我知道的国产MCU
电子元件涨价和缺货是多少嵌入式工程师的痛,一年内上游厂家晶圆产能告急能有数十次之多.而MCU更是重灾区,且不说国内有超75%的市场都是被国外产品占据,就是本国内的代理和供应商也是漫天要价,而交期更是长 ...
- 用国产CH32替代STM32,快来试试看!
/* 作者: 罗冰 https://blog.csdn.net/luobing4365 */ 随着芯片价格疯涨,项目的不可控性越来越大.特别是价格方面,达到了无法想象的地步了. 按我的记忆,之前项目 ...
- 除了GD!这11个国产品牌也能替代STM32!-道合顺大数据Infinigo
众所周知,GD是STM32国产替代最成功的一家公司.在2013年,GD选择大热的Cortex-M3作为切入口,如今GD32 MCU家族拥有GD32F103主流型.GD32F101基本型.GD32F10 ...
- STM32 MCU的替代产品
MCU是各种电子产品的核心.基于ARM的MCU因为体积小.低功耗.低成本.高性能:指令执行速度更快,指令长度固定:很好的兼容8位/16位器件:供应商众多,占据了当前MCU市场大部分的份额. 基于ARM ...
- 国产替代STM32的MCU厂家
---个人用过中科芯的CSK32F103RCT6,软件硬件都不需要修改,直接替代. 众所周知,GD是STM32国产替代最成功的一家公司.在2013年,GD选择大热的Cortex-M3作为切入口,如今G ...
- 32位ARM核单片机XL32F003开发板可替代STM32、华大、GD,脚位兼容
XL32F003开发板使用 XL32F003 作为主控制器.该开发板为采用 32 位 ARM® Cortex® -M0+ CPU 内核的单片机芯片,提供了一个简易的硬件开发环境.开发板使用 mini- ...
- 国产单片机替代-CH32替代STM32
(请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365) 国产单片机替代-CH32替代STM32 1 固件下载 2 代码编写 2.1 STM32的USB- ...
- STM32、GD32、ESP32 的区别
STM32.GD32.ESP32都是32位的单片机,本文对比其中的区别. STM32:意法半导体在2007年6月11日发布的产品,基于ARM-CORTEX内核. GD32:兆易创新公司 2013 年发 ...
最新文章
- 人工智能AI Boosting HMC Memory Chip
- 二叉搜索树-创建最小高度树(递归)
- Oracke nls Parameters
- SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)
- java 二进制as_Java中的二进制文本
- 无限循环小数四则运算_狐狸笔记 | 0.999999无限循环下去,就等于1吗?
- JavaScript数值类型及变量
- linux数据库实例开机启动,Oracle数据库之Linux下实现Oracle数据库单实例开机自启动设置...
- 求剁手的分享,如何简单开发js图表
- Windows系统安装教程
- Window phone7 修改程序语言
- 西威变频器avo下载调试资料_图解变频器的应用与接线,电气工程师必备
- 第六篇:A133 用DragonSN工具刷SN号,MAC地址细节问题
- 九宫格C语言递归程序,九宫格程序代码 共享并希望大家多提意见
- 【3D动态脑图制作软件】万彩脑图大师教程 | 将思维导图输出到云服务
- OSPF之Stub区域
- MFC中在界面上添加背景图片的方法
- 【C#上位机】chart动态更新数据
- STM32内存分布学习
- 横版格斗——技能动作概念