2015-09-13 07:48 AM
Hi guys,
I have a problem to test systick using GNU assembler on my STM32VLDiscoveryMy assembly code is:.thumb.syntax unified.cpu cortex-m3 @ STM32VLDiscovery Board .equ STACKINIT , 0x20005000 .equ GPIOC_BASE , 0x40011000 .equ GPIOC_CRL , GPIOC_BASE + 0x00 .equ GPIOC_CRH , GPIOC_BASE + 0x04 .equ GPIOC_IDR , GPIOC_BASE + 0x08 .equ GPIOC_ODR , GPIOC_BASE + 0x0C .equ GPIOC_BSRR , GPIOC_BASE + 0x10 .equ GPIOC_BRR , GPIOC_BASE + 0x14 .equ GPIOC_LCKR , GPIOC_BASE + 0x18 .equ RCC_APB2ENR, 0x40021018 .equ SYSTICK , 0xE000E010 .equ _CTRL , 0x00 .equ _LOAD , 0x04 .equ _CALIB , 0x0C .equ _CURRENT , 0x08 .equ LEDDELAY , 100000 .equ LEDDELAY2 , 800000 .align.global _start.global SysTick_handler.section .text.org 0vectors: @ Vectors .word STACKINIT .word _start + 1 .word _nmi_handler + 1 .word _hard_fault + 1 .word _memory_fault + 1 .word _bus_fault + 1 .word _usage_fault + 1 .org 0x0000003C .word SysTick_handler + 1 _start: ldr r6, = RCC_APB2ENR mov r0, #0x10 @ Port C Eneable str r0, [r6] ldr r6, =GPIOC_CRH ldr r0, = 0x444433 @ Port C8 dan C9 output 50Hz str r0, [r6] Systick_Init: cpsid i LDR R0, =SYSTICK @ SYSTICK control and status register MOV R1, #0 STR R1, [R0] @ Stop counter to prevent interrupt triggered accidentally LDR R1, =8000000 STR R1, [R0,_LOAD] @ Write reload value to reload register address STR R1, [R0,_CURRENT] @ Write any value to current value @ register to clear current value to 0 and clear COUNTFLAG MOV R1, #0x7 @ Clock source = core clock, Enable Interrupt, Enable Counter STR R1, [R0] @ Start counter cpsie i loop: ldr r6, =GPIOC_BSRR ldr r5, =LEDDELAY delay1: subs r5, 1 bne delay1 mov r2, #0x200 @ turn on port C8 str r2, [r6] ldr r5, = LEDDELAY delay2: subs r5, 1 bne delay2 mov r2, #0x2000000 @ turn off port C8 str r2, [r6] b loop_dummy: @ if any int gets triggered, just loop_nmi_handler:_hard_fault:_memory_fault:_bus_fault:_usage_fault: ldr r6, =GPIOC_BSRR ldr r5, =LEDDELAY2 delay3: subs r5, 1 bne delay3 mov r2, #0x300 @ turn on port C8 and C9 str r2, [r6] ldr r5, = LEDDELAY2 delay4: subs r5, 1 bne delay4 mov r2, #0x3000000 @ turn off portC8 and C9 str r2, [r6] b _dummySysTick_handler: @ isr routine ldr r6, =GPIOC_BSRR mov r2, #0x300 @ turn on port C9 str r2, [r6] bx lrMy goal just blink the led in pin C8 in the loop sectionand when the systick interrupt is triggered, the pin C9 in setif there is error, the pin C8 and C9 are blink together.In the first 1 second everything is running well, means C8 blink successfullywhen the systick interrupt is triggered, it should be turning on C9 onlyBut i always got error (hard fault) , means C8 and C9 blink together ( _dummy loop)I tried to add this code:LDR R1, =0xE000ED22 @ Set the PendSV exception priority (lowest)LDR R2, =0xFFSTRB R2, [R1] LDR R1, =0xE000ED23 @ Set the SysTick exception priority (lowest)LDR R2, =0xFFSTRB R2, [R1]but nothing change.Does anyone can help me !Thanks.2015-09-13 08:22 AM
I'm not wading through the code, perhaps using a debugger and stepping through it will help you?
Pretty sure if the assembler knows it's in a code segment, you don't have to +1 subroutine/location addresses. Look at what's in the vector table if you DON'T do this, the addresses should be ODD. If they are not, then look at some startup_stm32fxx.s files to see the desired structure, organization, and section/segment definitions. Also R6 isn't in the register set that the processor automatically pushes in interrupt context, so review that, and use a register that is pushed, or preserve it yourself.2015-09-13 08:33 AM
Thanks, for your fast reply
I will follow your advise, and try to fix againI will post the result later2015-09-13 09:44 AM
Actually i don't know how to debug the assembly code using GNU assembler
I just use ST-Link Utility - LiveUpdate facility, and ''Target --> MCU Core'' to debug and to know Micro controller stateThe +1 in my vector table is manually adjust to odd for thumb codei have tried to remove all the +1 in the vector table and the result is no interrupt called, by removing the +1 , the problem is not solved and my ''dummy loop'' as my indicator also never been called. when the reset button is pressed it should be return my pointer to the _start label, if i remove the +1 the _start label is never been called after the reset button is called.So i think the +1 in vector table is correct.i also tried to change r6 to r1 register but nothing change.moreover, i want to know the process without any interrupt handler,so i try to remove all the vector table except stackinit and reset, i just leave my vector table to this:vectors: .word STACKINIT .word _start + 1 and the result is same, the blink of c8 (main loop) is running 1 second, ( 1 second is my systick_load value is 8M) and after that all led is off.so i guess the problem is in systick interrupt event.here is my reason:The main loop is running well for 1 sec and then start error, means the error is happened exactly when systick countdown is reached 0.i just want to know, why there is an error when the system tick interrupt is triggered.sorry i am a newbie in microcontroller programming, so i need a lot of helps.2015-09-13 05:53 PM
.thumb
.syntax unified
.cpu cortex-m3 @ STM32VLDiscovery Board
.equ STACKINIT , 0x20005000
.equ GPIOC_BASE , 0x40011000
.equ GPIOC_CRL , GPIOC_BASE + 0x00
.equ GPIOC_CRH , GPIOC_BASE + 0x04
.equ GPIOC_IDR , GPIOC_BASE + 0x08
.equ GPIOC_ODR , GPIOC_BASE + 0x0C
.equ GPIOC_BSRR , GPIOC_BASE + 0x10
.equ GPIOC_BRR , GPIOC_BASE + 0x14
.equ GPIOC_LCKR , GPIOC_BASE + 0x18
.equ RCC_APB2ENR, 0x40021018
.equ SYSTICK , 0xE000E010
.equ _CTRL , 0x00
.equ _LOAD , 0x04
.equ _CURRENT , 0x08
.equ _CALIB , 0x0C
.equ LEDDELAY , 100000
.equ LEDDELAY2 , 800000
.align
.global _start
.global SysTick_handler
.global vectors
.section .text
.org 0
vectors: @ Vectors
.word STACKINIT
.word _start + 1
.word _nmi_handler + 1
.word _hard_fault + 1
.word _memory_fault + 1
.word _bus_fault + 1
.word _usage_fault + 1
.org 0x0000003C
.word SysTick_handler + 1
@if .type _start, function you wouldn't need the +1
_start:
ldr r6, =RCC_APB2ENR
mov r0, #0x10 @ Port C Enable
str r0, [r6]
ldr r6, =GPIOC_CRH
ldr r0, = 0x444433 @ Port C8 and C9 output 50Hz
str r0, [r6]
Systick_Init:
LDR R0, =SYSTICK @ SYSTICK control and status register
MOV R1, #0
STR R1, [R0] @ Stop counter to prevent interrupt triggered accidentally
LDR R1, =8000000
STR R1, [R0,_LOAD] @ Write reload value to reload register address
STR R1, [R0,_CURRENT] @ Write any value to current value
@ register to clear current value to 0 and clear COUNTFLAG
MOV R1, #0x7 @ Clock source = core clock, Enable Interrupt, Enable Counter
STR R1, [R0] @ Start counter
loop:
ldr r6, =GPIOC_BSRR
ldr r5, =LEDDELAY
delay1:
subs r5, 1
bne delay1
mov r2, #0x100 @ turn on port C8
str r2, [r6]
ldr r5, = LEDDELAY
delay2:
subs r5, 1
bne delay2
mov r2, #0x1000000 @ turn off port C8
str r2, [r6]
b loop
_dummy: @ if any int gets triggered, just loop
_nmi_handler:
_hard_fault:
_memory_fault:
_bus_fault:
_usage_fault:
ldr r6, =GPIOC_BSRR
ldr r5, =LEDDELAY2
delay3:
subs r5, 1
bne delay3
mov r2, #0x300 @ turn on port C8 and C9
str r2, [r6]
ldr r5, = LEDDELAY2
delay4:
subs r5, 1
bne delay4
mov r2, #0x3000000 @ turn off port C8 and C9
str r2, [r6]
b _dummy
SysTick_handler: @ isr routine
ldr r1, =GPIOC_ODR
ldr r2, [r1]
mov r0, #0x200 @ turn toggle port C9
eor r2, r0
str r2, [r1]
bx lr
2015-09-14 01:48 AM
.thumb
.syntax unified
.cpu cortex-m3 @ STM32VLDiscovery Board
.equ STACKINIT , 0x20005000
.equ GPIOC_BASE , 0x40011000
.equ GPIOC_CRL , GPIOC_BASE + 0x00
.equ GPIOC_CRH , GPIOC_BASE + 0x04
.equ GPIOC_IDR , GPIOC_BASE + 0x08
.equ GPIOC_ODR , GPIOC_BASE + 0x0C
.equ GPIOC_BSRR , GPIOC_BASE + 0x10
.equ GPIOC_BRR , GPIOC_BASE + 0x14
.equ GPIOC_LCKR , GPIOC_BASE + 0x18
.equ RCC_APB2ENR, 0x40021018
.equ SYSTICK , 0xE000E010
.equ _CTRL , 0x00
.equ _LOAD , 0x04
.equ _CURRENT , 0x08
.equ _CALIB , 0x0C
.equ LEDDELAY , 100000
.equ LEDDELAY2 , 800000
.align
.global vectors
.section .text
.org 0
.type _start, function
.type _nmi_handler, function
.type _hard_fault, function
.type _memory_fault, function
.type _bus_fault, function
.type _usage_fault, function
.type SysTick_handler, function
vectors: @ Vectors
.word STACKINIT
.word _start
.word _nmi_handler
.word _hard_fault
.word _memory_fault
.word _bus_fault
.word _usage_fault
.org 0x0000003C
.word SysTick_handler
@if .type _start, function you wouldn't need the +1
_start:
ldr r6, =RCC_APB2ENR
mov r0, #0x10 @ Port C Enable
str r0, [r6]
ldr r6, =GPIOC_CRH
ldr r0, = 0x444433 @ Port C8 and C9 output 50Hz
str r0, [r6]
Systick_Init:
LDR R0, =SYSTICK @ SYSTICK control and status register
MOV R1, #0
STR R1, [R0] @ Stop counter to prevent interrupt triggered accidentally
LDR R1, =8000000
STR R1, [R0,_LOAD] @ Write reload value to reload register address
STR R1, [R0,_CURRENT] @ Write any value to current value
@ register to clear current value to 0 and clear COUNTFLAG
MOV R1, #0x7 @ Clock source = core clock, Enable Interrupt, Enable Counter
STR R1, [R0] @ Start counter
loop:
ldr r6, =GPIOC_BSRR
ldr r5, =LEDDELAY
delay1:
subs r5, 1
bne delay1
mov r2, #0x100 @ turn on port C8
str r2, [r6]
ldr r5, = LEDDELAY
delay2:
subs r5, 1
bne delay2
mov r2, #0x1000000 @ turn off port C8
str r2, [r6]
b loop
_dummy: @ if any int gets triggered, just loop
_nmi_handler:
_hard_fault:
_memory_fault:
_bus_fault:
_usage_fault:
ldr r6, =GPIOC_BSRR
ldr r5, =LEDDELAY2
delay3:
subs r5, 1
bne delay3
mov r2, #0x300 @ turn on port C8 and C9
str r2, [r6]
ldr r5, = LEDDELAY2
delay4:
subs r5, 1
bne delay4
mov r2, #0x3000000 @ turn off port C8 and C9
str r2, [r6]
b _dummy
SysTick_handler: @ isr routine
ldr r1, =GPIOC_ODR
ldr r2, [r1]
mov r0, #0x200 @ turn toggle port C9
eor r2, r0
str r2, [r1]
bx lr
Hi Clieve, thanks for your help but i change my code same as your suggestion, Apply the type and use the R1 on Interrupt handler (I attach my complete code and also the assembler program in zip file) but the problem is not yet solved I have the video result https://www.youtube.com/watch?v=y2WVFK60tDo&feature=youtu.be
The first 1 second everything running well, as you can see, the c8 blinks well but when the systick countdown reach zero (1 second) it should be call the Systick handler and the c9 start blink, but i got hard fault so the dummy loop is running (c8 + c9 blink together) Any other suggestion? Thanks ________________ Attachments : Systick_Test.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzQw&d=%2Fa%2F0X0000000bO7%2F4sWWmagnx63cbhs.PhLQRuXdTSPt7mxL5tg3c6Ebx88&asPdf=false2015-09-14 07:04 PM
The part you are using only has 8KB of RAM, not 20KB
.equ STACKINIT , 0x200020002015-09-14 08:15 PM
Wow ..
Its work perfectlyI did not realize this very basic problem, but you know itYou are very geniusThank you very much Clive