| Author |
Message
|
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#31
07 Feb 2012 23:45 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Ogólnie rzecz biorąc udało mi się skonfigurować buttona tak, żeby działał na przerwaniach i timerze. Ale coś zaś musiałem fundamentalnego skopać i wywala HardFault. Tym razem nie mogę uruchomić SysTicka.
int main(void) { volatile uint32_t count, count_max = 1000000; system_init(); pll_start(CRYSTAL, FREQUENCY); SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); if (SysTick_Config(14400000)) { while(1); // W razie bledu petla nieskonczona } LED_bb = 1; while (1) { for (count = 0; count < count_max; count++); // delay LED2_bb ^= 1; } }
W system init jest gpio init. A w nim:
void gpio_init(void) { RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; RCC->APB2ENR |= RCC_APB2ENR_IOPEEN; gpio_pin_cfg(LED_GPIO, LED_pin, GPIO_CRx_MODE_CNF_OUT_PP_10M_value); gpio_pin_cfg(LED2_GPIO, LED2_pin, GPIO_CRx_MODE_CNF_OUT_PP_10M_value); }
No i obsługa ticka:
Code C (LoadRunner) - [expand] void SysTick_Handler(void) { LED_bb ^= 1; }
Nic więcej w zasadzie nie ma. Zastanawiam się, czy przy zmianie jakichś rejestrów nie muszę chwilę odczekać?
|
|
| Back to top |
|
 |
gaskoin Poziom 22

Joined: 02 Jun 2010 Posts: 2194 Location: Bytom
|
#32
08 Feb 2012 00:34 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Pokaż Twój makefile i skrypt linkera
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#33
08 Feb 2012 02:51 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Ok, coś jest nie tak.
Przede wszystkim systick działa na trybie optymalizacji O1 i O2. Bez zmiany kodu.
Na O0 od razu jest hard fault. Ale nie występuje na żadnej linijce kodu. Nie wchodzi do przerwania i wywala od razu błąd. EDIT: Działa w momencie kiedy wywaliłem inicjalizacje:
NVIC_Init(&NVIC_InitStructure);
A w to miejsce dałem:
NVIC->ISER[EXTI0_IRQn >> 0x05] = 1 << EXTI0_IRQn;
Ale sytuacja jest taka sama jak w przypadku O1/O2, czyli:
Włączyłem O2. Musiałem przy tym zaktualizować bibliotekę core_cm3.h i .c ale niestety przerwania nie działają. Wchodzi i skacze po nich i już z nich nie wychodzi!
void EXTI0_IRQHandler(void) { if (((EXTI->PR & EXTI_Line0) != (uint32_t)RESET) && ((EXTI->IMR & EXTI_Line0) != (uint32_t)RESET)) //EXTI_GetITStatus { EXTI->PR = EXTI_Line0; //EXTI_ClearITPendingBit //włączamy przerwanie zegara NVIC->ISER[TIM2_IRQn >> 0x05] = 1 << TIM2_IRQn; //wyłączamy przerwanie buttona NVIC->ICER[EXTI0_IRQn >> 0x05] = 1 << EXTI0_IRQn; //uruchamiamy timer TIM2->CNT = 0; TIM2->CR1 |= TIM_CR1_CEN; // oraz jego przerwania TIM2->DIER |= TIM_IT_CC1; //zmieniamy led LED3_bb ^= 1; } } void TIM2_IRQHandler(void) { if ( ((TIM2->SR & TIM_IT_CC1) != (uint16_t)RESET) && ((TIM2->DIER & TIM_IT_CC1) != (uint16_t)RESET) ) //TIM_GetITStatus { TIM2->SR = ~TIM_IT_CC1; //TIM_ClearITPendingBit LED4_bb ^= 1; //wyłączamy przerwanie zegara NVIC->ICER[TIM2_IRQn >> 0x05] = 1 << TIM2_IRQn; //włączamy przerwanie buttona NVIC->ISER[EXTI0_IRQn >> 0x05] = 1 << EXTI0_IRQn; // wylacz licznik TIM2->CR1 &= ~TIM_CR1_CEN; // oraz jego przerwanie TIM2->DIER &= ~TIM_IT_CC1; } }
Natomiast w trybie O0 błąd Hard Fault występuje tuż po konfiguracji NVIC dla buttona:
void ButtonInit(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOA clock */ RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPFEN; /* Configure PA.00 pin as input floating */ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // GPIO_Init(GPIOA, &GPIO_InitStructure); gpio_pin_cfg(GPIOA, GPIO_Pin_0, GPIO_CRx_MODE_CNF_IN_PULL_U_D_value); /* Enable AFIO clock */ RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; /* Connect EXTI0 Line to PA.00 pin */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); /* Configure EXTI0 line */ EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); /* Enable and set EXTI0 Interrupt to the lowest priority */ NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); BTN_pullup = 1; }
Dokładnie na tej linijce:
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
Wewnątrz procedury NVIC_Init.
Mój makefile. Poza optymalizacją i kodem procesora niczego nie ruszałem.
#=============================================================================# # ARM makefile # # author: Freddie Chopin, http://www.freddiechopin.info/ # last change: 2012-01-07 # # this makefile is based strongly on many examples found in the network #=============================================================================# #=============================================================================# # toolchain configuration #=============================================================================# TOOLCHAIN = arm-none-eabi- CXX = $(TOOLCHAIN)g++ CC = $(TOOLCHAIN)gcc AS = $(TOOLCHAIN)gcc -x assembler-with-cpp OBJCOPY = $(TOOLCHAIN)objcopy OBJDUMP = $(TOOLCHAIN)objdump SIZE = $(TOOLCHAIN)size RM = cs-rm -f #=============================================================================# # project configuration #=============================================================================# # project name PROJECT = stm32_blink_led # core type CORE = cortex-m3 # linker script LD_SCRIPT = STM32F103xB_rom.ld # output folder (absolute or relative path, leave empty for in-tree compilation) OUT_DIR = out # C++ definitions (e.g. "-Dsymbol_with_value=0xDEAD -Dsymbol_without_value") CXX_DEFS = -DSTM32F10X_HD # C definitions C_DEFS = -DSTM32F10X_HD # ASM definitions AS_DEFS = # include directories (absolute or relative paths to additional folders with # headers, current folder is always included) INC_DIRS = # library directories (absolute or relative paths to additional folders with # libraries) LIB_DIRS = # libraries (additional libraries for linking, e.g. "-lm -lsome_name" to link # math library libm.a and libsome_name.a) LIBS = # additional directories with source files (absolute or relative paths to # folders with source files, current folder is always included) SRCS_DIRS = # extension of C++ files CXX_EXT = cpp # wildcard for C++ source files (all files with CXX_EXT extension found in # current folder and SRCS_DIRS folders will be compiled and linked) CXX_SRCS = $(wildcard $(patsubst %, %/*.$(CXX_EXT), . $(SRCS_DIRS))) # extension of C files C_EXT = c # wildcard for C source files (all files with C_EXT extension found in current # folder and SRCS_DIRS folders will be compiled and linked) C_SRCS = $(wildcard $(patsubst %, %/*.$(C_EXT), . $(SRCS_DIRS))) # extension of ASM files AS_EXT = S # wildcard for ASM source files (all files with AS_EXT extension found in # current folder and SRCS_DIRS folders will be compiled and linked) AS_SRCS = $(wildcard $(patsubst %, %/*.$(AS_EXT), . $(SRCS_DIRS))) # optimization flags ("-O0" - no optimization, "-O1" - optimize, "-O2" - # optimize even more, "-Os" - optimize for size or "-O3" - optimize yet more) OPTIMIZATION = -O2 # set to 1 to optimize size by removing unused code and data during link phase REMOVE_UNUSED = 1 # set to 1 to compile and link additional code required for C++ USES_CXX = 0 # define warning options here CXX_WARNINGS = -Wall -Wextra C_WARNINGS = -Wall -Wstrict-prototypes -Wextra # C++ language standard ("c++98", "gnu++98" - default, "c++0x", "gnu++0x") CXX_STD = gnu++98 # C language standard ("c89" / "iso9899:1990", "iso9899:199409", # "c99" / "iso9899:1999", "gnu89" - default, "gnu99") C_STD = gnu89 #=============================================================================# # set the VPATH according to SRCS_DIRS #=============================================================================# VPATH = $(SRCS_DIRS) #=============================================================================# # when using output folder, append trailing slash to its name #=============================================================================# ifeq ($(strip $(OUT_DIR)), ) OUT_DIR_F = else OUT_DIR_F = $(strip $(OUT_DIR))/ endif #=============================================================================# # various compilation flags #=============================================================================# # core flags CORE_FLAGS = -mcpu=$(CORE) -mthumb # flags for C++ compiler CXX_FLAGS = -std=$(CXX_STD) -g -ggdb3 -fno-rtti -fno-exceptions -fverbose-asm -Wa,-ahlms=$(OUT_DIR_F)$(notdir $(<:.$(CXX_EXT)=.lst)) # flags for C compiler C_FLAGS = -std=$(C_STD) -g -ggdb3 -fverbose-asm -Wa,-ahlms=$(OUT_DIR_F)$(notdir $(<:.$(C_EXT)=.lst)) # flags for assembler AS_FLAGS = -g -ggdb3 -Wa,-amhls=$(OUT_DIR_F)$(notdir $(<:.$(AS_EXT)=.lst)) # flags for linker LD_FLAGS = -T$(LD_SCRIPT) -g -Wl,-Map=$(OUT_DIR_F)$(PROJECT).map,--cref,--no-warn-mismatch # process option for removing unused code ifeq ($(REMOVE_UNUSED), 1) LD_FLAGS += -Wl,--gc-sections OPTIMIZATION += -ffunction-sections -fdata-sections endif # if __USES_CXX is defined for ASM then code for global/static constructors / # destructors is compiled; if -nostartfiles option for linker is added then C++ # initialization / finalization code is not linked ifeq ($(USES_CXX), 1) AS_DEFS += -D__USES_CXX else LD_FLAGS += -nostartfiles endif #=============================================================================# # do some formatting #=============================================================================# CXX_OBJS = $(addprefix $(OUT_DIR_F), $(notdir $(CXX_SRCS:.$(CXX_EXT)=.o))) C_OBJS = $(addprefix $(OUT_DIR_F), $(notdir $(C_SRCS:.$(C_EXT)=.o))) AS_OBJS = $(addprefix $(OUT_DIR_F), $(notdir $(AS_SRCS:.$(AS_EXT)=.o))) OBJS = $(AS_OBJS) $(C_OBJS) $(CXX_OBJS) $(USER_OBJS) DEPS = $(OBJS:.o=.d) INC_DIRS_F = -I. $(patsubst %, -I%, $(INC_DIRS)) LIB_DIRS_F = $(patsubst %, -L%, $(LIB_DIRS)) ELF = $(OUT_DIR_F)$(PROJECT).elf HEX = $(OUT_DIR_F)$(PROJECT).hex BIN = $(OUT_DIR_F)$(PROJECT).bin LSS = $(OUT_DIR_F)$(PROJECT).lss DMP = $(OUT_DIR_F)$(PROJECT).dmp # format final flags for tools, request dependancies for C++, C and asm CXX_FLAGS_F = $(CORE_FLAGS) $(OPTIMIZATION) $(CXX_WARNINGS) $(CXX_FLAGS) $(CXX_DEFS) -MD -MP -MF $(OUT_DIR_F)$(@F:.o=.d) $(INC_DIRS_F) C_FLAGS_F = $(CORE_FLAGS) $(OPTIMIZATION) $(C_WARNINGS) $(C_FLAGS) $(C_DEFS) -MD -MP -MF $(OUT_DIR_F)$(@F:.o=.d) $(INC_DIRS_F) AS_FLAGS_F = $(CORE_FLAGS) $(AS_FLAGS) $(AS_DEFS) -MD -MP -MF $(OUT_DIR_F)$(@F:.o=.d) $(INC_DIRS_F) LD_FLAGS_F = $(CORE_FLAGS) $(LD_FLAGS) $(LIB_DIRS_F) #contents of output directory GENERATED = $(wildcard $(patsubst %, $(OUT_DIR_F)*.%, bin d dmp elf hex lss lst map o)) #=============================================================================# # make all #=============================================================================# all : make_output_dir $(ELF) $(LSS) $(DMP) $(HEX) $(BIN) print_size # make object files dependent on Makefile $(OBJS) : Makefile # make .elf file dependent on linker script $(ELF) : $(LD_SCRIPT) #-----------------------------------------------------------------------------# # linking - objects -> elf #-----------------------------------------------------------------------------# $(ELF) : $(OBJS) @echo 'Linking target: $(ELF)' $(CXX) $(LD_FLAGS_F) $(OBJS) $(LIBS) -o $@ @echo ' ' #-----------------------------------------------------------------------------# # compiling - C++ source -> objects #-----------------------------------------------------------------------------# $(OUT_DIR_F)%.o : %.$(CXX_EXT) @echo 'Compiling file: $<' $(CXX) -c $(CXX_FLAGS_F) $< -o $@ @echo ' ' #-----------------------------------------------------------------------------# # compiling - C source -> objects #-----------------------------------------------------------------------------# $(OUT_DIR_F)%.o : %.$(C_EXT) @echo 'Compiling file: $<' $(CC) -c $(C_FLAGS_F) $< -o $@ @echo ' ' #-----------------------------------------------------------------------------# # assembling - ASM source -> objects #-----------------------------------------------------------------------------# $(OUT_DIR_F)%.o : %.$(AS_EXT) @echo 'Assembling file: $<' $(AS) -c $(AS_FLAGS_F) $< -o $@ @echo ' ' #-----------------------------------------------------------------------------# # memory images - elf -> hex, elf -> bin #-----------------------------------------------------------------------------# $(HEX) : $(ELF) @echo 'Creating IHEX image: $(HEX)' $(OBJCOPY) -O ihex $< $@ @echo ' ' $(BIN) : $(ELF) @echo 'Creating binary image: $(BIN)' $(OBJCOPY) -O binary $< $@ @echo ' ' #-----------------------------------------------------------------------------# # memory dump - elf -> dmp #-----------------------------------------------------------------------------# $(DMP) : $(ELF) @echo 'Creating memory dump: $(DMP)' $(OBJDUMP) -x --syms $< > $@ @echo ' ' #-----------------------------------------------------------------------------# # extended listing - elf -> lss #-----------------------------------------------------------------------------# $(LSS) : $(ELF) @echo 'Creating extended listing: $(LSS)' $(OBJDUMP) -S $< > $@ @echo ' ' #-----------------------------------------------------------------------------# # print the size of the objects and the .elf file #-----------------------------------------------------------------------------# print_size : @echo 'Size of modules:' $(SIZE) -B -t --common $(OBJS) $(USER_OBJS) @echo ' ' @echo 'Size of target .elf file:' $(SIZE) -B $(ELF) @echo ' ' #-----------------------------------------------------------------------------# # create the desired output directory #-----------------------------------------------------------------------------# make_output_dir : $(shell mkdir $(OUT_DIR_F) 2>/dev/null) #=============================================================================# # make clean #=============================================================================# clean: ifeq ($(strip $(OUT_DIR_F)), ) @echo 'Removing all generated output files' else @echo 'Removing all generated output files from output directory: $(OUT_DIR_F)' endif ifneq ($(strip $(GENERATED)), ) $(RM) $(GENERATED) else @echo 'Nothing to remove...' endif #=============================================================================# # global exports #=============================================================================# .PHONY: all clean dependents .SECONDARY: # include dependancy files -include $(DEPS)
skrypt linkera:
/****************************************************************************** * author: Freddie Chopin, http://www.freddiechopin.info/ * file: STM32F103xB_rom.ld * last change: 2012-01-07 * * chip: STM32F103xB * compiler: arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1 * * description: * Linker script for STM32F103xB chip (128kB Flash, 20kB SRAM). ******************************************************************************/ SEARCH_DIR(.); /* +=============================================================================+ | format configurations +=============================================================================+ */ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm"); OUTPUT_ARCH(arm); /* +=============================================================================+ | stacks sizes +=============================================================================+ */ /* Handler mode (core exceptions / interrupts) can use only main stack */ /* Thread mode can use main stack (default) or process stack - selected in CONTROL special register */ __main_stack_size = 1024; __process_stack_size = 1024; PROVIDE(__main_stack_size = __main_stack_size); PROVIDE(__process_stack_size = __process_stack_size); /* +=============================================================================+ | available memories definitions +=============================================================================+ */ MEMORY { rom (rx) : org = 0x08000000, len = 128k ram (rwx) : org = 0x20000000, len = 20k } __rom_start = ORIGIN(rom); __rom_size = LENGTH(rom); __rom_end = __rom_start + __rom_size; __ram_start = ORIGIN(ram); __ram_size = LENGTH(ram); __ram_end = __ram_start + __ram_size; PROVIDE(__rom_start = __rom_start); PROVIDE(__rom_size = __rom_size); PROVIDE(__rom_end = __rom_end); PROVIDE(__ram_start = __ram_start); PROVIDE(__ram_size = __ram_size); PROVIDE(__ram_end = __ram_end); /* +=============================================================================+ | entry point +=============================================================================+ */ ENTRY(Reset_Handler); /* +=============================================================================+ | put data in sections +=============================================================================+ */ SECTIONS { .text : { . = ALIGN(4); __text_start = .; PROVIDE(__text_start = __text_start); . = ALIGN(4); KEEP(*(.vectors)); . = ALIGN(4); *(.text .text.* .gnu.linkonce.t.*); . = ALIGN(4); *(.glue_7t .glue_7); . = ALIGN(4); *(.rodata .rodata.* .gnu.linkonce.r.*); . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*); /* exception unwinding information */ . = ALIGN(4); *(.gcc_except_table); /* information used for stack unwinding during exception */ . = ALIGN(4); *(.eh_frame_hdr); /* additional information about .ex_frame section */ . = ALIGN(4); *(.eh_frame); /* information used for stack unwinding during exception */ . = ALIGN(4); KEEP(*(.init)); . = ALIGN(4); __preinit_array_start = .; KEEP(*(.preinit_array)); . = ALIGN(4); __preinit_array_end = .; __init_array_start = .; KEEP(*(SORT(.init_array.*))); . = ALIGN(4); KEEP(*(.init_array)); . = ALIGN(4); __init_array_end = .; KEEP(*(.fini)); . = ALIGN(4); __fini_array_start = .; KEEP(*(.fini_array)); . = ALIGN(4); KEEP(*(SORT(.fini_array.*))); . = ALIGN(4); __fini_array_end = .; . = ALIGN(4); __text_end = .; PROVIDE(__text_end = __text_end); } > rom AT > rom . = ALIGN(4); __exidx_start = .; PROVIDE(__exidx_start = __exidx_start); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*); } > rom AT > rom /* index entries for section unwinding */ . = ALIGN(4); __exidx_end = .; PROVIDE(__exidx_end = __exidx_end); .data : { . = ALIGN(4); __data_init_start = LOADADDR (.data); PROVIDE(__data_init_start = __data_init_start); __data_start = .; PROVIDE(__data_start = __data_start); . = ALIGN(4); *(.data .data.* .gnu.linkonce.d.*) . = ALIGN(4); __data_end = .; PROVIDE(__data_end = __data_end); } > ram AT > rom .bss : { . = ALIGN(4); __bss_start = .; PROVIDE(__bss_start = __bss_start); . = ALIGN(4); *(.bss .bss.* .gnu.linkonce.b.*) . = ALIGN(4); *(COMMON); . = ALIGN(4); __bss_end = .; PROVIDE(__bss_end = __bss_end); } > ram AT > ram .stack : { . = ALIGN(8); __stack_start = .; PROVIDE(__stack_start = __stack_start); . = ALIGN(8); __main_stack_start = .; PROVIDE(__main_stack_start = __main_stack_start); . += __main_stack_size; . = ALIGN(8); __main_stack_end = .; PROVIDE(__main_stack_end = __main_stack_end); . = ALIGN(8); __process_stack_start = .; PROVIDE(__process_stack_start = __process_stack_start); . += __process_stack_size; . = ALIGN(8); __process_stack_end = .; PROVIDE(__process_stack_end = __process_stack_end); . = ALIGN(8); __stack_end = .; PROVIDE(__stack_end = __stack_end); } > ram AT > ram . = ALIGN(4); __heap_start = .; PROVIDE(__heap_start = __heap_start); . = ALIGN(4); __heap_end = __ram_end; PROVIDE(__heap_end = __heap_end); .stab 0 (NOLOAD) : { *(.stab) } .stabstr 0 (NOLOAD) : { *(.stabstr) } /* DWARF debug sections. * Symbols in the DWARF debugging sections are relative to the beginning * of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } .note.gnu.arm.ident 0 : { KEEP(*(.note.gnu.arm.ident)) } .ARM.attributes 0 : { KEEP(*(.ARM.attributes)) } /DISCARD/ : { *(.note.GNU-stack) } } PROVIDE(__text_size = __text_end - __text_start); PROVIDE(__exidx_size = __exidx_end - __exidx_start); PROVIDE(__data_size = __data_end - __data_start); PROVIDE(__bss_size = __bss_end - __bss_start); PROVIDE(__stack_size = __stack_end - __stack_start); PROVIDE(__heap_size = __heap_end - __heap_start); /****************************************************************************** * END OF FILE ******************************************************************************/
Zdaje sobię sprawę, że to jest do wersji 128K-20K ale mimo wszystko taki mały programik nie powinien wyjść poza te wartości. No i wcześniej to działało...
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#34
08 Feb 2012 11:10 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Spróbuj korzystać z funkcji NVIC_EnableIRQ() oraz NVIC_DisableIRQ().
4\/3!!
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#35
08 Feb 2012 13:15 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Nie ma takiej funkcji w misc.c.
Zresztą zobacz, że problem już nie występuje z hard fault. Natomiast wchodzi cały czas w procedury obsługi przerwania. Nie wychodzi z nich.
|
|
| Back to top |
|
 |
nsvinc Poziom 22

Joined: 25 Mar 2006 Posts: 2066 Location: otfock
|
#36
08 Feb 2012 13:19 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Skoro hardfault występuje przy kompilacji z -O0 to znaczy że jednak występuje, a ty tylko znalazłeś obejście problemu.
Flagi przerwan w EXTI trzeba gasić ręcznie. Jesli tego nie zrobisz, będziesz w stanie permanentnego przerwania...
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#37
08 Feb 2012 13:20 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
| qscgu wrote: |
| Nie ma takiej funkcji w misc.c. |
Taka "funkcja" jest w core_cm3.h
4\/3!!
|
|
| Back to top |
|
 |
Google

|
#
08 Feb 2012 13:20 |
|
|
|
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#38
08 Feb 2012 13:54 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Ok po kolei bo widać trochę zamieszałem.
Zarówno w kofiguracji O0, O1, O2, Os występuje ten sam problem.
Wchodzi cały czas do funkcji obsługi przerwań. Hard fault przestał występować po aktualizacji biblioteki core_cm3.h i c.
Moje inicjalizacje wyglądają następująco:
void gpio_init(void) { RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPEEN; RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); /* TIM1 used for PWM genration */ TIM_TimeBaseStructure.TIM_Prescaler = 0x00; /* TIM1CLK = 72 MHz */ TIM_TimeBaseStructure.TIM_Period = 4320; /* 10 bits resolution */ TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //włączamy przerwanie zegara TIM2 NVIC_EnableIRQ(TIM2_IRQn); gpio_pin_cfg(LED_GPIO, LED_pin, GPIO_CRx_MODE_CNF_OUT_PP_10M_value); gpio_pin_cfg(LED2_GPIO, LED2_pin, GPIO_CRx_MODE_CNF_OUT_PP_10M_value); gpio_pin_cfg(LED_GPIO, LED3_pin, GPIO_CRx_MODE_CNF_OUT_PP_10M_value); gpio_pin_cfg(LED_GPIO, LED4_pin, GPIO_CRx_MODE_CNF_OUT_PP_10M_value); } void ButtonInit(void) { //Włączamy porty A i F RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPFEN; //Konfigurujemy pin na podciąganie górne gpio_pin_cfg(GPIOA, GPIO_Pin_0, GPIO_CRx_MODE_CNF_IN_PULL_U_D_value); BTN_pullup = 1; //Łączymy port PA0 do przypisanego mu numeru przerwania czyli EXTI0 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //Włączamy przerwanie NVIC_EnableIRQ(EXTI0_IRQn); EXTI->IMR = EXTI_Line0; EXTI->FTSR |= EXTI_Line0; }
Sukcesywnie pozbywam się funkcji obsługi z bibliotek STM32. Robie to w taki sposób, że podpatruje co jest w oryginalnej funkcji. Konfrontuje to z tym co znajdę w internecie (głównie tutaj na elektrodzie i zazwyczaj sugeruje się wypowiedziami Freddiego.)
W funkcji main:
Code C (LoadRunner) - [expand] int main(void) { system_init(); ButtonInit(); pll_start(CRYSTAL, FREQUENCY); SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); if (SysTick_Conf(14400000)) { while(1); // W razie bledu petla nieskonczona } LED3_bb = 1; LED4_bb = 1; while (1) { // delay Delay(7200000); LED2_bb ^= 1; } }
Program działa następująco przy wyłączonym debugowaniu:
Dioda 1 miga - przerwanie systemowe
Dioda 2 miga - główna pętla programu
Diody 3 i 4 migają bardzo szybko, ale da się to zauważyć. obie te diody są togglowane są w funkcjach obsługi obu przerwań:
Code C (LoadRunner) - [expand] void EXTI0_IRQHandler(void) { if ((EXTI->PR & EXTI_Line0) != 0) //EXTI_GetITStatus { EXTI->PR = EXTI_Line0; //EXTI_ClearITPendingBit //włączamy przerwanie zegara NVIC_EnableIRQ(TIM2_IRQn); //wyłączamy przerwanie buttona NVIC_DisableIRQ(EXTI0_IRQn); //uruchamiamy timer TIM2->CNT = 0; TIM2->CR1 |= TIM_CR1_CEN; // oraz jego przerwania TIM2->DIER |= TIM_IT_CC1; //zmieniamy led LED3_bb ^= 1; } } void TIM2_IRQHandler(void) { if ( ((TIM2->SR & TIM_IT_CC1) != 0) ) //TIM_GetITStatus { TIM2->SR = ~TIM_IT_CC1; //TIM_ClearITPendingBit LED4_bb ^= 1; //wyłączamy przerwanie zegara NVIC_DisableIRQ(TIM2_IRQn); //włączamy przerwanie buttona NVIC_EnableIRQ(EXTI0_IRQn); // wylacz licznik TIM2->CR1 &= ~TIM_CR1_CEN; // oraz jego przerwanie TIM2->DIER &= ~TIM_IT_CC1; } }
W momencie naciśnięcia przycisku i jego przytrzymania diody zatrzymują się. Czyli dzieje się to dokładnie na odwrót jak chce.
Przycisk wciśnięty -> Nie ma przerwania żadnego.
Przycisk normalnie -> Generuje się milion przerwań.[/code]
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#39
10 Feb 2012 15:39 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Odpowiem sobie sam na to pytanie. Otóż funkcja Freddiego nie zupełnie działa poprawnie:
Zamiast
gpio_pin_cfg(GPIOA, GPIO_Pin_0, GPIO_CRx_MODE_CNF_IN_PULL_U_D_value); BTN_pullup = 1;
Wstawiłem oryginalną:
Code C (LoadRunner) - [expand] GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure);
I działa.
Nie wiem dlaczego takie problemy. Może jakiś błąd w funkcji gpio_pin_cfg ?
Jeśli nikt nic nie doda to zamknę wątek jako rozwiązany.
Podsumując:
trzeba się upewnić, że mamy najnowszego cmsysa.
Najlepiej olać biblioteki od stma. Skopiować co potrzeba, zoptymalizować i resztę wywalić.
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#40
10 Feb 2012 15:48 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Nie wiem czy wiesz, ale moja funkcja oczekuje NUMERU pinu (0, 1, 2, ...), natomiast Ty jej przekazujesz MASKĘ pinu (1 << 0, 1 << 1, 1 << 2, ...). Innymi słowy konfigurujesz (w tym akurat przypadku) pin nr 1 (1 << 0 == 1), a nie pin nr 0.
Tak więc zanim zaczniesz sugerować że ktoś ma błąd sprawdź najpierw czy nie zrobiłeś go Ty.
BTW - W przykładach jest najnowszy CMSIS tyle że w wersji 1.x, dostępna jest już wersja 2.x, jednak obecnie obydwie te "gałęzie" rozwijane są równocześnie.
4\/3!!
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#41
10 Feb 2012 16:12 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Faktycznie.
Znaczy się:
Wiedziałem że twoja funkcja bierze numer pinu, ale myślałem że dla 0 pinu nie ma to znaczenia bo wartość będzie wynosić 0. Myliłem się. Pin_0 to jest 1 a nie 0.
Sprawdziłem teraz, faktycznie, twoja funkcja działa, zwracam honor.
Co do CMSISa to fakty są takie:
1.2 i 1.3 -> Hard Fault w losowym momencie
2.X -> brak problemów.
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#42
10 Feb 2012 16:39 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Nie wiem jaki wpływ na to mógłby mieć CMSIS... W samym CMSISie jest generalnie tylko kilka definicji, np NVIC_EnableIRQ().
Musiałbyś wrzucić tu cały swój problematyczny projekt w wersji "złej".
4\/3!!
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#43
10 Feb 2012 16:47 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Nic nie zmieniałem od tego czasu. Jakieś tam pierdółki. Ale na 100% to byłą wina CMSISa.
Wcześniej Hard fault latał na prawo i lewo. Od czasu zmiany na nową wersję nie było już żadnego problemu. A udało mi się uruchomić ADC i DAC'a od tego czasu.
Wcześniej dla O0 nie było błędu kompilacji natomiast dla O1 i O2 były. Przeczytaj wcześniejsze posty tam wszystko jest opisane jak się to zachowywało. Teraz nie ma problemu dla żadnego stopnia optymalizacji.
Aha problem prawdopodobnie występował z definicjami assemblera. Zobacz jakie błędy wywalał wczesniej.
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#45
10 Feb 2012 18:03 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Zrobiłem tak:
Błąd występował. Hard Fault.
1. Włączyłem optymalizacje O1.
2. Próbowałem kompilować. Błędy "registers may not be the same"
3. Poczytałem o tych błędach w necie i znalazłem jakieś tam niby podmianki do tych funkcji.
4. Nic one nie dały. Teraz błędu nie było "registers may not be the same" ALE wywalało błąd Hard fault przy wszystkich optymalizacjach.
5. Znalazłem nową wersję CMSIS i podmieniłem. Brakowało również z nich:
#include "core_cmInstr.h" /*!< Core Instruction Access */
#include "core_cmFunc.h" /*!< Core Function Access */
6. Ściągnąłem i dodałem
7. Problem ustał. Wszystkie optymalizacje działały, nigdy więcej już nie widziałem błędu hard fault.
Potem miałem problem z tą twoją funkcja ale to już dalszy ciąg opowieści znasz. Nie mniej jednak OD momentu kiedy OSTATNI raz widziałem hard fault DO momentu kiedy zaaktualizowałem CMSISa NIE DOTKNĄŁEM kodu źródłowego. Dla mnie jednoznacznie problemem był starszy CMSIS.
Zresztą, teraz wypisuje głupoty bawie się rejestrami i czasem zdarzy mi się coś źle zrobić i widzę to w debugu ale nie wywala hard faulta.
|
|
| Back to top |
|
 |
Google

|
#
10 Feb 2012 18:03 |
|
|
|
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#46
10 Feb 2012 18:14 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Ja uważasz.
4\/3!!
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#47
10 Feb 2012 18:48 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Innego racjonalnego wytłumaczenia nie mogę znaleźć. Wcześniej kolejność konfiguracji portów miała znaczenie teraz już nie. Zamieniam instrukcje miejscami i działa.
Wcześniej myślałem, że po prostu arm tak już ma ale się myliłem. Nie wywala błędów nawet przy konfiguracji na czuja. (Po prostu nie działa jak coś).
Mógłbym się jeszcze dowiedzieć jak skonfigurować skrypt linkera pod mój proc?
Mam obecnie tak:
| Code: |
__main_stack_size = 1024;
__process_stack_size = 1024;
MEMORY
{
rom (rx) : org = 0x08000000, len = 128k
ram (rwx) : org = 0x20000000, len = 20k
}
|
Myślę żeby zmienić na tak:
| Code: |
__main_stack_size = 1024;
__process_stack_size = 1024;
MEMORY
{
rom (rx) : org = 0x08000000, len = 512k
ram (rwx) : org = 0x20000000, len = 64k
}
|
Ale nie chcę ubić procka. Nie znalazłem opisu modyfikacji tego skrytpu. Same chińskie strony :)
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#48
10 Feb 2012 19:57 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Nie ma tu żadnej filozofii - zmieniasz sobie te cztery linijki według uznania/potrzeb i już (;
4\/3!!
|
|
| Back to top |
|
 |
qscgu Poziom 23

Joined: 07 Jul 2005 Posts: 3274 Location: Myslowice
|
#49
11 Feb 2012 14:46 Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault |
|
|
|
Dobra dzięki, wszystko jest jak trzeba. Teraz się będę zmagał z USB ale to już inny wątek.
|
|
| Back to top |
|
 |