FAQ | Points | Add... | Recent posts | Search | Register | Log in


[STM32][C/GCC] Przerwanie na buttonie i Hard Fault


Post new topic  This topic is locked      Main Page -> Forum Index -> Microcontrollers Generally -> ARM Microcontrollers -> [STM32][C/GCC] Przerwanie na buttonie i Hard Fault
Author
Message
qscgu
Poziom 23
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#31 Post from the author of the topic 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.

Code C - [expand]
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:

Code C - [expand]
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
Poziom 22


Joined: 02 Jun 2010
Posts: 2194
Location: Bytom

Post#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
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#33 Post from the author of the topic 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!

Code C - [expand]
 
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:

Code C - [expand]
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:
Code C - [expand]
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.

Code C - [expand]
#=============================================================================#
# 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:
Code C - [expand]
/******************************************************************************
* 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
Poziom 25


Joined: 12 Dec 2005
Posts: 7300
Location: Zawiercie

Post#34 08 Feb 2012 11:10helpful post - solution   

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
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#35 Post from the author of the topic 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
Poziom 22


Joined: 25 Mar 2006
Posts: 2066
Location: otfock

Post#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
Poziom 25


Joined: 12 Dec 2005
Posts: 7300
Location: Zawiercie

Post#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

Google Adsense


Post# 08 Feb 2012 13:20   





Back to top
   
qscgu
Poziom 23
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#38 Post from the author of the topic 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:

Code C - [expand]
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
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#39 Post from the author of the topic 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
Code C - [expand]
 
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
Poziom 25


Joined: 12 Dec 2005
Posts: 7300
Location: Zawiercie

Post#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
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#41 Post from the author of the topic 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
Poziom 25


Joined: 12 Dec 2005
Posts: 7300
Location: Zawiercie

Post#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
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#43 Post from the author of the topic 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
Poziom 25


Joined: 12 Dec 2005
Posts: 7300
Location: Zawiercie

Post#44 10 Feb 2012 17:55   

Re: [STM32][C/GCC] Przerwanie na buttonie i Hard Fault


Błędy jakie otrzymujesz (log konsoli) pokazałeś tylko raz. Co do błędów assemblera, to zapewne chodziło Ci o to co opisane zostało przy końcu tej strony http://www.freddiechopin.info/index.php/pl/artykuly/35-arm/79-przykady-dla-stm32-stm32f10x-standard-peripherals-library?start=4 to nie wiem jak to miałoby mieć coś wspólnego z Twoim problemem...

Na 99% problem masz gdzie indziej i albo rozwiązałeś go przypadkiem, albo ominąłeś go tymczasowo.

4\/3!!
Back to top
   
qscgu
Poziom 23
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#45 Post from the author of the topic 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

Google Adsense


Post# Post from the author of the topic 10 Feb 2012 18:03   





Back to top
   
Freddie Chopin
Poziom 25
Poziom 25


Joined: 12 Dec 2005
Posts: 7300
Location: Zawiercie

Post#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
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#47 Post from the author of the topic 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
Poziom 25


Joined: 12 Dec 2005
Posts: 7300
Location: Zawiercie

Post#48 10 Feb 2012 19:57helpful post - solution   

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
Poziom 23


Joined: 07 Jul 2005
Posts: 3274
Location: Myslowice

Post#49 Post from the author of the topic 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
   
Post new topic  This topic is locked      Main Page -> Forum Index -> Microcontrollers Generally -> ARM Microcontrollers -> [STM32][C/GCC] Przerwanie na buttonie i Hard Fault
Page 2 of 2 Go to page Previous  1, 2
Similar topics
[ARM7][gcc 4.2.2] przerwanie FIQ (26)
[at91sam7s256][gcc] przerwanie z timera (30)
[Bascom] Hard spi, slave, chip select, przerwanie (7)
[STM32][Keil][C]Hard Fault tylko przy optymalizacji -O3 (9)
[stm32][c/crossworks] Hard Fault przy wejsciu do funkcji (13)
[STM32 / Truestudio]Hard Fault przy powrocie z funkcji. (2)
[STM32]USART hard fault przy wysyłaniu (7)
[at91sam7s][gcc] Przerwanie USART (6)
AVR GCC TIMER0 i przerwanie - problem (6)
[atmega8][gcc]przerwanie od zbocza od przepełnienia (3)

Page generation time: 1.103 seconds


FAQ || Administrator || Moderators || Widgets and banners || Contact
elektroda.pl topic RSS feed