Hello guys,
I having trouble in using C++ for STM32 devices using Kiel UVision4 compiler. It seems the codes are compiled and the compiled codes main() thread is working because it can turn on a LED in the trainer board.
The test program is quite simple, it will light up the LED in the main thread and it will blink the another led every 1 second in the RTC interrupt.
However the interrupt routines are not working.
Its even more weird that when i shift to purely C codes the interrupt routines are working fine. The serial port is even working properly.
However due to the complexity of project, we are left with no choice but to use mixed C/C++.
Any idea how to fixed this issue?
Thanks, Jack
// sample main_test.cpp // the result is the LEDs do light up
#define __cplusplus
#include "stm32f10x.h"
#include "header_global_compile_test.h"
#include "stm32f10x_it.c"
int main(void){ char *str;
// No interrupts yet can be serviced from this point until // global interrupts are explicitly enabled.
// System Clocks Configuration RCC_Configuration();
// Initialize chip peripherals init_stm32();
// Interrupts Configuation NVIC_Configuration();
// Sample turn ON LED control_led(LED1, Bit_SET);
// Sample turn ON LED control_led(LED2, Bit_SET);
main_loop:
goto main_loop; }
// Interrupt code section /************************************************** ***************************** * Function Name : RTC_IRQHandler * Description : This function handles RTC global interrupt request. * Input : None * Output : None * Return : None ************************************************** *****************************/ void RTC_IRQHandler(void) { static uint8 led_state;
// Toggle LED4 if (led_state > 0){ control_led(LED4, Bit_SET); led_state = 0; } else { control_led(LED4, Bit_RESET); led_state = 1; }
if (RTC_GetITStatus(RTC_IT_SEC) != RESET){ // Clear the RTC Second interrupt RTC_ClearITPendingBit(RTC_IT_SEC);
#if (gcomc_ENABLE_INTERRUPTS) // increment system time sys_time_increment(); #endif
// Wait until last write operation on RTC registers has finished RTC_WaitForLastTask(); } }
// NVIC /************************************************** ***************************** * Function Name : NVIC_Configuration * Description : Configures Vector Table base location. * Input : None * Output : None * Return : None ************************************************** *****************************/ void NVIC_Configuration(void){ NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif
/* Configure one bit for preemption priority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// Enable the RTC Interrupt NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori ty = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
// Enable the USART2 Interrupt NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori ty = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
}
// The purely C codes only seemed to work.
IDE-Version: µVision V4.03 Copyright (c) Keil Elektronik GmbH / Keil Software, Inc. 1995 - 2009
Tool Version Numbers: Toolchain: RealView MDK-ARM Version: 4.10 Toolchain Path: BIN40\ C Compiler: Armcc.Exe V4.0.0.728 Assembler: Armasm.Exe V4.0.0.728 Linker/Locator: ArmLink.Exe V4.0.0.728 Librarian: ArmAr.Exe V4.0.0.728 Hex Converter: FromElf.Exe V4.0.0.728 CPU DLL: SARMCM3.DLL V4.10 Dialog DLL: DARMSTM.DLL V1.45b
make sure when you use C++ to use extern "C" when you need to Guarantee the exact name of a function.
extern "C" void RTC_IRQHandler(void)
This function is probably defined as WEAK somewhere so you do not get an error when the name is wrong because of this, but if you do not put extern "C" before the function, it is not the one that will be called - it will call the WEAKly defined one.
You certainly do have a choice!
It is entirely possible to make very large and complex projects using only 'C' - certainly within the scope of an STM32.
In fact, the (vast?) majority of projects at this size of microcontroller are still written in 'C'.
You may well be able to gain advantage with C++ - but you need to weigh that against the fact that you will be in the minority and, therefore, have less opportunities for support.
Just something to consider...
Thanks guys for this response. Yeah its almost easy to code complex projects in C. However, i find it very fast to develop using C++. Most importantly the design is highly documented using UML modeling. So C++ comes handy..
That doesn't prevent implementation in 'C'
Oops.. I tested it. with extern "C" .. interrupts still dead...
I use C++ just fine with the STM32 - every interrupt routine is defined in a .cpp file. You should continue to look down the path of miss named functions (Nothing outside of C++ knows of the names of C++ items. You MUST declare them as extern "C" if you want outside viability.) I am almost 100% sure this is where your issue is. You will need to understand this if you want to use C++ on the STM32. You will need to be able to find these issues, since no one else is going to be able to understand the exact way you have gotten it wrong.
Thats it.. my interrupts are inside a C file.. with externs.. :-)