STM32F103C8T6 doesn't work after reset button - arm

I have "Minimum System Development Board for ARM Microcontroller – STM32F103C8T6" with ST-LINK V2.
This is the main code followed by linker-script then startup:
1) main:
### Directives
.thumb # (same as saying '.code 16')
.syntax unified
.cpu cortex-m3
.fpu softvfp
.include "stm32f103.i"
.section .text
.org 0x00
.global main
.equ GPIOC_CRL ,GPIOC_BASE
.equ GPIOC_CRH ,GPIOC_BASE + 0x04
.equ GPIOC_ODR ,GPIOC_BASE + 0x0C
.equ RCC_APB2ENR ,RCC_BASE + 0x14
.equ LEDDELAY ,800000
main:
## Enable the Port C peripheral clock
ldr r6, = RCC_APB2ENR
mov r0, RCC_APB2ENR_IOPCEN
str r0, [r6]
## Set the config and mode bits for Port C bin 15 so it will
## be a push-pull output (up to 50 MHz)
## to '0011'.
ldr r6, = GPIOC_CRH
ldr r0, = 0x34444444
str r0, [r6]
## Load R2 and R3 with the "on" and "off" constants
mov r2, 0x8000 # value to turn on LED
mov r3, 0x0 # value to turn off LED
ldr r6, = GPIOC_ODR # point to Port C output data register
loop:
str r2, [r6] # clear Port C, pin 15, turning on LED
ldr r1, = LEDDELAY
delay1:
subs r1, 1
bne delay1
str r3, [r6] # set Port C, pin 15, turning off LED
ldr r1, = LEDDELAY
delay2:
subs r1, 1
bne delay2
b loop # continue forever
##st-flash write forth.bin 0x08000000
2) linker:
/*
*****************************************************************************
**
** File : LinkerScript.ld
**
** Abstract : Linker script for STM32F103C8Tx Device with
** 64KByte FLASH, 20KByte RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
/* Entry Point */
ENTRY(Reset_Handler)
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 256;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;
SECTIONS
{
.isr_vector : { /* the vector table goes FIRST into FLASH */
KEEP(*(.isr_vector)) /* vector table */
. = ALIGN(4);
} >FLASH
.text : { /* code and constants */
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >FLASH
.preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array : {
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array : {
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
_etext = .; /* global symbols at end of code */
.stack : {
__stack_start__ = .;
. = . + STACK_SIZE;
. = ALIGN(4);
__stack_end__ = .;
} >RAM
.data : AT (_etext) {
__data_load = LOADADDR (.data);
__data_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .;
_edata = __data_end__;
} >RAM
.bss : {
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = .;
} >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE ( __end__ = _ebss );
.heap : {
__heap_start__ = .;
. = . + HEAP_SIZE;
. = ALIGN(4);
__heap_end__ = .;
} >RAM
/* Remove information from the standard libraries
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
/*.ARM.attributes 0 : { *(.ARM.attributes) }*/
}
3) startup:
/**
*************** (C) COPYRIGHT 2016 STMicroelectronics ************************
* #file startup_stm32f103xb.s
* #author MCD Application Team
* #version V4.1.0
* #date 29-April-2016
* #brief STM32F103xB Devices vector table for Atollic toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Configure the clock system
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M3 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
*/
.syntax unified
.cpu cortex-m3
.fpu softvfp
.thumb
.global __stack_start__
.global __stack_end__
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word __data_load
/* start address for the .data section. defined in linker script */
.word __data_start
/* end address for the .data section. defined in linker script */
.word __data_end__
/* start address for the .bss section. defined in linker script */
.word __bss_start__
/* end address for the .bss section. defined in linker script */
.word __bss_end__
.equ BootRAM, 0xF108F85F
/**
* #brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* #param None
* #retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =__data_load
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =__data_start
ldr r3, =__data_end__
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =__bss_start__
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4
LoopFillZerobss:
ldr r3, =__bss_end__
cmp r2, r3
bcc FillZerobss
/* Call the clock system intitialization function.*/
/*bl SystemInit*/
/* Call static constructors */
/*bl __libc_init_array*/
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* #brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* #param None
* #retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word __stack_end__
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler
.word PVD_IRQHandler
.word TAMPER_IRQHandler
.word RTC_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMA1_Channel1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word DMA1_Channel7_IRQHandler
.word ADC1_2_IRQHandler
.word USB_HP_CAN1_TX_IRQHandler
.word USB_LP_CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word CAN1_SCE_IRQHandler
.word EXTI9_5_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word SPI1_IRQHandler
.word SPI2_IRQHandler
.word USART1_IRQHandler
.word USART2_IRQHandler
.word USART3_IRQHandler
.word EXTI15_10_IRQHandler
.word RTC_Alarm_IRQHandler
.word USBWakeUp_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word BootRAM /* #0x108. This is for boot in RAM mode for
STM32F10x Medium Density devices. */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak PVD_IRQHandler
.thumb_set PVD_IRQHandler,Default_Handler
.weak TAMPER_IRQHandler
.thumb_set TAMPER_IRQHandler,Default_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak DMA1_Channel7_IRQHandler
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
.weak ADC1_2_IRQHandler
.thumb_set ADC1_2_IRQHandler,Default_Handler
.weak USB_HP_CAN1_TX_IRQHandler
.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
.weak USB_LP_CAN1_RX0_IRQHandler
.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
.weak CAN1_RX1_IRQHandler
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
.weak CAN1_SCE_IRQHandler
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
.weak EXTI9_5_IRQHandler
.thumb_set EXTI9_5_IRQHandler,Default_Handler
.weak TIM1_BRK_IRQHandler
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
.weak TIM1_UP_IRQHandler
.thumb_set TIM1_UP_IRQHandler,Default_Handler
.weak TIM1_TRG_COM_IRQHandler
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak TIM4_IRQHandler
.thumb_set TIM4_IRQHandler,Default_Handler
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak I2C2_EV_IRQHandler
.thumb_set I2C2_EV_IRQHandler,Default_Handler
.weak I2C2_ER_IRQHandler
.thumb_set I2C2_ER_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak USART3_IRQHandler
.thumb_set USART3_IRQHandler,Default_Handler
.weak EXTI15_10_IRQHandler
.thumb_set EXTI15_10_IRQHandler,Default_Handler
.weak RTC_Alarm_IRQHandler
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
.weak USBWakeUp_IRQHandler
.thumb_set USBWakeUp_IRQHandler,Default_Handler
.align
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
When I try to flash this code with
st-flash write main.bin 0x08000000
I get the following :
st-flash 1.3.1
2017-07-03T21:42:39 INFO src/common.c: Loading device parameters....
2017-07-03T21:42:39 INFO src/common.c: Device connected is: F1 Medium-density device, id 0x20036410
2017-07-03T21:42:39 INFO src/common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x20000 bytes (128 KiB) in pages of 1024 bytes
2017-07-03T21:42:39 INFO src/common.c: Attempting to write 420 (0x1a4) bytes to stm32 address: 134217728 (0x8000000)
Flash page at addr: 0x08000000 erased
2017-07-03T21:42:40 INFO src/common.c: Finished erasing 1 pages of 1024 (0x400) bytes
2017-07-03T21:42:40 INFO src/common.c: Starting Flash write for VL/F0/F3 core id
2017-07-03T21:42:40 INFO src/flash_loader.c: Successfully loaded flash loader in sram
0/0 pages written
2017-07-03T21:42:40 INFO src/common.c: Starting verification of write complete
2017-07-03T21:42:40 INFO src/common.c: Flash written and verified! jolly good!
and the LED doesn't flash, but when I first upload any code using ARDUINO IDE(for this board) then I run the prevouis command, the led starts blinking, but if I pushed the reset button or unplug then plug st-link agian the LED stop blinking.
So I think the problem is with my linker or the startup code, but I don't know where it is.
What is wrong with startup code or linker script?
----- EDIT -----
result of disassembly:
arm-none-eabi-objdump -D main.elf > dump.S
main.elf: file format elf32-littlearm
Disassembly of section .isr_vector:
08000000 <g_pfnVectors>:
8000000: 20005000 andcs r5, r0, r0
8000004: 08000165 stmdaeq r0, {r0, r2, r5, r6, r8}
8000008: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
800000c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000010: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000014: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000018: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
...
800002c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000030: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000034: 00000000 andeq r0, r0, r0
8000038: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
800003c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000040: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000044: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000048: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
800004c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000050: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000054: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000058: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
800005c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000060: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000064: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000068: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
800006c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000070: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000074: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000078: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
800007c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000080: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000084: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000088: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
800008c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000090: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000094: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
8000098: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
800009c: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000a0: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000a4: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000a8: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000ac: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000b0: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000b4: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000b8: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000bc: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000c0: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000c4: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000c8: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000cc: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000d0: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000d4: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000d8: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000dc: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000e0: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000e4: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
80000e8: 080001a5 stmdaeq r0, {r0, r2, r5, r7, r8}
...
8000108: f108f85f ; <UNDEFINED> instruction: 0xf108f85f
Disassembly of section .text:
08000110 <main>:
8000110: 4e0a ldr r6, [pc, #40] ; (800013c <delay2+0x8>)
8000112: f04f 0010 mov.w r0, #16
8000116: 6030 str r0, [r6, #0]
8000118: 4e09 ldr r6, [pc, #36] ; (8000140 <delay2+0xc>)
800011a: 480a ldr r0, [pc, #40] ; (8000144 <delay2+0x10>)
800011c: 6030 str r0, [r6, #0]
800011e: f44f 4200 mov.w r2, #32768 ; 0x8000
8000122: f04f 0300 mov.w r3, #0
8000126: 4e08 ldr r6, [pc, #32] ; (8000148 <delay2+0x14>)
08000128 <loop>:
8000128: 6032 str r2, [r6, #0]
800012a: 4908 ldr r1, [pc, #32] ; (800014c <delay2+0x18>)
0800012c <delay1>:
800012c: 3901 subs r1, #1
800012e: d1fd bne.n 800012c <delay1>
8000130: 6033 str r3, [r6, #0]
8000132: 4906 ldr r1, [pc, #24] ; (800014c <delay2+0x18>)
08000134 <delay2>:
8000134: 3901 subs r1, #1
8000136: d1fd bne.n 8000134 <delay2>
8000138: e7f6 b.n 8000128 <loop>
800013a: bf00 nop
800013c: 40021014 andmi r1, r2, r4, lsl r0
8000140: 40011004 andmi r1, r1, r4
8000144: 34444444 strbcc r4, [r4], #-1092 ; 0xfffffbbc
8000148: 4001100c andmi r1, r1, ip
800014c: 000c3500 andeq r3, ip, r0, lsl #10
8000150: 080001a8 stmdaeq r0, {r3, r5, r7, r8}
8000154: 20005000 andcs r5, r0, r0
8000158: 20005000 andcs r5, r0, r0
800015c: 20005000 andcs r5, r0, r0
8000160: 20005000 andcs r5, r0, r0
08000164 <Reset_Handler>:
8000164: 2100 movs r1, #0
8000166: e003 b.n 8000170 <LoopCopyDataInit>
08000168 <CopyDataInit>:
8000168: 4b09 ldr r3, [pc, #36] ; (8000190 <LoopFillZerobss+0xc>)
800016a: 585b ldr r3, [r3, r1]
800016c: 5043 str r3, [r0, r1]
800016e: 3104 adds r1, #4
08000170 <LoopCopyDataInit>:
8000170: 4808 ldr r0, [pc, #32] ; (8000194 <LoopFillZerobss+0x10>)
8000172: 4b09 ldr r3, [pc, #36] ; (8000198 <LoopFillZerobss+0x14>)
8000174: 1842 adds r2, r0, r1
8000176: 429a cmp r2, r3
8000178: d3f6 bcc.n 8000168 <CopyDataInit>
800017a: 4a08 ldr r2, [pc, #32] ; (800019c <LoopFillZerobss+0x18>)
800017c: e002 b.n 8000184 <LoopFillZerobss>
0800017e <FillZerobss>:
800017e: 2300 movs r3, #0
8000180: f842 3b04 str.w r3, [r2], #4
08000184 <LoopFillZerobss>:
8000184: 4b06 ldr r3, [pc, #24] ; (80001a0 <LoopFillZerobss+0x1c>)
8000186: 429a cmp r2, r3
8000188: d3f9 bcc.n 800017e <FillZerobss>
800018a: f7ff ffc1 bl 8000110 <main>
800018e: 4770 bx lr
8000190: 080001a8 stmdaeq r0, {r3, r5, r7, r8}
8000194: 20005000 andcs r5, r0, r0
8000198: 20005000 andcs r5, r0, r0
800019c: 20005000 andcs r5, r0, r0
80001a0: 20005000 andcs r5, r0, r0
080001a4 <ADC1_2_IRQHandler>:
80001a4: e7fe b.n 80001a4 <ADC1_2_IRQHandler>
...
Disassembly of section .stack:
20000000 <__stack_start__>:
...
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 00002041 andeq r2, r0, r1, asr #32
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 00000016 andeq r0, r0, r6, lsl r0
10: 726f4305 rsbvc r4, pc, #335544320 ; 0x14000000
14: 2d786574 cfldr64cs mvdx6, [r8, #-464]! ; 0xfffffe30
18: 0600334d streq r3, [r0], -sp, asr #6
1c: 094d070a stmdbeq sp, {r1, r3, r8, r9, sl}^
20: Address 0x0000000000000020 is out of bounds.

so.s
.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.thumb_func
reset:
b hang
.thumb_func
hang: b .
so.ld
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > rom
.rodata : { *(.rodata*) } > rom
.bss : { *(.bss*) } > ram
}
commands
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m3 so.s -o so.o
arm-none-eabi-ld -o so.elf -T so.ld so.o
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy so.elf so.bin -O binary
so.list (partial)
Disassembly of section .text:
08000000 <_start>:
8000000: 20001000 andcs r1, r0, r0
8000004: 08000041 stmdaeq r0, {r0, r6}
8000008: 08000043 stmdaeq r0, {r0, r1, r6}
800000c: 08000043 stmdaeq r0, {r0, r1, r6}
8000010: 08000043 stmdaeq r0, {r0, r1, r6}
8000014: 08000043 stmdaeq r0, {r0, r1, r6}
8000018: 08000043 stmdaeq r0, {r0, r1, r6}
800001c: 08000043 stmdaeq r0, {r0, r1, r6}
8000020: 08000043 stmdaeq r0, {r0, r1, r6}
8000024: 08000043 stmdaeq r0, {r0, r1, r6}
8000028: 08000043 stmdaeq r0, {r0, r1, r6}
800002c: 08000043 stmdaeq r0, {r0, r1, r6}
8000030: 08000043 stmdaeq r0, {r0, r1, r6}
8000034: 08000043 stmdaeq r0, {r0, r1, r6}
8000038: 08000043 stmdaeq r0, {r0, r1, r6}
800003c: 08000043 stmdaeq r0, {r0, r1, r6}
08000040 <reset>:
8000040: e7ff b.n 8000042 <hang>
08000042 <hang>:
8000042: e7fe b.n 8000042 <hang>
with your linker script, added a label for Reset_Handler which doesnt do much since this is not being loaded from an operating system, but from flash (the vector table defines entry points not the elf, it isnt used in that form)
Disassembly of section .text:
08000000 <_start>:
8000000: 20001000 andcs r1, r0, r0
8000004: 08000041 stmdaeq r0, {r0, r6}
8000008: 08000043 stmdaeq r0, {r0, r1, r6}
800000c: 08000043 stmdaeq r0, {r0, r1, r6}
8000010: 08000043 stmdaeq r0, {r0, r1, r6}
8000014: 08000043 stmdaeq r0, {r0, r1, r6}
8000018: 08000043 stmdaeq r0, {r0, r1, r6}
800001c: 08000043 stmdaeq r0, {r0, r1, r6}
8000020: 08000043 stmdaeq r0, {r0, r1, r6}
8000024: 08000043 stmdaeq r0, {r0, r1, r6}
8000028: 08000043 stmdaeq r0, {r0, r1, r6}
800002c: 08000043 stmdaeq r0, {r0, r1, r6}
8000030: 08000043 stmdaeq r0, {r0, r1, r6}
8000034: 08000043 stmdaeq r0, {r0, r1, r6}
8000038: 08000043 stmdaeq r0, {r0, r1, r6}
800003c: 08000043 stmdaeq r0, {r0, r1, r6}
08000040 <reset>:
8000040: e7ff b.n 8000042 <hang>
08000042 <hang>:
8000042: e7fe b.n 8000042 <hang>
Then you can add more code to make it blink, I am not going to dig out an STM32F103 right now, could maybe cobble together something untested. will see.
Are you getting the 0x08000000 address with the vector table in the right place in your build seeing how to use the tools in this way?
from the way you dissassembled your file starts off okay
20000100
08000161
080001a1
080001a1
080001a1
080001a1
080001a1
that looks reasonable...I dont know if they are the correct addresses, but assume they are
this is working C code for the same chip but pin PC13 instead of 15.
void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
void dummy ( unsigned int );
#define GPIOCBASE 0x40011000
#define RCCBASE 0x40021000
int notmain ( void )
{
unsigned int ra;
unsigned int rx;
ra=GET32(RCCBASE+0x18);
ra|=1<<4; //enable port c
PUT32(RCCBASE+0x18,ra);
//config
ra=GET32(GPIOCBASE+0x04);
ra&=~(3<<20); //PC13
ra|=1<<20; //PC13
ra&=~(3<<22); //PC13
ra|=0<<22; //PC13
PUT32(GPIOCBASE+0x04,ra);
for(rx=0;;rx++)
{
PUT32(GPIOCBASE+0x10,1<<(13+0));
for(ra=0;ra<200000;ra++) dummy(ra);
PUT32(GPIOCBASE+0x10,1<<(13+16));
for(ra=0;ra<200000;ra++) dummy(ra);
}
return(0);
}
I am working through your disassembly to try to figure out what addresses you are using, they look wrong so far 0x40021014 instead of 0x40021018 to enable port c. (PUT32/GET32 are just store/load functions dummy just returns, used to prevent optimization)

Related

Timer interrupts in ARM processor QEMU not occurring

I am trying to get interrupts to work on an ARM processor using QEMU. I have tried Google and various attempts to solve it, but I cannot get my IRQ handler to be called.
I also tried keyboard interrupts, which did not work either. I think the book I have may have a few mistakes, as the UART driver ended up being slightly different than described.
My assembly code:
.code 32
.global start, vectors_start, vectors_end, lock, unlock
start:
LDR sp, =stack_top
BL copy_vector
MSR cpsr, #0x92
LDR sp, =irq_stack_top
MSR cpsr, #0x13
bl unlock
BL main
B .
irq_handler:
sub lr, lr, #4
stmfd sp!, {r0-r12, lr}
bl IRQ_handler
ldmfd sp!, {r0-r12, pc}^
vectors_start:
LDR PC, reset_handler_addr
LDR PC, undef_handler_addr
LDR PC, swi_handler_addr
LDR PC, prefetch_abort_handler_addr
LDR PC, data_abort_handler_addr
B .
LDR PC, irq_handler_addr
LDR PC, fiq_handler_addr
reset_handler_addr: .word start
undef_handler_addr: .word undef_handler
swi_handler_addr: .word swi_handler
prefetch_abort_handler_addr: .word prefetch_abort_handler
data_abort_handler_addr: .word data_abort_handler
irq_handler_addr: .word irq_handler
fiq_handler_addr: .word fiq_handler
vectors_end:
lock:
MRS r0, CPSR
ORR r0,r0,#0x80
MSR CPSR, r0
mov PC, lr
unlock:
MRS r0,CPSR
BIC r0,r0,#0x80
MSR CPSR, r0
mov PC, lr
Relevant C functions:
void copy_vector(void){
extern u32 vectors_start, vectors_end;
u32 *vectors_src = &vectors_start;
u32 *vectors_dst = (u32 *) 0;
while (vectors_src<&vectors_end){
*vectors_dst++ = *vectors_src++;
}
}
// this function has been modified somewhat because the book was incomplete
// the print statement never prints
void IRQ_handler(void){
int vicstatus = 0;
uprints(uarts,"in interupt");
// int vicstatus = 0;
if(1){
if(*(tp[0]->base+TVALUE)==0){
timer_handler(0);
}
if(*(tp[1]->base+TVALUE)==0){
timer_handler(1);
}
}
if( 1){
if(*(tp[2]->base+TVALUE)==0){
timer_handler(2);
}
if(*(tp[3]->base+TVALUE)==0){
timer_handler(3);
}
}
}
void timer_init()
{
// timers[0].base = (u32*) 0x101E2000;
// timers[1].base = (u32*) 0x101E2020;
// timers[2].base = (u32*) 0x101E3000;
// timers[3].base = (u32*) 0x101E3020;
int i; TIMER * tp;
for (i = 0; i<4; ++i){
tp = &timers[i];
if(i==0) tp->base = (u32*) 0x101E2000;
if(i==1) tp->base = (u32*) 0x101E2020;
if (i == 2) tp->base = (u32*) 0x101E3000;
if (i == 3) tp->base = (u32*) 0x101E3020;
*(tp->base+TLOAD) = 0x0;
*(tp->base+TVALUE) = 0xFFFFFFFF;
*(tp->base+TRIS) = 0x0;
*(tp->base+TMIS) = 0x0;
*(tp->base+TLOAD) = 0x100;
*(tp->base+TCNTL) = 0x66;
*(tp->base+TBGLOAD) = 0x1C00;
*(tp->base ) |= (unsigned int)(1<<6);
tp->tick = 0;
///uprints(uarts,"timer init");
}
}
When I reset the machine in QEMU I get the message Timer with delta zero disabling.
I can get the message to disappear by changing: *(tp->base+TLOAD) = 0x0;
to *(tp->base+TLOAD) = 0x1; but the timer still doesn't work.
Lastly, my build script is:
arm-none-eabi-as -o start3.o start3.s
arm-none-eabi-gcc -c main3.c
arm-none-eabi-ld -T t.ld -o start3.elf start3.o main3.o
arm-none-eabi-nm start3.elf
arm-none-eabi-objcopy -O binary start3.elf start3.bin
qemu-system-arm -M versatilepb -m 128M -kernel start3.bin
edit: in addition here is the disassembled code from my main.c file (which includes a few other c files for the drivers)
the board is the versatilepb which according to the docs emulates the following:
ARM926E, ARM1136 or Cortex-A8 CPU
00000000 <uart_init>:
0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
4: e28db000 add fp, sp, #0
8: e24dd00c sub sp, sp, #12
c: e3a03000 mov r3, #0
10: e50b3008 str r3, [fp, #-8]
14: ea000011 b 60 <uart_init+0x60>
18: e51b3008 ldr r3, [fp, #-8]
1c: e1a03183 lsl r3, r3, #3
20: e59f2064 ldr r2, [pc, #100] ; 8c <uart_init+0x8c>
24: e0833002 add r3, r3, r2
28: e50b300c str r3, [fp, #-12]
2c: e51b2008 ldr r2, [fp, #-8]
30: e59f3058 ldr r3, [pc, #88] ; 90 <uart_init+0x90>
34: e0823003 add r3, r2, r3
38: e1a03603 lsl r3, r3, #12
3c: e1a02003 mov r2, r3
40: e51b300c ldr r3, [fp, #-12]
44: e5832000 str r2, [r3]
48: e51b300c ldr r3, [fp, #-12]
4c: e51b2008 ldr r2, [fp, #-8]
50: e5832004 str r2, [r3, #4]
54: e51b3008 ldr r3, [fp, #-8]
58: e2833001 add r3, r3, #1
5c: e50b3008 str r3, [fp, #-8]
60: e51b3008 ldr r3, [fp, #-8]
64: e3530003 cmp r3, #3
68: daffffea ble 18 <uart_init+0x18>
6c: e59f3018 ldr r3, [pc, #24] ; 8c <uart_init+0x8c>
70: e59f201c ldr r2, [pc, #28] ; 94 <uart_init+0x94>
74: e5832018 str r2, [r3, #24]
78: e1a00000 nop ; (mov r0, r0)
7c: e1a00003 mov r0, r3
80: e28bd000 add sp, fp, #0
84: e49db004 pop {fp} ; (ldr fp, [sp], #4)
88: e12fff1e bx lr
8c: 00000000 .word 0x00000000
90: 000101f1 .word 0x000101f1
94: 10009000 .word 0x10009000
00000098 <ugetc>:
98: e52db004 push {fp} ; (str fp, [sp, #-4]!)
9c: e28db000 add fp, sp, #0
a0: e24dd00c sub sp, sp, #12
a4: e50b0008 str r0, [fp, #-8]
a8: e1a00000 nop ; (mov r0, r0)
ac: e51b3008 ldr r3, [fp, #-8]
b0: e5933000 ldr r3, [r3]
b4: e2833018 add r3, r3, #24
b8: e5d33000 ldrb r3, [r3]
bc: e2033010 and r3, r3, #16
c0: e3530000 cmp r3, #0
c4: 1afffff8 bne ac <ugetc+0x14>
c8: e51b3008 ldr r3, [fp, #-8]
cc: e5933000 ldr r3, [r3]
d0: e5d33000 ldrb r3, [r3]
d4: e1a00003 mov r0, r3
d8: e28bd000 add sp, fp, #0
dc: e49db004 pop {fp} ; (ldr fp, [sp], #4)
e0: e12fff1e bx lr
000000e4 <uputc>:
e4: e52db004 push {fp} ; (str fp, [sp, #-4]!)
e8: e28db000 add fp, sp, #0
ec: e24dd00c sub sp, sp, #12
f0: e50b0008 str r0, [fp, #-8]
f4: e1a03001 mov r3, r1
f8: e54b3009 strb r3, [fp, #-9]
fc: e1a00000 nop ; (mov r0, r0)
100: e51b3008 ldr r3, [fp, #-8]
104: e5933000 ldr r3, [r3]
108: e2833018 add r3, r3, #24
10c: e5d33000 ldrb r3, [r3]
110: e2033020 and r3, r3, #32
114: e3530000 cmp r3, #0
118: 1afffff8 bne 100 <uputc+0x1c>
11c: e51b3008 ldr r3, [fp, #-8]
120: e5933000 ldr r3, [r3]
124: e55b2009 ldrb r2, [fp, #-9]
128: e5c32000 strb r2, [r3]
12c: e1a00000 nop ; (mov r0, r0)
130: e1a00003 mov r0, r3
134: e28bd000 add sp, fp, #0
138: e49db004 pop {fp} ; (ldr fp, [sp], #4)
13c: e12fff1e bx lr
00000140 <ugets>:
140: e92d4800 push {fp, lr}
144: e28db004 add fp, sp, #4
148: e24dd008 sub sp, sp, #8
14c: e50b0008 str r0, [fp, #-8]
150: e50b100c str r1, [fp, #-12]
154: ea000007 b 178 <ugets+0x38>
158: e51b300c ldr r3, [fp, #-12]
15c: e5d33000 ldrb r3, [r3]
160: e1a01003 mov r1, r3
164: e51b0008 ldr r0, [fp, #-8]
168: ebfffffe bl e4 <uputc>
16c: e51b300c ldr r3, [fp, #-12]
170: e2833001 add r3, r3, #1
174: e50b300c str r3, [fp, #-12]
178: e51b0008 ldr r0, [fp, #-8]
17c: ebfffffe bl 98 <ugetc>
180: e1a03000 mov r3, r0
184: e20320ff and r2, r3, #255 ; 0xff
188: e51b300c ldr r3, [fp, #-12]
18c: e5c32000 strb r2, [r3]
190: e51b300c ldr r3, [fp, #-12]
194: e5d33000 ldrb r3, [r3]
198: e353000d cmp r3, #13
19c: 1affffed bne 158 <ugets+0x18>
1a0: e51b300c ldr r3, [fp, #-12]
1a4: e3a02000 mov r2, #0
1a8: e5c32000 strb r2, [r3]
1ac: e1a00000 nop ; (mov r0, r0)
1b0: e1a00003 mov r0, r3
1b4: e24bd004 sub sp, fp, #4
1b8: e8bd4800 pop {fp, lr}
1bc: e12fff1e bx lr
000001c0 <uprints>:
1c0: e92d4800 push {fp, lr}
1c4: e28db004 add fp, sp, #4
1c8: e24dd008 sub sp, sp, #8
1cc: e50b0008 str r0, [fp, #-8]
1d0: e50b100c str r1, [fp, #-12]
1d4: ea000006 b 1f4 <uprints+0x34>
1d8: e51b300c ldr r3, [fp, #-12]
1dc: e2832001 add r2, r3, #1
1e0: e50b200c str r2, [fp, #-12]
1e4: e5d33000 ldrb r3, [r3]
1e8: e1a01003 mov r1, r3
1ec: e51b0008 ldr r0, [fp, #-8]
1f0: ebfffffe bl e4 <uputc>
1f4: e51b300c ldr r3, [fp, #-12]
1f8: e5d33000 ldrb r3, [r3]
1fc: e3530000 cmp r3, #0
200: 1afffff4 bne 1d8 <uprints+0x18>
204: e1a00000 nop ; (mov r0, r0)
208: e1a00003 mov r0, r3
20c: e24bd004 sub sp, fp, #4
210: e8bd4800 pop {fp, lr}
214: e12fff1e bx lr
00000218 <fbuf_init>:
218: e52db004 push {fp} ; (str fp, [sp, #-4]!)
21c: e28db000 add fp, sp, #0
220: e59f3060 ldr r3, [pc, #96] ; 288 <fbuf_init+0x70>
224: e3a02602 mov r2, #2097152 ; 0x200000
228: e5832000 str r2, [r3]
22c: e59f3058 ldr r3, [pc, #88] ; 28c <fbuf_init+0x74>
230: e59f2058 ldr r2, [pc, #88] ; 290 <fbuf_init+0x78>
234: e5832000 str r2, [r3]
238: e59f3054 ldr r3, [pc, #84] ; 294 <fbuf_init+0x7c>
23c: e59f2054 ldr r2, [pc, #84] ; 298 <fbuf_init+0x80>
240: e5832000 str r2, [r3]
244: e59f3050 ldr r3, [pc, #80] ; 29c <fbuf_init+0x84>
248: e59f2050 ldr r2, [pc, #80] ; 2a0 <fbuf_init+0x88>
24c: e5832000 str r2, [r3]
250: e59f304c ldr r3, [pc, #76] ; 2a4 <fbuf_init+0x8c>
254: e59f204c ldr r2, [pc, #76] ; 2a8 <fbuf_init+0x90>
258: e5832000 str r2, [r3]
25c: e59f3048 ldr r3, [pc, #72] ; 2ac <fbuf_init+0x94>
260: e3a02602 mov r2, #2097152 ; 0x200000
264: e5832000 str r2, [r3]
268: e59f3040 ldr r3, [pc, #64] ; 2b0 <fbuf_init+0x98>
26c: e59f2040 ldr r2, [pc, #64] ; 2b4 <fbuf_init+0x9c>
270: e5832000 str r2, [r3]
274: e1a00000 nop ; (mov r0, r0)
278: e1a00003 mov r0, r3
27c: e28bd000 add sp, fp, #0
280: e49db004 pop {fp} ; (ldr fp, [sp], #4)
284: e12fff1e bx lr
288: 00000000 .word 0x00000000
28c: 1000001c .word 0x1000001c
290: 00002c77 .word 0x00002c77
294: 10120000 .word 0x10120000
298: 3f1f3f9c .word 0x3f1f3f9c
29c: 10120004 .word 0x10120004
2a0: 090b61df .word 0x090b61df
2a4: 10120008 .word 0x10120008
2a8: 071f1800 .word 0x071f1800
2ac: 10120010 .word 0x10120010
2b0: 10120018 .word 0x10120018
2b4: 0000082b .word 0x0000082b
000002b8 <draw_box>:
2b8: e52db004 push {fp} ; (str fp, [sp, #-4]!)
2bc: e28db000 add fp, sp, #0
2c0: e24dd01c sub sp, sp, #28
2c4: e50b0010 str r0, [fp, #-16]
2c8: e50b1014 str r1, [fp, #-20] ; 0xffffffec
2cc: e50b2018 str r2, [fp, #-24] ; 0xffffffe8
2d0: e50b301c str r3, [fp, #-28] ; 0xffffffe4
2d4: e3a03000 mov r3, #0
2d8: e50b3008 str r3, [fp, #-8]
2dc: ea00001c b 354 <draw_box+0x9c>
2e0: e3a03000 mov r3, #0
2e4: e50b300c str r3, [fp, #-12]
2e8: ea000012 b 338 <draw_box+0x80>
2ec: e59f3084 ldr r3, [pc, #132] ; 378 <draw_box+0xc0>
2f0: e5932000 ldr r2, [r3]
2f4: e51b100c ldr r1, [fp, #-12]
2f8: e51b3014 ldr r3, [fp, #-20] ; 0xffffffec
2fc: e0813003 add r3, r1, r3
300: e59f1074 ldr r1, [pc, #116] ; 37c <draw_box+0xc4>
304: e5911000 ldr r1, [r1]
308: e0010193 mul r1, r3, r1
30c: e51b3008 ldr r3, [fp, #-8]
310: e0811003 add r1, r1, r3
314: e51b3010 ldr r3, [fp, #-16]
318: e0813003 add r3, r1, r3
31c: e1a03103 lsl r3, r3, #2
320: e0823003 add r3, r2, r3
324: e51b201c ldr r2, [fp, #-28] ; 0xffffffe4
328: e5832000 str r2, [r3]
32c: e51b300c ldr r3, [fp, #-12]
330: e2833001 add r3, r3, #1
334: e50b300c str r3, [fp, #-12]
338: e51b200c ldr r2, [fp, #-12]
33c: e51b3018 ldr r3, [fp, #-24] ; 0xffffffe8
340: e1520003 cmp r2, r3
344: baffffe8 blt 2ec <draw_box+0x34>
348: e51b3008 ldr r3, [fp, #-8]
34c: e2833001 add r3, r3, #1
350: e50b3008 str r3, [fp, #-8]
354: e51b2008 ldr r2, [fp, #-8]
358: e51b3018 ldr r3, [fp, #-24] ; 0xffffffe8
35c: e1520003 cmp r2, r3
360: baffffde blt 2e0 <draw_box+0x28>
364: e1a00000 nop ; (mov r0, r0)
368: e1a00000 nop ; (mov r0, r0)
36c: e28bd000 add sp, fp, #0
370: e49db004 pop {fp} ; (ldr fp, [sp], #4)
374: e12fff1e bx lr
...
00000380 <timer_init>:
380: e52db004 push {fp} ; (str fp, [sp, #-4]!)
384: e28db000 add fp, sp, #0
388: e24dd00c sub sp, sp, #12
38c: e3a03000 mov r3, #0
390: e50b3008 str r3, [fp, #-8]
394: ea000048 b 4bc <timer_init+0x13c>
398: e51b3008 ldr r3, [fp, #-8]
39c: e1a03183 lsl r3, r3, #3
3a0: e59f2134 ldr r2, [pc, #308] ; 4dc <timer_init+0x15c>
3a4: e0833002 add r3, r3, r2
3a8: e50b300c str r3, [fp, #-12]
3ac: e51b3008 ldr r3, [fp, #-8]
3b0: e3530000 cmp r3, #0
3b4: 1a000002 bne 3c4 <timer_init+0x44>
3b8: e51b300c ldr r3, [fp, #-12]
3bc: e59f211c ldr r2, [pc, #284] ; 4e0 <timer_init+0x160>
3c0: e5832000 str r2, [r3]
3c4: e51b3008 ldr r3, [fp, #-8]
3c8: e3530001 cmp r3, #1
3cc: 1a000002 bne 3dc <timer_init+0x5c>
3d0: e51b300c ldr r3, [fp, #-12]
3d4: e59f2108 ldr r2, [pc, #264] ; 4e4 <timer_init+0x164>
3d8: e5832000 str r2, [r3]
3dc: e51b3008 ldr r3, [fp, #-8]
3e0: e3530002 cmp r3, #2
3e4: 1a000002 bne 3f4 <timer_init+0x74>
3e8: e51b300c ldr r3, [fp, #-12]
3ec: e59f20f4 ldr r2, [pc, #244] ; 4e8 <timer_init+0x168>
3f0: e5832000 str r2, [r3]
3f4: e51b3008 ldr r3, [fp, #-8]
3f8: e3530003 cmp r3, #3
3fc: 1a000002 bne 40c <timer_init+0x8c>
400: e51b300c ldr r3, [fp, #-12]
404: e59f20e0 ldr r2, [pc, #224] ; 4ec <timer_init+0x16c>
408: e5832000 str r2, [r3]
40c: e51b300c ldr r3, [fp, #-12]
410: e5933000 ldr r3, [r3]
414: e3a02000 mov r2, #0
418: e5832000 str r2, [r3]
41c: e51b300c ldr r3, [fp, #-12]
420: e5933000 ldr r3, [r3]
424: e2833004 add r3, r3, #4
428: e3e02000 mvn r2, #0
42c: e5832000 str r2, [r3]
430: e51b300c ldr r3, [fp, #-12]
434: e5933000 ldr r3, [r3]
438: e2833010 add r3, r3, #16
43c: e3a02000 mov r2, #0
440: e5832000 str r2, [r3]
444: e51b300c ldr r3, [fp, #-12]
448: e5933000 ldr r3, [r3]
44c: e2833014 add r3, r3, #20
450: e3a02000 mov r2, #0
454: e5832000 str r2, [r3]
458: e51b300c ldr r3, [fp, #-12]
45c: e5933000 ldr r3, [r3]
460: e3a02c01 mov r2, #256 ; 0x100
464: e5832000 str r2, [r3]
468: e51b300c ldr r3, [fp, #-12]
46c: e5933000 ldr r3, [r3]
470: e2833008 add r3, r3, #8
474: e3a02066 mov r2, #102 ; 0x66
478: e5832000 str r2, [r3]
47c: e51b300c ldr r3, [fp, #-12]
480: e5933000 ldr r3, [r3]
484: e2833018 add r3, r3, #24
488: e3a02b07 mov r2, #7168 ; 0x1c00
48c: e5832000 str r2, [r3]
490: e51b300c ldr r3, [fp, #-12]
494: e5933000 ldr r3, [r3]
498: e5932000 ldr r2, [r3]
49c: e3822040 orr r2, r2, #64 ; 0x40
4a0: e5832000 str r2, [r3]
4a4: e51b300c ldr r3, [fp, #-12]
4a8: e3a02000 mov r2, #0
4ac: e5832004 str r2, [r3, #4]
4b0: e51b3008 ldr r3, [fp, #-8]
4b4: e2833001 add r3, r3, #1
4b8: e50b3008 str r3, [fp, #-8]
4bc: e51b3008 ldr r3, [fp, #-8]
4c0: e3530003 cmp r3, #3
4c4: daffffb3 ble 398 <timer_init+0x18>
4c8: e1a00000 nop ; (mov r0, r0)
4cc: e1a00000 nop ; (mov r0, r0)
4d0: e28bd000 add sp, fp, #0
4d4: e49db004 pop {fp} ; (ldr fp, [sp], #4)
4d8: e12fff1e bx lr
4dc: 00000000 .word 0x00000000
4e0: 101e2000 .word 0x101e2000
4e4: 101e2020 .word 0x101e2020
4e8: 101e3000 .word 0x101e3000
4ec: 101e3020 .word 0x101e3020
000004f0 <timer_clearInterupt>:
4f0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
4f4: e28db000 add fp, sp, #0
4f8: e24dd014 sub sp, sp, #20
4fc: e50b0010 str r0, [fp, #-16]
500: e51b3010 ldr r3, [fp, #-16]
504: e1a03183 lsl r3, r3, #3
508: e59f2028 ldr r2, [pc, #40] ; 538 <timer_clearInterupt+0x48>
50c: e0833002 add r3, r3, r2
510: e50b3008 str r3, [fp, #-8]
514: e51b3008 ldr r3, [fp, #-8]
518: e5933000 ldr r3, [r3]
51c: e283300c add r3, r3, #12
520: e3e02000 mvn r2, #0
524: e5832000 str r2, [r3]
528: e1a00000 nop ; (mov r0, r0)
52c: e28bd000 add sp, fp, #0
530: e49db004 pop {fp} ; (ldr fp, [sp], #4)
534: e12fff1e bx lr
538: 00000000 .word 0x00000000
0000053c <timer_handler>:
53c: e92d4800 push {fp, lr}
540: e28db004 add fp, sp, #4
544: e24dd010 sub sp, sp, #16
548: e50b0010 str r0, [fp, #-16]
54c: e51b3010 ldr r3, [fp, #-16]
550: e1a03183 lsl r3, r3, #3
554: e59f203c ldr r2, [pc, #60] ; 598 <timer_handler+0x5c>
558: e0833002 add r3, r3, r2
55c: e50b3008 str r3, [fp, #-8]
560: e51b3008 ldr r3, [fp, #-8]
564: e5933004 ldr r3, [r3, #4]
568: e2832001 add r2, r3, #1
56c: e51b3008 ldr r3, [fp, #-8]
570: e5832004 str r2, [r3, #4]
574: e51b0010 ldr r0, [fp, #-16]
578: ebfffffe bl 4f0 <timer_clearInterupt>
57c: e59f1018 ldr r1, [pc, #24] ; 59c <timer_handler+0x60>
580: e59f0018 ldr r0, [pc, #24] ; 5a0 <timer_handler+0x64>
584: ebfffffe bl 1c0 <uprints>
588: e1a00000 nop ; (mov r0, r0)
58c: e24bd004 sub sp, fp, #4
590: e8bd4800 pop {fp, lr}
594: e12fff1e bx lr
...
000005a4 <timer_start>:
5a4: e92d4800 push {fp, lr}
5a8: e28db004 add fp, sp, #4
5ac: e24dd010 sub sp, sp, #16
5b0: e50b0010 str r0, [fp, #-16]
5b4: e59f1044 ldr r1, [pc, #68] ; 600 <timer_start+0x5c>
5b8: e59f0044 ldr r0, [pc, #68] ; 604 <timer_start+0x60>
5bc: ebfffffe bl 1c0 <uprints>
5c0: e51b3010 ldr r3, [fp, #-16]
5c4: e1a03183 lsl r3, r3, #3
5c8: e59f2038 ldr r2, [pc, #56] ; 608 <timer_start+0x64>
5cc: e0833002 add r3, r3, r2
5d0: e50b3008 str r3, [fp, #-8]
5d4: e51b3008 ldr r3, [fp, #-8]
5d8: e5933000 ldr r3, [r3]
5dc: e2832008 add r2, r3, #8
5e0: e5922000 ldr r2, [r2]
5e4: e2833008 add r3, r3, #8
5e8: e3822080 orr r2, r2, #128 ; 0x80
5ec: e5832000 str r2, [r3]
5f0: e1a00000 nop ; (mov r0, r0)
5f4: e24bd004 sub sp, fp, #4
5f8: e8bd4800 pop {fp, lr}
5fc: e12fff1e bx lr
600: 00000010 .word 0x00000010
...
0000060c <timer_stop>:
60c: e52db004 push {fp} ; (str fp, [sp, #-4]!)
610: e28db000 add fp, sp, #0
614: e24dd014 sub sp, sp, #20
618: e50b0010 str r0, [fp, #-16]
61c: e51b3010 ldr r3, [fp, #-16]
620: e1a03183 lsl r3, r3, #3
624: e59f2028 ldr r2, [pc, #40] ; 654 <timer_stop+0x48>
628: e0833002 add r3, r3, r2
62c: e50b3008 str r3, [fp, #-8]
630: e51b3008 ldr r3, [fp, #-8]
634: e5933000 ldr r3, [r3]
638: e2833008 add r3, r3, #8
63c: e3a0207f mov r2, #127 ; 0x7f
640: e5832000 str r2, [r3]
644: e1a00000 nop ; (mov r0, r0)
648: e28bd000 add sp, fp, #0
64c: e49db004 pop {fp} ; (ldr fp, [sp], #4)
650: e12fff1e bx lr
654: 00000000 .word 0x00000000
00000658 <undef_handler>:
658: e92d4800 push {fp, lr}
65c: e28db004 add fp, sp, #4
660: e59f1014 ldr r1, [pc, #20] ; 67c <undef_handler+0x24>
664: e59f0014 ldr r0, [pc, #20] ; 680 <undef_handler+0x28>
668: ebfffffe bl 1c0 <uprints>
66c: e1a00000 nop ; (mov r0, r0)
670: e24bd004 sub sp, fp, #4
674: e8bd4800 pop {fp, lr}
678: e12fff1e bx lr
67c: 00000020 .word 0x00000020
680: 00000000 .word 0x00000000
00000684 <swi_handler>:
684: e92d4800 push {fp, lr}
688: e28db004 add fp, sp, #4
68c: e59f1014 ldr r1, [pc, #20] ; 6a8 <swi_handler+0x24>
690: e59f0014 ldr r0, [pc, #20] ; 6ac <swi_handler+0x28>
694: ebfffffe bl 1c0 <uprints>
698: e1a00000 nop ; (mov r0, r0)
69c: e24bd004 sub sp, fp, #4
6a0: e8bd4800 pop {fp, lr}
6a4: e12fff1e bx lr
6a8: 00000020 .word 0x00000020
6ac: 00000000 .word 0x00000000
000006b0 <prefetch_abort_handler>:
6b0: e92d4800 push {fp, lr}
6b4: e28db004 add fp, sp, #4
6b8: e59f1014 ldr r1, [pc, #20] ; 6d4 <prefetch_abort_handler+0x24>
6bc: e59f0014 ldr r0, [pc, #20] ; 6d8 <prefetch_abort_handler+0x28>
6c0: ebfffffe bl 1c0 <uprints>
6c4: e1a00000 nop ; (mov r0, r0)
6c8: e24bd004 sub sp, fp, #4
6cc: e8bd4800 pop {fp, lr}
6d0: e12fff1e bx lr
6d4: 00000020 .word 0x00000020
6d8: 00000000 .word 0x00000000
000006dc <data_abort_handler>:
6dc: e92d4800 push {fp, lr}
6e0: e28db004 add fp, sp, #4
6e4: e59f1014 ldr r1, [pc, #20] ; 700 <data_abort_handler+0x24>
6e8: e59f0014 ldr r0, [pc, #20] ; 704 <data_abort_handler+0x28>
6ec: ebfffffe bl 1c0 <uprints>
6f0: e1a00000 nop ; (mov r0, r0)
6f4: e24bd004 sub sp, fp, #4
6f8: e8bd4800 pop {fp, lr}
6fc: e12fff1e bx lr
700: 00000020 .word 0x00000020
704: 00000000 .word 0x00000000
00000708 <fiq_handler>:
708: e92d4800 push {fp, lr}
70c: e28db004 add fp, sp, #4
710: e59f1014 ldr r1, [pc, #20] ; 72c <fiq_handler+0x24>
714: e59f0014 ldr r0, [pc, #20] ; 730 <fiq_handler+0x28>
718: ebfffffe bl 1c0 <uprints>
71c: e1a00000 nop ; (mov r0, r0)
720: e24bd004 sub sp, fp, #4
724: e8bd4800 pop {fp, lr}
728: e12fff1e bx lr
72c: 00000020 .word 0x00000020
730: 00000000 .word 0x00000000
00000734 <copy_vector>:
734: e52db004 push {fp} ; (str fp, [sp, #-4]!)
738: e28db000 add fp, sp, #0
73c: e24dd00c sub sp, sp, #12
740: e59f3050 ldr r3, [pc, #80] ; 798 <copy_vector+0x64>
744: e50b3008 str r3, [fp, #-8]
748: e3a03000 mov r3, #0
74c: e50b300c str r3, [fp, #-12]
750: ea000007 b 774 <copy_vector+0x40>
754: e51b2008 ldr r2, [fp, #-8]
758: e2823004 add r3, r2, #4
75c: e50b3008 str r3, [fp, #-8]
760: e51b300c ldr r3, [fp, #-12]
764: e2831004 add r1, r3, #4
768: e50b100c str r1, [fp, #-12]
76c: e5922000 ldr r2, [r2]
770: e5832000 str r2, [r3]
774: e51b3008 ldr r3, [fp, #-8]
778: e59f201c ldr r2, [pc, #28] ; 79c <copy_vector+0x68>
77c: e1530002 cmp r3, r2
780: 3afffff3 bcc 754 <copy_vector+0x20>
784: e1a00000 nop ; (mov r0, r0)
788: e1a00000 nop ; (mov r0, r0)
78c: e28bd000 add sp, fp, #0
790: e49db004 pop {fp} ; (ldr fp, [sp], #4)
794: e12fff1e bx lr
...
000007a0 <kbd_init>:
7a0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
7a4: e28db000 add fp, sp, #0
7a8: e24dd00c sub sp, sp, #12
7ac: e59f302c ldr r3, [pc, #44] ; 7e0 <kbd_init+0x40>
7b0: e50b3008 str r3, [fp, #-8]
7b4: e51b3008 ldr r3, [fp, #-8]
7b8: e3a02014 mov r2, #20
7bc: e5c32000 strb r2, [r3]
7c0: e51b3008 ldr r3, [fp, #-8]
7c4: e283300c add r3, r3, #12
7c8: e3a02008 mov r2, #8
7cc: e5c32000 strb r2, [r3]
7d0: e1a00000 nop ; (mov r0, r0)
7d4: e28bd000 add sp, fp, #0
7d8: e49db004 pop {fp} ; (ldr fp, [sp], #4)
7dc: e12fff1e bx lr
7e0: 10006000 .word 0x10006000
000007e4 <IRQ_handler>:
7e4: e92d4800 push {fp, lr}
7e8: e28db004 add fp, sp, #4
7ec: e24dd008 sub sp, sp, #8
7f0: e3a03000 mov r3, #0
7f4: e50b3008 str r3, [fp, #-8]
7f8: e59f10a4 ldr r1, [pc, #164] ; 8a4 <IRQ_handler+0xc0>
7fc: e59f00a4 ldr r0, [pc, #164] ; 8a8 <IRQ_handler+0xc4>
800: ebfffffe bl 1c0 <uprints>
804: e59f30a0 ldr r3, [pc, #160] ; 8ac <IRQ_handler+0xc8>
808: e5933000 ldr r3, [r3]
80c: e5933000 ldr r3, [r3]
810: e2833004 add r3, r3, #4
814: e5933000 ldr r3, [r3]
818: e3530000 cmp r3, #0
81c: 1a000001 bne 828 <IRQ_handler+0x44>
820: e3a00000 mov r0, #0
824: ebfffffe bl 53c <timer_handler>
828: e59f307c ldr r3, [pc, #124] ; 8ac <IRQ_handler+0xc8>
82c: e5933004 ldr r3, [r3, #4]
830: e5933000 ldr r3, [r3]
834: e2833004 add r3, r3, #4
838: e5933000 ldr r3, [r3]
83c: e3530000 cmp r3, #0
840: 1a000001 bne 84c <IRQ_handler+0x68>
844: e3a00001 mov r0, #1
848: ebfffffe bl 53c <timer_handler>
84c: e59f3058 ldr r3, [pc, #88] ; 8ac <IRQ_handler+0xc8>
850: e5933008 ldr r3, [r3, #8]
854: e5933000 ldr r3, [r3]
858: e2833004 add r3, r3, #4
85c: e5933000 ldr r3, [r3]
860: e3530000 cmp r3, #0
864: 1a000001 bne 870 <IRQ_handler+0x8c>
868: e3a00002 mov r0, #2
86c: ebfffffe bl 53c <timer_handler>
870: e59f3034 ldr r3, [pc, #52] ; 8ac <IRQ_handler+0xc8>
874: e593300c ldr r3, [r3, #12]
878: e5933000 ldr r3, [r3]
87c: e2833004 add r3, r3, #4
880: e5933000 ldr r3, [r3]
884: e3530000 cmp r3, #0
888: 1a000001 bne 894 <IRQ_handler+0xb0>
88c: e3a00003 mov r0, #3
890: ebfffffe bl 53c <timer_handler>
894: e1a00000 nop ; (mov r0, r0)
898: e24bd004 sub sp, fp, #4
89c: e8bd4800 pop {fp, lr}
8a0: e12fff1e bx lr
8a4: 00000030 .word 0x00000030
...
000008b0 <main>:
8b0: e92d4800 push {fp, lr}
8b4: e28db004 add fp, sp, #4
8b8: e24dd010 sub sp, sp, #16
8bc: ebfffffe bl 218 <fbuf_init>
8c0: ebfffffe bl 0 <uart_init>
8c4: ebfffffe bl 380 <timer_init>
8c8: ebfffffe bl 7a0 <kbd_init>
8cc: e3a03000 mov r3, #0
8d0: e50b3008 str r3, [fp, #-8]
8d4: ea00000b b 908 <main+0x58>
8d8: e51b3008 ldr r3, [fp, #-8]
8dc: e1a03183 lsl r3, r3, #3
8e0: e59f20dc ldr r2, [pc, #220] ; 9c4 <main+0x114>
8e4: e0832002 add r2, r3, r2
8e8: e59f10d8 ldr r1, [pc, #216] ; 9c8 <main+0x118>
8ec: e51b3008 ldr r3, [fp, #-8]
8f0: e7812103 str r2, [r1, r3, lsl #2]
8f4: e51b0008 ldr r0, [fp, #-8]
8f8: ebfffffe bl 5a4 <timer_start>
8fc: e51b3008 ldr r3, [fp, #-8]
900: e2833001 add r3, r3, #1
904: e50b3008 str r3, [fp, #-8]
908: e51b3008 ldr r3, [fp, #-8]
90c: e3530003 cmp r3, #3
910: dafffff0 ble 8d8 <main+0x28>
914: e59f10b0 ldr r1, [pc, #176] ; 9cc <main+0x11c>
918: e59f00b0 ldr r0, [pc, #176] ; 9d0 <main+0x120>
91c: ebfffffe bl 1c0 <uprints>
920: e59f309c ldr r3, [pc, #156] ; 9c4 <main+0x114>
924: e5931004 ldr r1, [r3, #4]
928: e59f30a4 ldr r3, [pc, #164] ; 9d4 <main+0x124>
92c: e0c32391 smull r2, r3, r1, r3
930: e1a021c3 asr r2, r3, #3
934: e1a03fc1 asr r3, r1, #31
938: e0422003 sub r2, r2, r3
93c: e1a03002 mov r3, r2
940: e1a03183 lsl r3, r3, #3
944: e0433002 sub r3, r3, r2
948: e1a03183 lsl r3, r3, #3
94c: e0433002 sub r3, r3, r2
950: e1a03103 lsl r3, r3, #2
954: e0412003 sub r2, r1, r3
958: e1a03002 mov r3, r2
95c: e54b3009 strb r3, [fp, #-9]
960: e55b3009 ldrb r3, [fp, #-9]
964: e2833037 add r3, r3, #55 ; 0x37
968: e20330ff and r3, r3, #255 ; 0xff
96c: e1a01003 mov r1, r3
970: e59f0058 ldr r0, [pc, #88] ; 9d0 <main+0x120>
974: ebfffffe bl e4 <uputc>
978: e55b3009 ldrb r3, [fp, #-9]
97c: e383386e orr r3, r3, #7208960 ; 0x6e0000
980: e3833001 orr r3, r3, #1
984: e50b3010 str r3, [fp, #-16]
988: e51b3010 ldr r3, [fp, #-16]
98c: e3a02064 mov r2, #100 ; 0x64
990: e3a0100a mov r1, #10
994: e3a0000a mov r0, #10
998: ebfffffe bl 2b8 <draw_box>
99c: e59f3020 ldr r3, [pc, #32] ; 9c4 <main+0x114>
9a0: e5933004 ldr r3, [r3, #4]
9a4: e3530000 cmp r3, #0
9a8: 0affffdc beq 920 <main+0x70>
9ac: e3a03b32 mov r3, #51200 ; 0xc800
9b0: e3a02032 mov r2, #50 ; 0x32
9b4: e3a010fa mov r1, #250 ; 0xfa
9b8: e3a000c8 mov r0, #200 ; 0xc8
9bc: ebfffffe bl 2b8 <draw_box>
9c0: eaffffd6 b 920 <main+0x70>
...
9cc: 0000003c .word 0x0000003c
9d0: 00000000 .word 0x00000000
9d4: 094f2095 .word 0x094f2095
also my linker script:
ENTRY(start)
SECTIONS{
. = 0x10000;
.text : {*(.text)}
.data : {*(.data)}
.bss : {*(.bss)}
. =ALIGN(8);
. =. + 0x1000;
stack_top = .;
. = . + 0x1000;
irq_stack_top = .;
}
So I do not have a complete example but something looks wrong, really wrong that you will need to sort out. And maybe you are already through all of these basic steps to get to this point.
qemu-system-arm -M versatilepb -m 128M -kernel notmain.bin
Implies a binary memory image file as in objcopy -O binary is being used. And there is no addressing information, so some default built into that machine or simulation is being used. What is that address....
strap.s
mov sp,#0x10000
bl notmain
b .
.globl GETPC
GETPC:
mov r0,pc
bx lr
.globl PUT32
PUT32:
str r1,[r0]
bx lr
notmain.c
void PUT32 ( unsigned int, unsigned int );
unsigned int GETPC ( void );
#define UART_BASE 0x101F1000
#define UARTDR (UART_BASE+0x000)
static void uart_send ( unsigned int x )
{
PUT32(UARTDR,x);
}
static void hexstrings ( unsigned int d )
{
unsigned int rb;
unsigned int rc;
rb=32;
while(1)
{
rb-=4;
rc=(d>>rb)&0xF;
if(rc>9) rc+=0x37; else rc+=0x30;
uart_send(rc);
if(rb==0) break;
}
uart_send(0x20);
}
static void hexstring ( unsigned int d )
{
hexstrings(d);
uart_send(0x0D);
uart_send(0x0A);
}
int notmain ( void )
{
hexstring(GETPC());
return(0);
}
uart address culled from the source code to qemu. so far I find you can cheat and just write to the tx buffer, it does not actually emulate the time it takes to send out a character and overflow a fifo, etc. So I cheat.
/* memmap */
MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 32K
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.text*) } > ram
}
build
arm-none-eabi-as --warn --fatal-warnings -march=armv4t strap.s -o strap.o
arm-none-eabi-gcc -c -Wall -O2 -ffreestanding -march=armv4t notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles strap.o notmain.o -T memmap -o notmain.elf
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy notmain.elf -O binary notmain.bin
examine output
Disassembly of section .text:
00000000 <GETPC-0xc>:
0: e3a0d801 mov sp, #65536 ; 0x10000
4: eb000004 bl 1c <notmain>
8: eafffffe b 8 <GETPC-0x4>
0000000c <GETPC>:
c: e1a0000f mov r0, pc
10: e12fff1e bx lr
00000014 <PUT32>:
14: e5801000 str r1, [r0]
18: e12fff1e bx lr
0000001c <notmain>:
1c: e92d4070 push {r4, r5, r6, lr}
20: ebfffff9 bl c <GETPC>
24: e3a04020 mov r4, #32
my entry point is where I want it. I am not loading an elf I am loading a binary image. If I wanted the entry point to be different and load an elf it may be possible that using ENTRY() in the linker script then having the entry point wherever might work.
qemu-system-arm -M versatilepb -m 128M -kernel notmain.bin
then view the serial0 output of 00010014 so they are loading us at 0x10000 so change memmap
ram : ORIGIN = 0x00010000, LENGTH = 32K
Now your linker script implies it should have put your code at 0x10000 but
clearly it has not based on your disassembly, so how are you running anything at all. Also your entry point using a binary image is not the bootstrap it is not the first instructions you want to be executing. maybe you disassembled an object not the final binary?
So for fun before changing the memory map to 0x10000 if I instead
qemu-system-arm -M versatilepb -m 128M -kernel notmain.elf
Then I get 00000014 on the output. it used the address defined in the elf file.
If I add this
b .
.globl _start
_start:
mov sp,#0x10000
bl notmain
b .
and this
/* memmap */
ENTRY(_start)
MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 32K
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.text*) } > ram
}
and execute the elf I do get output of 00000018 so it is entering at the entry point not the first word of the loadable image.
run the .bin and you get no serial output as expected.
Change memmap to 0x10000 and run the elf you get 0x10018 as expected.
So that was a simple way to see how qemu loads our program.
so same build and linker script (with the 0x10000)
.globl _start
_start:
ldr pc,reset_handler
ldr pc,undefined_handler
ldr pc,swi_handler
ldr pc,prefetch_handler
ldr pc,data_handler
ldr pc,unused_handler
ldr pc,irq_handler
ldr pc,fiq_handler
reset_handler: .word reset
undefined_handler: .word hang
swi_handler: .word swi
prefetch_handler: .word hang
data_handler: .word hang
unused_handler: .word hang
irq_handler: .word hang
fiq_handler: .word hang
reset:
mov r0,#0x10000
mov r1,#0x00000
ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9}
stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9}
ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9}
stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9}
;# FIQ 110 10001
msr cpsr_c,#0xD1
mov sp,#0x1000
;# IRQ 110 10010
msr cpsr_c,#0xD2
mov sp,#0x2000
;# SVC 110 10011
msr cpsr_c,#0xD3
mov sp,#0x3000
;# ABT 110 10111
msr cpsr_c,#0xD7
mov sp,#0x4000
;# UND 110 11011
msr cpsr_c,#0xDB
mov sp,#0x5000
;# SYS 110 11111
msr cpsr_c,#0xDF
mov sp,#0x6000
;# SVC 110 10011
msr cpsr_c,#0xD3
bl notmain
hang:
b hang
swi:
push {r4-r12,lr}
bl swi_main
pop {r4-r12,lr}
movs pc,lr
.globl DO_SWI
DO_SWI:
push {lr}
svc 0
pop {lr}
bx lr
.globl GO_USER
GO_USER:
;# USER 110 10000
msr cpsr_c,#0xD0
bl gouser
b .
gouser:
bx r0
.globl GETMODE
GETMODE:
mrs r0,cpsr
bx lr
.globl GETPC
GETPC:
mov r0,pc
bx lr
.globl GETSP
GETSP:
mov r0,sp
bx lr
.globl PUT32
PUT32:
str r1,[r0]
bx lr
.globl GET32
GET32:
ldr r0,[r0]
bx lr
and
void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
unsigned int GETPC ( void );
unsigned int GETSP ( void );
unsigned int GETMODE ( void );
unsigned int GO_USER ( unsigned int );
unsigned int DO_SWI ( unsigned int, unsigned int, unsigned int, unsigned int );
#define UART_BASE 0x101F1000
#define UARTDR (UART_BASE+0x000)
#define UARTFR (UART_BASE+0x018)
static void uart_send ( unsigned int x )
{
while(1)
{
if(GET32(UARTFR)&(1<<7)) break;
}
PUT32(UARTDR,x);
}
static void hexstrings ( unsigned int d )
{
unsigned int rb;
unsigned int rc;
rb=32;
while(1)
{
rb-=4;
rc=(d>>rb)&0xF;
if(rc>9) rc+=0x37; else rc+=0x30;
uart_send(rc);
if(rb==0) break;
}
uart_send(0x20);
}
static void hexstring ( unsigned int d )
{
hexstrings(d);
uart_send(0x0D);
uart_send(0x0A);
}
unsigned int swi_main ( unsigned int a, unsigned int b, unsigned int c, unsigned int d )
{
hexstring(0xAABBCCDD);
switch(a)
{
case 0:
{
return(~b);
}
case 1:
{
return(GETMODE());
}
}
return(0);
}
void user_main ( void )
{
hexstring(GETMODE());
hexstring(GETSP());
hexstring(DO_SWI(0,0x1234,0,0));
hexstring(DO_SWI(1,0x1234,0,0));
}
int notmain ( void )
{
hexstring(GETMODE());
hexstring(GETSP());
GO_USER((unsigned int)user_main);
return(0);
}
get even a trivial swi in place first before attempting an interrupt. getting the exception table in place, the banked stack registers, etc. seems trivial but even with experience those things bite you and you end up chasing the wrong thing.
400001D3
00002FF8
200001D0
00005FF8
AABBCCDD
FFFFEDCB
AABBCCDD
600001D3
this was a bit overkill with mode changes and such, but it still has the swi handler in the right place. The code is linked for
notmain.elf: file format elf32-littlearm
Disassembly of section .text:
00010000 <_start>:
10000: e59ff018 ldr pc, [pc, #24] ; 10020 <reset_handler>
10004: e59ff018 ldr pc, [pc, #24] ; 10024 <undefined_handler>
10008: e59ff018 ldr pc, [pc, #24] ; 10028 <swi_handler>
1000c: e59ff018 ldr pc, [pc, #24] ; 1002c <prefetch_handler>
10010: e59ff018 ldr pc, [pc, #24] ; 10030 <data_handler>
10014: e59ff018 ldr pc, [pc, #24] ; 10034 <unused_handler>
10018: e59ff018 ldr pc, [pc, #24] ; 10038 <irq_handler>
1001c: e59ff018 ldr pc, [pc, #24] ; 1003c <fiq_handler>
00010020 <reset_handler>:
10020: 00010040 andeq r0, r1, r0, asr #32
00010024 <undefined_handler>:
10024: 00010090 muleq r1, r0, r0
packing the exception table with its pc-relative addresses and letting the toolchain do all the work of sorting out addresses for you, you can then simply copy it to 0x00000000 from 0x10000. It is probably fine but in your case I would at least put some level of alignment before your table, something makes me want to think it wants to be aligned. However you wish to copy it is your deal, I would not use C in a bootstrap, the habit creates problems from time to time that are easily avoided.
Knowing what we know of course if we linked for address 0x00000000 and used the elf file then we do not have to copy/move the exception table. It lands in the right place on load.
Newer cores have a VTOR register and you can simply choose a different exception or vector table address, but it does need to have a level of alignment that you cannot forget.
I did not go and research this timer, but I assume long before you attempted an interrupt you wrote very many throwaway programs that used polling to fully understand the timer and how to clear its interrupt, etc? Depending on the chip (not necessarily core) then there may also be arm side registers you can poll, disable interrupts into the core, poll the gvic or vpic or whatever it is called and see the interrupt hit the edge of the core, be able to turn it off, etc. Then.....enable it into the core now that you have mastered that peripheral. Sometimes leaving nothing left to work on, for some cores though there is some interrupt stuff that can only be done in an isr (how to detect and clear the interrupt source) this virtual machine predates that by a long time though, so no worries there.
so...
If that is your linker script then why is your output zero based, and why is the uart function up front and not the bootstrap entry point? If that is the disassembly of the final binary then there are all kinds of problems going on there.
I was seeing this as baremetal but forgetting qemu is loading linux-like so at some address like 0x8000, 0x10000, or 0x80000 are some examples, so yes you either need a core with a VTOR or copy the exception table over, and letting the tools build the addresses and pc-relative loads is the way to go. That copy is probably fine if you are actually booting right and executing it.
Then have you completely mastered that peripheral?
This is an emulated core so it may resemble one/some of the products from arm but remember they are not all identical some come with interrupt controllers some do not, some folks like the raspi folks disable that interrupt controller, etc. The base address of add on peripherals for real arm cores is based on the chip vendor not arm. Etc....Best to dig through the source code for the specific machine emulation and see what it is doing to truly get a qemu machine to work.
So maybe you have done all of these things and it still does not work. The question as written has some issues, the disassembly does not make sense for example. Need to resolve that. What if you try with an elf file first and an entry point then do the extra work to be able to run without the elf file and the bin file instead. Do not re-write but add more content to the question if you need further help. Unless someone else sees the issue with what has been presented.

Problem with selfmade bare-metal startup procedure for STM32F072-Nucleo Board

I'm currently trying to get a better understanding of what is happening after power-on until I reach the main() function of an embedded project. Furthermore I'll try to understand how startup code and linker scripts are incorporated during build and startup procedure as I never learned these things properly.
So I read and watched a bunch of tutorials (QuantumLeaps, Fastbit, Interrupt, Teivaz,...) and I think I got a basic understanding of what is going on.
To see if I really understood everything I tried the following:
For a STM32F0-Nucleo Board (STM32F072RB) I tried to create a bare-metal blinky LED project. The build toolchain I use is the arm-none-eabi-gcc compiler, GNU make and the CubeProgrammer by ST.
I want it to be as basic as possible. So linker script, startup code and all the stuff should be self-written, no third party files by ST or other sources should be utilized.
As you can already imagine, I couldn't make it work but also am not sure of where the error resides or what I understood wrongly...
Here you can find the reference manual of the used MCU.
And here are the files I wrote (inspired by the above mentioned tutorials):
Linker Script
ENTRY(Reset_Handler)
/*FLASH memory from 0x08000000 with 128K*/
/*RAM memory from 0x20000000 with 16K*/
MEMORY
{
FLASH(rx) : ORIGIN =0x08000000, LENGTH = 128K
SRAM(rwx) : ORIGIN =0x20000000, LENGTH = 16K
}
SECTIONS
{
.text :
{
KEEP(*(.vectors))
*(.text)
*(.text*) /*Maybe?*/
*(.rodata)
*(.rodata*)
. = ALIGN(4);
_etext = .;
}> FLASH /*AT> FLASH*/
.data :
{
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
}> SRAM AT> FLASH
.bss :
{
_sbss = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
}> SRAM
}
I saw in the official STM linker scripts that there are always two entries for each section ( *(.bss) and *(.bss*)). I don't understand why this is the case, the tutorials I saw were also inconsistent with this. Can someone explain this to me?
Startup Code (shortend the list of the handlers for displaying reasons)
#include "device.h"
//Tracking variables for memory sections
extern uint32_t _etext;
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sbss;
extern uint32_t _ebss;
// Prototypes
extern int main (void);
// Vector Table Prototypes + Default Handler
void Reset_Handler(void);
void Default_Handler(void);
void NMI_Handler(void) __attribute__((weak, alias("Default_Handler")));
void HardFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
void SVCall_Handler(void) __attribute__((weak, alias("Default_Handler")));
void PendSV_Handler(void) __attribute__((weak, alias("Default_Handler")));
void SysTick_Handler(void) __attribute__((weak, alias("Default_Handler")));
.
.
.
#define SRAM_START 0x20000000U
#define SRAM_SIZE (16U * 1024U) // 16KB
#define SRAM_END ((SRAM_START)+(SRAM_SIZE))
#define STACK_START SRAM_END //Stack will grow from high to low
//This can also be done in Linker script with PROVIDE(_stack = ORIGIN(SRAM) + LENGTH(SRAM));
// Vector Array
__attribute__ ((section(".vectors"))) uint32_t vectors[] =
{
(uint32_t)STACK_START, //First Entry holds address of initial Stack Pointer (MSP) which points at end of SRAM, note that only the address is kept here
(uint32_t)&Reset_Handler,
//(uint32_t)&NMI_Handler,
//(uint32_t)&HardFault_Handler,
(uint32_t)&NMI_Handler, //NMI Handler
(uint32_t)&HardFault_Handler, //HardFault Handler (0x0000 000C)
(uint32_t)0,
(uint32_t)0,
(uint32_t)0,
(uint32_t)0,
(uint32_t)0,
(uint32_t)0,
(uint32_t)0,
(uint32_t)&SVCall_Handler, //SVCall (0x0000 002C)
(uint32_t)0,
(uint32_t)0,
(uint32_t)&PendSV_Handler, //PendSV (0x000 0038)
(uint32_t)&SysTick_Handler, //Systick
.
.
.
};
//Definitions
void Reset_Handler ( void )
{
// Copy Data section to SRAM
uint32_t size = (uint32_t)&_edata - (uint32_t)&_sdata;
uint8_t *pDst = (uint8_t*)&_sdata; //SRAM
uint8_t *pSrc = (uint8_t*)&_etext; //FLASH
for(uint32_t i = 0 ; i<size ; i++)
{
*pDst++ = *pSrc++;
};
// Init bss section to 0
size = (uint32_t)&_ebss - (uint32_t)&_sbss;
pDst = (uint8_t*)&_sbss; //SRAM
for(uint32_t i = 0 ; i<size ; i++)
{
*pDst++ = 0;
};
//Call Main
main();
}
void Default_Handler(void)
{
}
The makefile:
CC=arm-none-eabi-gcc
CORE=cortex-m4
CFLAG= -c -mcpu=$(CORE) -std=gnu11 -mthumb -O0 -Wall -v -save-temps -fno-common
LDFLAG= -mcpu=$(CORE) -mthumb -nostdlib -T mySTM32_linkerScript.ld -Wl,-Map=final.Map
all: main.o myStartup.o final.elf
main.o: main.c
$(CC) $(CFLAG) -o $# $^
myStartup.o: myStartup.c
$(CC) $(CFLAG) -o $# $^
final.elf: main.o myStartup.o
$(CC) $(LDFLAG) -o $# $^
clean:
rm -rf *.o *.elf
test:
echo "This works"
The main file:
/* Includes */
#include "device.h"
void delay (int a);
int main(void)
{
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA->MODER |= GPIO_MODER_MODER5_0;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_5;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5_0;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR5_0;
/* Infinite loop */
while (1)
{
GPIOA->BSRR |= GPIO_BSRR_BS_5;
delay(50000);
GPIOA->BSRR |= GPIO_BSRR_BR_5;
delay(50000);
}
return 0;
}
void delay (int a)
{
int i,j;
for (i=0 ; i < a ; i++)
{
j++;
}
return;
}
I tried this code inside the CubeIDE with the #include "stm32f72xx.h" and it worked without problems. LED is blinking and registers got set correctly.
Lastly the corresponding device header file
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef unsigned long long uint64_t;
#define __IO volatile /*!< Defines 'read / write' permissions */
typedef struct
{
__IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */
__IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x04 */
__IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x08 */
__IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x0C */
__IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x10 */
__IO uint32_t AHBENR; /*!< RCC AHB peripheral clock register, Address offset: 0x14 */
__IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x18 */
__IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x1C */
__IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x20 */
__IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x24 */
__IO uint32_t AHBRSTR; /*!< RCC AHB peripheral reset register, Address offset: 0x28 */
__IO uint32_t CFGR2; /*!< RCC clock configuration register 2, Address offset: 0x2C */
__IO uint32_t CFGR3; /*!< RCC clock configuration register 3, Address offset: 0x30 */
__IO uint32_t CR2; /*!< RCC clock control register 2, Address offset: 0x34 */
} RCC_TypeDef;
typedef struct
{
__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */
__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
__IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */
__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */
__IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */
__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */
__IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x1A */
__IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */
__IO uint32_t AFR[2]; /*!< GPIO alternate function low register, Address offset: 0x20-0x24 */
__IO uint32_t BRR; /*!< GPIO bit reset register, Address offset: 0x28 */
} GPIO_TypeDef;
#define PERIPH_BASE 0x40000000UL
#define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000UL)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000UL)
#define RCC_BASE (AHBPERIPH_BASE + 0x00001000UL)
#define RCC ((RCC_TypeDef *) RCC_BASE)
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x00000000UL)
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
#define RCC_AHBENR_GPIOAEN_Pos (17U)
#define RCC_AHBENR_GPIOAEN_Msk (0x1UL << RCC_AHBENR_GPIOAEN_Pos) /*!< 0x00020000 */
#define RCC_AHBENR_GPIOAEN RCC_AHBENR_GPIOAEN_Msk /*!< GPIOA clock enable */
#define GPIO_MODER_MODER5_Pos (10U)
#define GPIO_MODER_MODER5_Msk (0x3UL << GPIO_MODER_MODER5_Pos) /*!< 0x00000C00 */
#define GPIO_MODER_MODER5 GPIO_MODER_MODER5_Msk
#define GPIO_MODER_MODER5_0 (0x1UL << GPIO_MODER_MODER5_Pos) /*!< 0x00000400 */
#define GPIO_MODER_MODER5_1 (0x2UL << GPIO_MODER_MODER5_Pos) /*!< 0x00000800 */
#define GPIO_OTYPER_OT_5 (0x00000020U)
#define GPIO_OSPEEDR_OSPEEDR5_Pos (10U)
#define GPIO_OSPEEDR_OSPEEDR5_Msk (0x3UL << GPIO_OSPEEDR_OSPEEDR5_Pos) /*!< 0x00000C00 */
#define GPIO_OSPEEDR_OSPEEDR5 GPIO_OSPEEDR_OSPEEDR5_Msk
#define GPIO_OSPEEDR_OSPEEDR5_0 (0x1UL << GPIO_OSPEEDR_OSPEEDR5_Pos) /*!< 0x00000400 */
#define GPIO_OSPEEDR_OSPEEDR5_1 (0x2UL << GPIO_OSPEEDR_OSPEEDR5_Pos) /*!< 0x00000800 */
#define GPIO_OSPEEDER_OSPEEDR5 GPIO_OSPEEDR_OSPEEDR5
#define GPIO_OSPEEDER_OSPEEDR5_0 GPIO_OSPEEDR_OSPEEDR5_0
#define GPIO_OSPEEDER_OSPEEDR5_1 GPIO_OSPEEDR_OSPEEDR5_1
#define GPIO_PUPDR_PUPDR5_Pos (10U)
#define GPIO_PUPDR_PUPDR5_Msk (0x3UL << GPIO_PUPDR_PUPDR5_Pos) /*!< 0x00000C00 */
#define GPIO_PUPDR_PUPDR5 GPIO_PUPDR_PUPDR5_Msk
#define GPIO_PUPDR_PUPDR5_0 (0x1UL << GPIO_PUPDR_PUPDR5_Pos) /*!< 0x00000400 */
#define GPIO_PUPDR_PUPDR5_1 (0x2UL << GPIO_PUPDR_PUPDR5_Pos) /*!< 0x00000800 */
#define GPIO_BSRR_BS_5 (0x00000020U)
#define GPIO_BSRR_BR_5 (0x00200000U)
As you probably already realized, I was extremly lazy and just copied the relevant register defines from the official stm32f072 header.
After a "make all" the build proceeds without errors or warnings.
The generated map file looks ok to me:
Memory Configuration
Name Origin Length Attributes
FLASH 0x08000000 0x00020000 xr
SRAM 0x20000000 0x00004000 xrw
*default* 0x00000000 0xffffffff
Linker script and memory map
LOAD main.o
LOAD myStartup.o
.text 0x08000000 0x204
*(.vectors)
.vectors 0x08000000 0xc0 myStartup.o
0x08000000 vectors
*(.text)
.text 0x080000c0 0xb4 main.o
0x080000c0 main
0x08000148 delay
.text 0x08000174 0x90 myStartup.o
0x08000174 Reset_Handler
0x080001f8 EXTI2_3_Handler
0x080001f8 SVCall_Handler
0x080001f8 HardFault_Handler
0x080001f8 SysTick_Handler
0x080001f8 I2C1_Handler
0x080001f8 PendSV_Handler
0x080001f8 NMI_Handler
0x080001f8 PVD_VDDIO2_Handler
0x080001f8 WWDG_Handler
0x080001f8 RTC_Handler
0x080001f8 TIM1_CC_Handler
0x080001f8 USART3_8_Handler
0x080001f8 EXTI4_15_Handler
0x080001f8 DMA_Ch4_7_Handler
0x080001f8 TSC_Handler
0x080001f8 FLASH_Handler
0x080001f8 USB_Handler
0x080001f8 TIM2_Handler
0x080001f8 USART1_Handler
0x080001f8 TIM3_Handler
0x080001f8 Default_Handler
0x080001f8 CEC_CAN_Handler
0x080001f8 TIM17_Handler
0x080001f8 EXTI0_1_Handler
0x080001f8 SPI2_Handler
0x080001f8 TIM16_Handler
0x080001f8 DMA_Ch1_Handler
0x080001f8 I2C2_Handler
0x080001f8 TIM6_DAC_VDDIO2_Handler
0x080001f8 TIM14_Handler
0x080001f8 USART2_Handler
0x080001f8 SPI1_Handler
0x080001f8 RCC_CRS_Handler
0x080001f8 TIM15_Handler
0x080001f8 TIM7_Handler
0x080001f8 TIM1_BRK_UP_Handler
0x080001f8 ADC_COMP_Handler
0x080001f8 DMA_Ch2_3_Handler
*(.text*)
*(.rodata)
*(.rodata*)
0x08000204 . = ALIGN (0x4)
0x08000204 _etext = .
.glue_7 0x08000204 0x0
.glue_7 0x08000204 0x0 linker stubs
.glue_7t 0x08000204 0x0
.glue_7t 0x08000204 0x0 linker stubs
.vfp11_veneer 0x08000204 0x0
.vfp11_veneer 0x08000204 0x0 linker stubs
.v4_bx 0x08000204 0x0
.v4_bx 0x08000204 0x0 linker stubs
.iplt 0x08000204 0x0
.iplt 0x08000204 0x0 main.o
.rel.dyn 0x08000204 0x0
.rel.iplt 0x08000204 0x0 main.o
.data 0x20000000 0x0 load address 0x08000204
0x20000000 _sdata = .
*(.data)
.data 0x20000000 0x0 main.o
.data 0x20000000 0x0 myStartup.o
*(.data*)
0x20000000 . = ALIGN (0x4)
0x20000000 _edata = .
.igot.plt 0x20000000 0x0 load address 0x08000204
.igot.plt 0x20000000 0x0 main.o
.bss 0x20000000 0x0 load address 0x08000204
0x20000000 _sbss = .
*(.bss)
.bss 0x20000000 0x0 main.o
.bss 0x20000000 0x0 myStartup.o
*(.bss*)
*(COMMON)
0x20000000 . = ALIGN (0x4)
0x20000000 _ebss = .
OUTPUT(final.elf elf32-littlearm)
LOAD linker stubs
.comment 0x00000000 0x49
.comment 0x00000000 0x49 main.o
0x4a (size before relaxing)
.comment 0x00000049 0x4a myStartup.o
.ARM.attributes
0x00000000 0x2e
.ARM.attributes
0x00000000 0x2e main.o
.ARM.attributes
0x0000002e 0x2e myStartup.o
I still don't know what the additional added sections are for but decided to ingore them for the time being.
So I tried to load the .elf file onto my board using the CubeProgrammer but I see no blinking LED.
The cube programmer has the option to access the registers and they also show that my code was not executed at all. Nonetheless I can see that the vector table handlers got set (all pointing to the default handler) like I would expect them to. (If wanted I can add screenshots).
Because of that, my guess would be, that there is something missing or wrong with my startup code, linker script and/or makefile...
I'm sorry for the long post but if you find the time, can someone please help me to get this project running and helping me understand what is going on behind the curtains?
Thank you in advance
Best regards
Evox402
edit(21-12-09):
final.elf: file format elf32-littlearm
Disassembly of section .text:
08000000 <vectors>:
8000000: 20004000 andcs r4, r0, r0
8000004: 08000175 stmdaeq r0, {r0, r2, r4, r5, r6, r8}
8000008: 080001f9 stmdaeq r0, {r0, r3, r4, r5, r6, r7, r8}
800000c: 080001f9 stmdaeq r0, {r0, r3, r4, r5, r6, r7, r8}
...
800002c: 080001f9 stmdaeq r0, {r0, r3, r4, r5, r6, r7, r8}
...
8000038: 080001f9 stmdaeq r0, {r0, r3, r4, r5, r6, r7, r8}
800003c: 080001f9 stmdaeq r0, {r0, r3, r4, r5, r6, r7, r8}
. . . .
80000b8: 080001f9 stmdaeq r0, {r0, r3, r4, r5, r6, r7, r8}
80000bc: 080001f9 stmdaeq r0, {r0, r3, r4, r5, r6, r7, r8}
080000c0 <main>:
80000c0: b580 push {r7, lr}
80000c2: af00 add r7, sp, #0
80000c4: 4b1f ldr r3, [pc, #124] ; (8000144 <main+0x84>)
80000c6: 695b ldr r3, [r3, #20]
80000c8: 4a1e ldr r2, [pc, #120] ; (8000144 <main+0x84>)
80000ca: f443 3300 orr.w r3, r3, #131072 ; 0x20000
80000ce: 6153 str r3, [r2, #20]
80000d0: f04f 4390 mov.w r3, #1207959552 ; 0x48000000
80000d4: 681b ldr r3, [r3, #0]
80000d6: f04f 4290 mov.w r2, #1207959552 ; 0x48000000
80000da: f443 6380 orr.w r3, r3, #1024 ; 0x400
80000de: 6013 str r3, [r2, #0]
80000e0: f04f 4390 mov.w r3, #1207959552 ; 0x48000000
80000e4: 685b ldr r3, [r3, #4]
80000e6: f04f 4290 mov.w r2, #1207959552 ; 0x48000000
80000ea: f023 0320 bic.w r3, r3, #32
80000ee: 6053 str r3, [r2, #4]
80000f0: f04f 4390 mov.w r3, #1207959552 ; 0x48000000
80000f4: 689b ldr r3, [r3, #8]
80000f6: f04f 4290 mov.w r2, #1207959552 ; 0x48000000
80000fa: f443 6380 orr.w r3, r3, #1024 ; 0x400
80000fe: 6093 str r3, [r2, #8]
8000100: f04f 4390 mov.w r3, #1207959552 ; 0x48000000
8000104: 68db ldr r3, [r3, #12]
8000106: f04f 4290 mov.w r2, #1207959552 ; 0x48000000
800010a: f423 6380 bic.w r3, r3, #1024 ; 0x400
800010e: 60d3 str r3, [r2, #12]
8000110: f04f 4390 mov.w r3, #1207959552 ; 0x48000000
8000114: 699b ldr r3, [r3, #24]
8000116: f04f 4290 mov.w r2, #1207959552 ; 0x48000000
800011a: f043 0320 orr.w r3, r3, #32
800011e: 6193 str r3, [r2, #24]
8000120: f24c 3050 movw r0, #50000 ; 0xc350
8000124: f000 f810 bl 8000148 <delay>
8000128: f04f 4390 mov.w r3, #1207959552 ; 0x48000000
800012c: 699b ldr r3, [r3, #24]
800012e: f04f 4290 mov.w r2, #1207959552 ; 0x48000000
8000132: f443 1300 orr.w r3, r3, #2097152 ; 0x200000
8000136: 6193 str r3, [r2, #24]
8000138: f24c 3050 movw r0, #50000 ; 0xc350
800013c: f000 f804 bl 8000148 <delay>
8000140: e7e6 b.n 8000110 <main+0x50>
8000142: bf00 nop
8000144: 40021000 andmi r1, r2, r0
08000148 <delay>:
8000148: b480 push {r7}
800014a: b085 sub sp, #20
800014c: af00 add r7, sp, #0
800014e: 6078 str r0, [r7, #4]
8000150: 2300 movs r3, #0
8000152: 60fb str r3, [r7, #12]
8000154: e005 b.n 8000162 <delay+0x1a>
8000156: 68bb ldr r3, [r7, #8]
8000158: 3301 adds r3, #1
800015a: 60bb str r3, [r7, #8]
800015c: 68fb ldr r3, [r7, #12]
800015e: 3301 adds r3, #1
8000160: 60fb str r3, [r7, #12]
8000162: 68fa ldr r2, [r7, #12]
8000164: 687b ldr r3, [r7, #4]
8000166: 429a cmp r2, r3
8000168: dbf5 blt.n 8000156 <delay+0xe>
800016a: bf00 nop
800016c: 3714 adds r7, #20
800016e: 46bd mov sp, r7
8000170: bc80 pop {r7}
8000172: 4770 bx lr
08000174 <Reset_Handler>:
8000174: b580 push {r7, lr}
8000176: b086 sub sp, #24
8000178: af00 add r7, sp, #0
800017a: 4a1a ldr r2, [pc, #104] ; (80001e4 <Reset_Handler+0x70>)
800017c: 4b1a ldr r3, [pc, #104] ; (80001e8 <Reset_Handler+0x74>)
800017e: 1ad3 subs r3, r2, r3
8000180: 607b str r3, [r7, #4]
8000182: 4b19 ldr r3, [pc, #100] ; (80001e8 <Reset_Handler+0x74>)
8000184: 617b str r3, [r7, #20]
8000186: 4b19 ldr r3, [pc, #100] ; (80001ec <Reset_Handler+0x78>)
8000188: 613b str r3, [r7, #16]
800018a: 2300 movs r3, #0
800018c: 60fb str r3, [r7, #12]
800018e: e00a b.n 80001a6 <Reset_Handler+0x32>
8000190: 693a ldr r2, [r7, #16]
8000192: 1c53 adds r3, r2, #1
8000194: 613b str r3, [r7, #16]
8000196: 697b ldr r3, [r7, #20]
8000198: 1c59 adds r1, r3, #1
800019a: 6179 str r1, [r7, #20]
800019c: 7812 ldrb r2, [r2, #0]
800019e: 701a strb r2, [r3, #0]
80001a0: 68fb ldr r3, [r7, #12]
80001a2: 3301 adds r3, #1
80001a4: 60fb str r3, [r7, #12]
80001a6: 68fa ldr r2, [r7, #12]
80001a8: 687b ldr r3, [r7, #4]
80001aa: 429a cmp r2, r3
80001ac: d3f0 bcc.n 8000190 <Reset_Handler+0x1c>
80001ae: 4a10 ldr r2, [pc, #64] ; (80001f0 <Reset_Handler+0x7c>)
80001b0: 4b10 ldr r3, [pc, #64] ; (80001f4 <Reset_Handler+0x80>)
80001b2: 1ad3 subs r3, r2, r3
80001b4: 607b str r3, [r7, #4]
80001b6: 4b0f ldr r3, [pc, #60] ; (80001f4 <Reset_Handler+0x80>)
80001b8: 617b str r3, [r7, #20]
80001ba: 2300 movs r3, #0
80001bc: 60bb str r3, [r7, #8]
80001be: e007 b.n 80001d0 <Reset_Handler+0x5c>
80001c0: 697b ldr r3, [r7, #20]
80001c2: 1c5a adds r2, r3, #1
80001c4: 617a str r2, [r7, #20]
80001c6: 2200 movs r2, #0
80001c8: 701a strb r2, [r3, #0]
80001ca: 68bb ldr r3, [r7, #8]
80001cc: 3301 adds r3, #1
80001ce: 60bb str r3, [r7, #8]
80001d0: 68ba ldr r2, [r7, #8]
80001d2: 687b ldr r3, [r7, #4]
80001d4: 429a cmp r2, r3
80001d6: d3f3 bcc.n 80001c0 <Reset_Handler+0x4c>
80001d8: f7ff ff72 bl 80000c0 <main>
80001dc: bf00 nop
80001de: 3718 adds r7, #24
80001e0: 46bd mov sp, r7
80001e2: bd80 pop {r7, pc}
80001e4: 20000000 andcs r0, r0, r0
80001e8: 20000000 andcs r0, r0, r0
80001ec: 08000204 stmdaeq r0, {r2, r9}
80001f0: 20000000 andcs r0, r0, r0
80001f4: 20000000 andcs r0, r0, r0
080001f8 <Default_Handler>:
80001f8: b480 push {r7}
80001fa: af00 add r7, sp, #0
80001fc: bf00 nop
80001fe: 46bd mov sp, r7
8000200: bc80 pop {r7}
8000202: 4770 bx lr
Disassembly of section .comment:
00000000 <.comment>:
0: 3a434347 bcc 10d0d24 <vectors-0x6f2f2dc>
4: 4e472820 cdpmi 8, 4, cr2, cr7, cr0, {1}
8: 72412055 subvc r2, r1, #85 ; 0x55
c: 6d45206d stclvs 0, cr2, [r5, #-436] ; 0xfffffe4c
10: 64646562 strbtvs r6, [r4], #-1378 ; 0xfffffa9e
14: 54206465 strtpl r6, [r0], #-1125 ; 0xfffffb9b
18: 636c6f6f cmnvs ip, #444 ; 0x1bc
1c: 6e696168 powvsez f6, f1, #0.0
20: 2e303120 rsfcssp f3, f0, f0
24: 30322d33 eorscc r2, r2, r3, lsr sp
28: 312e3132 ; <UNDEFINED> instruction: 0x312e3132
2c: 31202930 ; <UNDEFINED> instruction: 0x31202930
30: 2e332e30 mrccs 14, 1, r2, cr3, cr0, {1}
34: 30322031 eorscc r2, r2, r1, lsr r0
38: 38303132 ldmdacc r0!, {r1, r4, r5, r8, ip, sp}
3c: 28203432 stmdacs r0!, {r1, r4, r5, sl, ip, sp}
40: 656c6572 strbvs r6, [ip, #-1394]! ; 0xfffffa8e
44: 29657361 stmdbcs r5!, {r0, r5, r6, r8, r9, ip, sp, lr}^
...
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 00002d41 andeq r2, r0, r1, asr #26
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 00000023 andeq r0, r0, r3, lsr #32
10: 2d453705 stclcs 7, cr3, [r5, #-20] ; 0xffffffec
14: 0d06004d stceq 0, cr0, [r6, #-308] ; 0xfffffecc
18: 02094d07 andeq r4, r9, #448 ; 0x1c0
1c: 01140412 tsteq r4, r2, lsl r4
20: 03170115 tsteq r7, #1073741829 ; 0x40000005
24: 01190118 tsteq r9, r8, lsl r1
28: 061e011a ; <UNDEFINED> instruction: 0x061e011a
2c: Address 0x0000002c is out of bounds.

how to check if objdump disassembles a binary file for the correct architure?

I would like to disassemble armv7m executable using the command arm-none-eabi-objdump -d -S -marm my_elf_file.elf ..i got this output
file format elf32-littlearm
Disassembly of section .init:
00008000 <_init>:
8000: b5f8 push {r3, r4, r5, r6, r7, lr}
8002: bf00 nop
8004: bcf8 pop {r3, r4, r5, r6, r7}
8006: bc08 pop {r3}
8008: 469e mov lr, r3
800a: 4770 bx lr
Disassembly of section .text:
0000800c <_GLOBAL__sub_I__ZN9__gnu_cxx9__freeresEv>:
800c: b538 push {r3, r4, r5, lr}
800e: f44f 651e mov.w r5, #2528 ; 0x9e0
8012: 4c07 ldr r4, [pc, #28] ; (8030 <_GLOBAL__sub_I__ZN9__gnu_cxx9__freeresEv+0x24>)
8014: 4628 mov r0, r5
8016: 60e5 str r5, [r4, #12]
8018: f005 fbe6 bl d7e8 <malloc>
801c: 60a0 str r0, [r4, #8]
801e: b120 cbz r0, 802a <_GLOBAL__sub_I__ZN9__gnu_cxx9__freeresEv+0x1e>
8020: 2300 movs r3, #0
8022: 6060 str r0, [r4, #4]
8024: 6005 str r5, [r0, #0]
8026: 6043 str r3, [r0, #4]
8028: bd38 pop {r3, r4, r5, pc}
802a: 60e0 str r0, [r4, #12]
802c: 6060 str r0, [r4, #4]
802e: bd38 pop {r3, r4, r5, pc}
8030: 000228b4 .word 0x000228b4
how to make sure that the disassembly generated is for armv7m and not another arm architure ?

GCC is not finding the built-in 'memcpy'

I am doing work on an ARM Cortex-M microcontroller using the arm-none-eabi version of GCC. I am also using -fnostdlib and -fnostdin.
In my code I am using memcpy and strlen. Both of these functions are built-in functions as per the GCC manual. When I use these function as is or as __buitin_..., I get undefined reference to ....
Why is GCC not generating the code as expected?
builtins are not real functions. Compiler is free to replace them with the "normal" function call. ARM b as in this example:
void *m(void *a, void *b, size_t size)
{
return __builtin_memcpy(a,b,size);
}
void *m1(void *a, void *b)
{
return __builtin_memcpy(a,b,16);
}
void *m2(void *a, void *b)
{
return __builtin_memcpy(a,b,200);
}
volatile int a[1000],b[10000], c[1000];
int main(void)
{
m((void *)a,(void *)b,16);
__asm(":::m");
m((void *)a,(void *)c,400);
}
The resulting code will depend on the ARM architecture (if not aligned accesses are legal).
CORTEX-M4 CORTEX-M0
m: m:
b memcpy push {r4, lr}
m1: bl memcpy
push {r4, r5} pop {r4, pc}
ldr r5, [r1] # unaligned m1:
ldr r4, [r1, #4] # unaligned push {r4, lr}
ldr r2, [r1, #8] # unaligned movs r2, #16
ldr r1, [r1, #12] # unaligned bl memcpy
str r1, [r0, #12] # unaligned pop {r4, pc}
str r5, [r0] # unaligned m2:
str r4, [r0, #4] # unaligned push {r4, lr}
str r2, [r0, #8] # unaligned movs r2, #200
pop {r4, r5} bl memcpy
bx lr pop {r4, pc}
m2: main:
movs r2, #200 ldr r0, .L6
b memcpy push {r4, r5, r6, lr}
main: movs r2, r0
push {r4, lr} ldr r3, .L6+4
ldr r3, .L8 ldmia r3!, {r1, r4, r5}
ldr r4, .L8+4 stmia r2!, {r1, r4, r5}
ldm r3, {r0, r1, r2, r3} ldr r3, [r3]
stm r4, {r0, r1, r2, r3} str r3, [r2]
:::m :::m
mov r2, #400 movs r2, #200
mov r0, r4 ldr r1, .L6+8
ldr r1, .L8+8 lsls r2, r2, #1
bl memcpy bl memcpy
movs r0, #0 movs r0, #0
pop {r4, pc} pop {r4, r5, r6, pc}
.L8: .L6:
.word b .word a
.word a .word b
.word c .word c
https://godbolt.org/z/fh68cv

Bare metal C Function not working

I have been writing a kernel for the Raspberry Pi 2 using C. To do so I have been following the Valvers and Baking Pi (written in Assembly) tutorials to do so. But each time I try to port the function to set a pin to output from the Baking Pi OK03 tutorial to C the led stops blinking (but the code compiles just fine). I have rewritten the function several times but I cannot get it to work.
Here is my code:
main.c:
#include "gpio.h"
int main(void) __attribute__((naked));
int main(void)
{
gpio = (unsigned int*)GPIO_BASE;
/* Write 1 to the GPIO16 init nibble in the Function Select 1 GPIO
peripheral register to enable GPIO16 as an output */
// gpio[LED_GPFSEL] |= (1 << LED_GPFBIT);
pinMode(47, 1);
// Never return from here
while(1)
{
for(tim = 0; tim < 500000; tim++)
;
/* Set the LED GPIO pin low ( Turn OK LED on for original Pi, and off
for plus models )*/
gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);
for(tim = 0; tim < 500000; tim++)
;
/* Set the LED GPIO pin high ( Turn OK LED off for original Pi, and on
for plus models )*/
gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
}
}
gpio.h:
#ifndef GPIO_H
#define GPIO_H
#ifdef RPI2
#define GPIO_BASE 0x3F200000UL
#else
#define GPIO_BASE 0x20200000UL
#endif
#if defined( RPIBPLUS ) || defined( RPI2 )
#define LED_GPFSEL GPIO_GPFSEL4
#define LED_GPFBIT 21
#define LED_GPSET GPIO_GPSET1
#define LED_GPCLR GPIO_GPCLR1
#define LED_GPIO_BIT 15
#else
#define LED_GPFSEL GPIO_GPFSEL1
#define LED_GPFBIT 18
#define LED_GPSET GPIO_GPSET0
#define LED_GPCLR GPIO_GPCLR0
#define LED_GPIO_BIT 16
#endif
#define GPIO_GPFSEL0 0
#define GPIO_GPFSEL1 1
#define GPIO_GPFSEL2 2
#define GPIO_GPFSEL3 3
#define GPIO_GPFSEL4 4
#define GPIO_GPFSEL5 5
#define GPIO_GPSET0 7
#define GPIO_GPSET1 8
#define GPIO_GPCLR0 10
#define GPIO_GPCLR1 11
#define GPIO_GPLEV0 13
#define GPIO_GPLEV1 14
#define GPIO_GPEDS0 16
#define GPIO_GPEDS1 17
#define GPIO_GPREN0 19
#define GPIO_GPREN1 20
#define GPIO_GPFEN0 22
#define GPIO_GPFEN1 23
#define GPIO_GPHEN0 25
#define GPIO_GPHEN1 26
#define GPIO_GPLEN0 28
#define GPIO_GPLEN1 29
#define GPIO_GPAREN0 31
#define GPIO_GPAREN1 32
#define GPIO_GPAFEN0 34
#define GPIO_GPAFEN1 35
#define GPIO_GPPUD 37
#define GPIO_GPPUDCLK0 38
#define GPIO_GPPUDCLK1 39
/** GPIO Register set */
volatile unsigned int* gpio;
/** Simple loop variable */
volatile unsigned int tim;
// Function to change a pin's mode
int pinMode(int pinnum, int mode);
#endif
gpio.c:
#include "gpio.h"
/* Docs: The Pi has 54 GPIO pins and 6 Function Selec Registers (FSR). Each FSR
controls 10 GPIO pins and each FSR is made of 33 bits (each pin is controlled by
3 bits of the FSR). To know which pins of the FSR control each GPIO pin the formula
3n is used (where n is the pin number). In order for this to work, the pin number must be minor or equal to 9. Therefore if the pin is higher than 9, 10 units are subtracted from the pin number and one unit is added to the fsr variable. This loops until the pin number is lower or equal to 9. */
int pinMode(int pinnum, int mode) {
// Variable declaration and initialization
int fsr = 0;
int fsrbit;
// Let's check the pin does exist
if (pinnum < 0 || pinnum > 53) {
// Abort, there is no such pin.
return 1;
}
else if (mode < 0 || mode > 1) {
// Abort, invalid mode (Actually there are 7 modes but we will only use 2)
return 1;
}
// Create a pointer to the GPIO perhiperal register so we can speak to it
gpio = (unsigned int*)GPIO_BASE;
// And calculate wich FSR we should use
/* do {
if (pinnum > 9) {
pinnum -= 10;
fsr++;
}
} while (pinnum > 9); */
if (pinnum > 9) {
while (pinnum > 9) {
pinnum -= 10;
fsr++;
}
}
// Then we calculate the bytes of the fsreg to use
fsrbit = pinnum * 3;
// Finally let's set the pin to the desired mode
gpio[fsr] |= (mode << fsrbit);
return 0;
}
Please help, I have been stuck with this problem for weeks.
PS: In case you want the kernel disassembly:
kernel_disassembly.asm:
./kernel.elf: file format elf32-littlearm
Disassembly of section .text:
00008000 <main>:
8000: e3082200 movw r2, #33280 ; 0x8200
8004: e3402001 movt r2, #1
8008: e3a03000 mov r3, #0
800c: e3433f20 movt r3, #16160 ; 0x3f20
8010: e5823000 str r3, [r2]
8014: e3a01001 mov r1, #1
8018: e3a0002f mov r0, #47 ; 0x2f
801c: eb000032 bl 80ec <pinMode>
8020: e30831fc movw r3, #33276 ; 0x81fc
8024: e3403001 movt r3, #1
8028: e3a02000 mov r2, #0
802c: e5832000 str r2, [r3]
8030: ea000006 b 8050 <main+0x50>
8034: e30831fc movw r3, #33276 ; 0x81fc
8038: e3403001 movt r3, #1
803c: e5933000 ldr r3, [r3]
8040: e2832001 add r2, r3, #1
8044: e30831fc movw r3, #33276 ; 0x81fc
8048: e3403001 movt r3, #1
804c: e5832000 str r2, [r3]
8050: e30831fc movw r3, #33276 ; 0x81fc
8054: e3403001 movt r3, #1
8058: e5932000 ldr r2, [r3]
805c: e30a311f movw r3, #41247 ; 0xa11f
8060: e3403007 movt r3, #7
8064: e1520003 cmp r2, r3
8068: 9afffff1 bls 8034 <main+0x34>
806c: e3083200 movw r3, #33280 ; 0x8200
8070: e3403001 movt r3, #1
8074: e5933000 ldr r3, [r3]
8078: e283302c add r3, r3, #44 ; 0x2c
807c: e3a02902 mov r2, #32768 ; 0x8000
8080: e5832000 str r2, [r3]
8084: e30831fc movw r3, #33276 ; 0x81fc
8088: e3403001 movt r3, #1
808c: e3a02000 mov r2, #0
8090: e5832000 str r2, [r3]
8094: ea000006 b 80b4 <main+0xb4>
8098: e30831fc movw r3, #33276 ; 0x81fc
809c: e3403001 movt r3, #1
80a0: e5933000 ldr r3, [r3]
80a4: e2832001 add r2, r3, #1
80a8: e30831fc movw r3, #33276 ; 0x81fc
80ac: e3403001 movt r3, #1
80b0: e5832000 str r2, [r3]
80b4: e30831fc movw r3, #33276 ; 0x81fc
80b8: e3403001 movt r3, #1
80bc: e5932000 ldr r2, [r3]
80c0: e30a311f movw r3, #41247 ; 0xa11f
80c4: e3403007 movt r3, #7
80c8: e1520003 cmp r2, r3
80cc: 9afffff1 bls 8098 <main+0x98>
80d0: e3083200 movw r3, #33280 ; 0x8200
80d4: e3403001 movt r3, #1
80d8: e5933000 ldr r3, [r3]
80dc: e2833020 add r3, r3, #32
80e0: e3a02902 mov r2, #32768 ; 0x8000
80e4: e5832000 str r2, [r3]
80e8: eaffffcc b 8020 <main+0x20>
000080ec <pinMode>:
80ec: e52db004 push {fp} ; (str fp, [sp, #-4]!)
80f0: e28db000 add fp, sp, #0
80f4: e24dd014 sub sp, sp, #20
80f8: e50b0010 str r0, [fp, #-16]
80fc: e50b1014 str r1, [fp, #-20] ; 0xffffffec
8100: e3a03000 mov r3, #0
8104: e50b3008 str r3, [fp, #-8]
8108: e51b3010 ldr r3, [fp, #-16]
810c: e3530000 cmp r3, #0
8110: ba000002 blt 8120 <pinMode+0x34>
8114: e51b3010 ldr r3, [fp, #-16]
8118: e3530035 cmp r3, #53 ; 0x35
811c: da000001 ble 8128 <pinMode+0x3c>
8120: e3a03001 mov r3, #1
8124: ea000030 b 81ec <pinMode+0x100>
8128: e51b3014 ldr r3, [fp, #-20] ; 0xffffffec
812c: e3530000 cmp r3, #0
8130: ba000002 blt 8140 <pinMode+0x54>
8134: e51b3014 ldr r3, [fp, #-20] ; 0xffffffec
8138: e3530001 cmp r3, #1
813c: da000001 ble 8148 <pinMode+0x5c>
8140: e3a03001 mov r3, #1
8144: ea000028 b 81ec <pinMode+0x100>
8148: e3082200 movw r2, #33280 ; 0x8200
814c: e3402001 movt r2, #1
8150: e3a03000 mov r3, #0
8154: e3433f20 movt r3, #16160 ; 0x3f20
8158: e5823000 str r3, [r2]
815c: e51b3010 ldr r3, [fp, #-16]
8160: e3530009 cmp r3, #9
8164: da000009 ble 8190 <pinMode+0xa4>
8168: ea000005 b 8184 <pinMode+0x98>
816c: e51b3010 ldr r3, [fp, #-16]
8170: e243300a sub r3, r3, #10
8174: e50b3010 str r3, [fp, #-16]
8178: e51b3008 ldr r3, [fp, #-8]
817c: e2833001 add r3, r3, #1
8180: e50b3008 str r3, [fp, #-8]
8184: e51b3010 ldr r3, [fp, #-16]
8188: e3530009 cmp r3, #9
818c: cafffff6 bgt 816c <pinMode+0x80>
8190: e51b3010 ldr r3, [fp, #-16]
8194: e3a02003 mov r2, #3
8198: e0030392 mul r3, r2, r3
819c: e50b300c str r3, [fp, #-12]
81a0: e3083200 movw r3, #33280 ; 0x8200
81a4: e3403001 movt r3, #1
81a8: e5932000 ldr r2, [r3]
81ac: e51b3008 ldr r3, [fp, #-8]
81b0: e1a03103 lsl r3, r3, #2
81b4: e0822003 add r2, r2, r3
81b8: e3083200 movw r3, #33280 ; 0x8200
81bc: e3403001 movt r3, #1
81c0: e5931000 ldr r1, [r3]
81c4: e51b3008 ldr r3, [fp, #-8]
81c8: e1a03103 lsl r3, r3, #2
81cc: e0813003 add r3, r1, r3
81d0: e5933000 ldr r3, [r3]
81d4: e51b0014 ldr r0, [fp, #-20] ; 0xffffffec
81d8: e51b100c ldr r1, [fp, #-12]
81dc: e1a01110 lsl r1, r0, r1
81e0: e1833001 orr r3, r3, r1
81e4: e5823000 str r3, [r2]
81e8: e3a03000 mov r3, #0
81ec: e1a00003 mov r0, r3
81f0: e24bd000 sub sp, fp, #0
81f4: e49db004 pop {fp} ; (ldr fp, [sp], #4)
81f8: e12fff1e bx lr
Disassembly of section .bss:
000181fc <__bss_start>:
181fc: 00000000 andeq r0, r0, r0
00018200 <gpio>:
18200: 00000000 andeq r0, r0, r0
Disassembly of section .comment:
00000000 <.comment>:
0: 3a434347 bcc 10d0d24 <_stack+0x1050d24>
4: 4e472820 cdpmi 8, 4, cr2, cr7, cr0, {1}
8: 6f542055 svcvs 0x00542055
c: 20736c6f rsbscs r6, r3, pc, ror #24
10: 20726f66 rsbscs r6, r2, r6, ror #30
14: 204d5241 subcs r5, sp, r1, asr #4
18: 65626d45 strbvs r6, [r2, #-3397]! ; 0xfffff2bb
1c: 64656464 strbtvs r6, [r5], #-1124 ; 0xfffffb9c
20: 6f725020 svcvs 0x00725020
24: 73736563 cmnvc r3, #415236096 ; 0x18c00000
28: 2973726f ldmdbcs r3!, {r0, r1, r2, r3, r5, r6, r9, ip, sp, lr}^
2c: 342e3520 strtcc r3, [lr], #-1312 ; 0xfffffae0
30: 3220312e eorcc r3, r0, #-2147483637 ; 0x8000000b
34: 30363130 eorscc r3, r6, r0, lsr r1
38: 20393139 eorscs r3, r9, r9, lsr r1
3c: 6c657228 sfmvs f7, 2, [r5], #-160 ; 0xffffff60
40: 65736165 ldrbvs r6, [r3, #-357]! ; 0xfffffe9b
44: 415b2029 cmpmi fp, r9, lsr #32
48: 652f4d52 strvs r4, [pc, #-3410]! ; fffff2fe <_stack+0xfff7f2fe>
4c: 6465626d strbtvs r6, [r5], #-621 ; 0xfffffd93
50: 2d646564 cfstr64cs mvdx6, [r4, #-400]! ; 0xfffffe70
54: 72622d35 rsbvc r2, r2, #3392 ; 0xd40
58: 68636e61 stmdavs r3!, {r0, r5, r6, r9, sl, fp, sp, lr}^
5c: 76657220 strbtvc r7, [r5], -r0, lsr #4
60: 6f697369 svcvs 0x00697369
64: 3432206e ldrtcc r2, [r2], #-110 ; 0xffffff92
68: 36393430 ; <UNDEFINED> instruction: 0x36393430
6c: Address 0x000000000000006c is out of bounds.
Disassembly of section .debug_aranges:
00000000 <.debug_aranges>:
0: 0000001c andeq r0, r0, ip, lsl r0
4: 00000002 andeq r0, r0, r2
8: 00040000 andeq r0, r4, r0
c: 00000000 andeq r0, r0, r0
10: 00008000 andeq r8, r0, r0
14: 000000ec andeq r0, r0, ip, ror #1
...
20: 0000001c andeq r0, r0, ip, lsl r0
24: 00760002 rsbseq r0, r6, r2
28: 00040000 andeq r0, r4, r0
2c: 00000000 andeq r0, r0, r0
30: 000080ec andeq r8, r0, ip, ror #1
34: 00000110 andeq r0, r0, r0, lsl r1
...
Disassembly of section .debug_info:
00000000 <.debug_info>:
0: 00000072 andeq r0, r0, r2, ror r0
4: 00000004 andeq r0, r0, r4
8: 01040000 mrseq r0, (UNDEF: 4)
c: 0000003f andeq r0, r0, pc, lsr r0
10: 0000340c andeq r3, r0, ip, lsl #8
14: 00000d00 andeq r0, r0, r0, lsl #26
18: 00800000 addeq r0, r0, r0
1c: 0000ec00 andeq lr, r0, r0, lsl #24
20: 00000000 andeq r0, r0, r0
24: 00d10200 sbcseq r0, r1, r0, lsl #4
28: 04010000 streq r0, [r1], #-0
2c: 0000003a andeq r0, r0, sl, lsr r0
30: 00008000 andeq r8, r0, r0
34: 000000ec andeq r0, r0, ip, ror #1
38: 04039c01 streq r9, [r3], #-3073 ; 0xfffff3ff
3c: 746e6905 strbtvc r6, [lr], #-2309 ; 0xfffff6fb
40: 002f0400 eoreq r0, pc, r0, lsl #8
44: 42020000 andmi r0, r2, #0
48: 00000052 andeq r0, r0, r2, asr r0
4c: 82000305 andhi r0, r0, #335544320 ; 0x14000000
50: 04050001 streq r0, [r5], #-1
54: 0000005f andeq r0, r0, pc, asr r0
58: 00070406 andeq r0, r7, r6, lsl #8
5c: 07000000 streq r0, [r0, -r0]
60: 00000058 andeq r0, r0, r8, asr r0
64: 6d697408 cfstrdvs mvd7, [r9, #-32]! ; 0xffffffe0
68: 5f450200 svcpl 0x00450200
6c: 05000000 streq r0, [r0, #-0]
70: 0181fc03 orreq pc, r1, r3, lsl #24
74: 00af0000 adceq r0, pc, r0
78: 00040000 andeq r0, r4, r0
7c: 00000076 andeq r0, r0, r6, ror r0
80: 003f0104 eorseq r0, pc, r4, lsl #2
84: dd0c0000 stcle 0, cr0, [ip, #-0]
88: 0d000000 stceq 0, cr0, [r0, #-0]
8c: ec000000 stc 0, cr0, [r0], {-0}
90: 10000080 andne r0, r0, r0, lsl #1
94: 61000001 tstvs r0, r1
98: 02000000 andeq r0, r0, #0
9c: 000000ef andeq r0, r0, pc, ror #1
a0: 00770b01 rsbseq r0, r7, r1, lsl #22
a4: 80ec0000 rschi r0, ip, r0
a8: 01100000 tsteq r0, r0
ac: 9c010000 stcls 0, cr0, [r1], {-0}
b0: 00000077 andeq r0, r0, r7, ror r0
b4: 0000d603 andeq sp, r0, r3, lsl #12
b8: 770b0100 strvc r0, [fp, -r0, lsl #2]
bc: 02000000 andeq r0, r0, #0
c0: f7036c91 ; <UNDEFINED> instruction: 0xf7036c91
c4: 01000000 mrseq r0, (UNDEF: 0)
c8: 0000770b andeq r7, r0, fp, lsl #14
cc: 68910200 ldmvs r1, {r9}
d0: 72736604 rsbsvc r6, r3, #4, 12 ; 0x400000
d4: 770d0100 strvc r0, [sp, -r0, lsl #2]
d8: 02000000 andeq r0, r0, #0
dc: e8057491 stmda r5, {r0, r4, r7, sl, ip, sp, lr}
e0: 01000000 mrseq r0, (UNDEF: 0)
e4: 0000770e andeq r7, r0, lr, lsl #14
e8: 70910200 addsvc r0, r1, r0, lsl #4
ec: 05040600 streq r0, [r4, #-1536] ; 0xfffffa00
f0: 00746e69 rsbseq r6, r4, r9, ror #28
f4: 00002f07 andeq r2, r0, r7, lsl #30
f8: 8f420200 svchi 0x00420200
fc: 05000000 streq r0, [r0, #-0]
100: 01820003 orreq r0, r2, r3
104: 9c040800 stcls 8, cr0, [r4], {-0}
108: 09000000 stmdbeq r0, {} ; <UNPREDICTABLE>
10c: 00000704 andeq r0, r0, r4, lsl #14
110: 950a0000 strls r0, [sl, #-0]
114: 0b000000 bleq 11c <main-0x7ee4>
118: 006d6974 rsbeq r6, sp, r4, ror r9
11c: 009c4502 addseq r4, ip, r2, lsl #10
120: 03050000 movweq r0, #20480 ; 0x5000
124: 000181fc strdeq r8, [r1], -ip
...
Disassembly of section .debug_abbrev:
00000000 <.debug_abbrev>:
0: 25011101 strcs r1, [r1, #-257] ; 0xfffffeff
4: 030b130e movweq r1, #45838 ; 0xb30e
8: 110e1b0e tstne lr, lr, lsl #22
c: 10061201 andne r1, r6, r1, lsl #4
10: 02000017 andeq r0, r0, #23
14: 193f002e ldmdbne pc!, {r1, r2, r3, r5} ; <UNPREDICTABLE>
18: 0b3a0e03 bleq e8382c <_stack+0xe0382c>
1c: 19270b3b stmdbne r7!, {r0, r1, r3, r4, r5, r8, r9, fp}
20: 01111349 tsteq r1, r9, asr #6
24: 18400612 stmdane r0, {r1, r4, r9, sl}^
28: 00194296 mulseq r9, r6, r2
2c: 00240300 eoreq r0, r4, r0, lsl #6
30: 0b3e0b0b bleq f82c64 <_stack+0xf02c64>
34: 00000803 andeq r0, r0, r3, lsl #16
38: 03003404 movweq r3, #1028 ; 0x404
3c: 3b0b3a0e blcc 2ce87c <_stack+0x24e87c>
40: 3f13490b svccc 0x0013490b
44: 00180219 andseq r0, r8, r9, lsl r2
48: 000f0500 andeq r0, pc, r0, lsl #10
4c: 13490b0b movtne r0, #39691 ; 0x9b0b
50: 24060000 strcs r0, [r6], #-0
54: 3e0b0b00 vmlacc.f64 d0, d11, d0
58: 000e030b andeq r0, lr, fp, lsl #6
5c: 00350700 eorseq r0, r5, r0, lsl #14
60: 00001349 andeq r1, r0, r9, asr #6
64: 03003408 movweq r3, #1032 ; 0x408
68: 3b0b3a08 blcc 2ce890 <_stack+0x24e890>
6c: 3f13490b svccc 0x0013490b
70: 00180219 andseq r0, r8, r9, lsl r2
74: 11010000 mrsne r0, (UNDEF: 1)
78: 130e2501 movwne r2, #58625 ; 0xe501
7c: 1b0e030b blne 380cb0 <_stack+0x300cb0>
80: 1201110e andne r1, r1, #-2147483645 ; 0x80000003
84: 00171006 andseq r1, r7, r6
88: 012e0200 ; <UNDEFINED> instruction: 0x012e0200
8c: 0e03193f mcreq 9, 0, r1, cr3, cr15, {1}
90: 0b3b0b3a bleq ec2d80 <_stack+0xe42d80>
94: 13491927 movtne r1, #39207 ; 0x9927
98: 06120111 ; <UNDEFINED> instruction: 0x06120111
9c: 42971840 addsmi r1, r7, #64, 16 ; 0x400000
a0: 00130119 andseq r0, r3, r9, lsl r1
a4: 00050300 andeq r0, r5, r0, lsl #6
a8: 0b3a0e03 bleq e838bc <_stack+0xe038bc>
ac: 13490b3b movtne r0, #39739 ; 0x9b3b
b0: 00001802 andeq r1, r0, r2, lsl #16
b4: 03003404 movweq r3, #1028 ; 0x404
b8: 3b0b3a08 blcc 2ce8e0 <_stack+0x24e8e0>
bc: 0213490b andseq r4, r3, #180224 ; 0x2c000
c0: 05000018 streq r0, [r0, #-24] ; 0xffffffe8
c4: 0e030034 mcreq 0, 0, r0, cr3, cr4, {1}
c8: 0b3b0b3a bleq ec2db8 <_stack+0xe42db8>
cc: 18021349 stmdane r2, {r0, r3, r6, r8, r9, ip}
d0: 24060000 strcs r0, [r6], #-0
d4: 3e0b0b00 vmlacc.f64 d0, d11, d0
d8: 0008030b andeq r0, r8, fp, lsl #6
dc: 00340700 eorseq r0, r4, r0, lsl #14
e0: 0b3a0e03 bleq e838f4 <_stack+0xe038f4>
e4: 13490b3b movtne r0, #39739 ; 0x9b3b
e8: 1802193f stmdane r2, {r0, r1, r2, r3, r4, r5, r8, fp, ip}
ec: 0f080000 svceq 0x00080000
f0: 490b0b00 stmdbmi fp, {r8, r9, fp}
f4: 09000013 stmdbeq r0, {r0, r1, r4}
f8: 0b0b0024 bleq 2c0190 <_stack+0x240190>
fc: 0e030b3e vmoveq.16 d3[0], r0
100: 350a0000 strcc r0, [sl, #-0]
104: 00134900 andseq r4, r3, r0, lsl #18
108: 00340b00 eorseq r0, r4, r0, lsl #22
10c: 0b3a0803 bleq e82120 <_stack+0xe02120>
110: 13490b3b movtne r0, #39739 ; 0x9b3b
114: 1802193f stmdane r2, {r0, r1, r2, r3, r4, r5, r8, fp, ip}
118: Address 0x0000000000000118 is out of bounds.
Disassembly of section .debug_line:
00000000 <.debug_line>:
0: 0000005d andeq r0, r0, sp, asr r0
4: 002b0002 eoreq r0, fp, r2
8: 01020000 mrseq r0, (UNDEF: 2)
c: 000d0efb strdeq r0, [sp], -fp
10: 01010101 tsteq r1, r1, lsl #2
14: 01000000 mrseq r0, (UNDEF: 0)
18: 73010000 movwvc r0, #4096 ; 0x1000
1c: 00006372 andeq r6, r0, r2, ror r3
20: 6e69616d powvsez f6, f1, #5.0
24: 0100632e tsteq r0, lr, lsr #6
28: 70670000 rsbvc r0, r7, r0
2c: 682e6f69 stmdavs lr!, {r0, r3, r5, r6, r8, r9, sl, fp, sp, lr}
30: 00000100 andeq r0, r0, r0, lsl #2
34: 02050000 andeq r0, r5, #0
38: 00008000 andeq r8, r0, r0
3c: 6ba31316 blvs fe8c4c9c <_stack+0xfe844c9c>
40: 03040200 movweq r0, #16896 ; 0x4200
44: 02009e06 andeq r9, r0, #6, 28 ; 0x60
48: 06d60104 ldrbeq r0, [r6], r4, lsl #2
4c: 0200bcdb andeq fp, r0, #56064 ; 0xdb00
50: 9e060304 cdpls 3, 0, cr0, cr6, cr4, {0}
54: 01040200 mrseq r0, R12_usr
58: bbdb06d6 bllt ff6c1bb8 <_stack+0xff641bb8>
5c: 01000202 tsteq r0, r2, lsl #4
60: 00005f01 andeq r5, r0, r1, lsl #30
64: 2b000200 blcs 86c <main-0x7794>
68: 02000000 andeq r0, r0, #0
6c: 0d0efb01 vstreq d15, [lr, #-4]
70: 01010100 mrseq r0, (UNDEF: 17)
74: 00000001 andeq r0, r0, r1
78: 01000001 tsteq r0, r1
7c: 00637273 rsbeq r7, r3, r3, ror r2
80: 69706700 ldmdbvs r0!, {r8, r9, sl, sp, lr}^
84: 00632e6f rsbeq r2, r3, pc, ror #28
88: 67000001 strvs r0, [r0, -r1]
8c: 2e6f6970 mcrcs 9, 3, r6, cr15, cr0, {3}
90: 00010068 andeq r0, r1, r8, rrx
94: 05000000 streq r0, [r0, #-0]
98: 0080ec02 addeq lr, r0, r2, lsl #24
9c: 010a0300 mrseq r0, (UNDEF: 58)
a0: 02004da0 andeq r4, r0, #160, 26 ; 0x2800
a4: 66060104 strvs r0, [r6], -r4, lsl #2
a8: 004c6806 subeq r6, ip, r6, lsl #16
ac: 06010402 streq r0, [r1], -r2, lsl #8
b0: 4d680666 stclmi 6, cr0, [r8, #-408]! ; 0xfffffe68
b4: 672f67a6 strvs r6, [pc, -r6, lsr #15]!
b8: 02846c64 addeq r6, r4, #100, 24 ; 0x6400
bc: 022f1424 eoreq r1, pc, #36, 8 ; 0x24000000
c0: 01010008 tsteq r1, r8
Disassembly of section .debug_frame:
00000000 <.debug_frame>:
0: 0000000c andeq r0, r0, ip
4: ffffffff ; <UNDEFINED> instruction: 0xffffffff
8: 7c020001 stcvc 0, cr0, [r2], {1}
c: 000d0c0e andeq r0, sp, lr, lsl #24
10: 0000000c andeq r0, r0, ip
14: 00000000 andeq r0, r0, r0
18: 00008000 andeq r8, r0, r0
1c: 000000ec andeq r0, r0, ip, ror #1
20: 0000000c andeq r0, r0, ip
24: ffffffff ; <UNDEFINED> instruction: 0xffffffff
28: 7c020001 stcvc 0, cr0, [r2], {1}
2c: 000d0c0e andeq r0, sp, lr, lsl #24
30: 0000001c andeq r0, r0, ip, lsl r0
34: 00000020 andeq r0, r0, r0, lsr #32
38: 000080ec andeq r8, r0, ip, ror #1
3c: 00000110 andeq r0, r0, r0, lsl r1
40: 8b040e42 blhi 103950 <_stack+0x83950>
44: 0b0d4201 bleq 350850 <_stack+0x2d0850>
48: 0d0d8002 stceq 0, cr8, [sp, #-8]
4c: 000ecb42 andeq ip, lr, r2, asr #22
Disassembly of section .debug_str:
00000000 <.debug_str>:
0: 69736e75 ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^
4: 64656e67 strbtvs r6, [r5], #-3687 ; 0xfffff199
8: 746e6920 strbtvc r6, [lr], #-2336 ; 0xfffff6e0
c: 73552f00 cmpvc r5, #0, 30
10: 2f737265 svccs 0x00737265
14: 6f63614a svcvs 0x0063614a
18: 66666f53 uqsaxvs r6, r6, r3
1c: 7365442f cmnvc r5, #788529152 ; 0x2f000000
20: 706f746b rsbvc r7, pc, fp, ror #8
24: 6964452f stmdbvs r4!, {r0, r1, r2, r3, r5, r8, sl, lr}^
28: 2d6e6f73 stclcs 15, cr6, [lr, #-460]! ; 0xfffffe34
2c: 67005452 smlsdvs r0, r2, r4, r5
30: 006f6970 rsbeq r6, pc, r0, ror r9 ; <UNPREDICTABLE>
34: 2f637273 svccs 0x00637273
38: 6e69616d powvsez f6, f1, #5.0
3c: 4700632e strmi r6, [r0, -lr, lsr #6]
40: 4320554e ; <UNDEFINED> instruction: 0x4320554e
44: 35203131 strcc r3, [r0, #-305]! ; 0xfffffecf
48: 312e342e ; <UNDEFINED> instruction: 0x312e342e
4c: 31303220 teqcc r0, r0, lsr #4
50: 31393036 teqcc r9, r6, lsr r0
54: 72282039 eorvc r2, r8, #57 ; 0x39
58: 61656c65 cmnvs r5, r5, ror #24
5c: 20296573 eorcs r6, r9, r3, ror r5
60: 4d52415b ldfmie f4, [r2, #-364] ; 0xfffffe94
64: 626d652f rsbvs r6, sp, #197132288 ; 0xbc00000
68: 65646465 strbvs r6, [r4, #-1125]! ; 0xfffffb9b
6c: 2d352d64 ldccs 13, cr2, [r5, #-400]! ; 0xfffffe70
70: 6e617262 cdpvs 2, 6, cr7, cr1, cr2, {3}
74: 72206863 eorvc r6, r0, #6488064 ; 0x630000
78: 73697665 cmnvc r9, #105906176 ; 0x6500000
7c: 206e6f69 rsbcs r6, lr, r9, ror #30
80: 34303432 ldrtcc r3, [r0], #-1074 ; 0xfffffbce
84: 205d3639 subscs r3, sp, r9, lsr r6
88: 70666d2d rsbvc r6, r6, sp, lsr #26
8c: 656e3d75 strbvs r3, [lr, #-3445]! ; 0xfffff28b
90: 762d6e6f strtvc r6, [sp], -pc, ror #28
94: 34767066 ldrbtcc r7, [r6], #-102 ; 0xffffff9a
98: 666d2d20 strbtvs r2, [sp], -r0, lsr #26
9c: 74616f6c strbtvc r6, [r1], #-3948 ; 0xfffff094
a0: 6962612d stmdbvs r2!, {r0, r2, r3, r5, r8, sp, lr}^
a4: 7261683d rsbvc r6, r1, #3997696 ; 0x3d0000
a8: 6d2d2064 stcvs 0, cr2, [sp, #-400]! ; 0xfffffe70
ac: 68637261 stmdavs r3!, {r0, r5, r6, r9, ip, sp, lr}^
b0: 6d72613d ldfvse f6, [r2, #-244]! ; 0xffffff0c
b4: 612d3776 ; <UNDEFINED> instruction: 0x612d3776
b8: 746d2d20 strbtvc r2, [sp], #-3360 ; 0xfffff2e0
bc: 3d656e75 stclcc 14, cr6, [r5, #-468]! ; 0xfffffe2c
c0: 74726f63 ldrbtvc r6, [r2], #-3939 ; 0xfffff09d
c4: 612d7865 ; <UNDEFINED> instruction: 0x612d7865
c8: 672d2037 ; <UNDEFINED> instruction: 0x672d2037
cc: 304f2d20 subcc r2, pc, r0, lsr #26
d0: 69616d00 stmdbvs r1!, {r8, sl, fp, sp, lr}^
d4: 6970006e ldmdbvs r0!, {r1, r2, r3, r5, r6}^
d8: 6d756e6e ldclvs 14, cr6, [r5, #-440]! ; 0xfffffe48
dc: 63727300 cmnvs r2, #0, 6
e0: 6970672f ldmdbvs r0!, {r0, r1, r2, r3, r5, r8, r9, sl, sp, lr}^
e4: 00632e6f rsbeq r2, r3, pc, ror #28
e8: 62727366 rsbsvs r7, r2, #-1744830463 ; 0x98000001
ec: 70007469 andvc r7, r0, r9, ror #8
f0: 6f4d6e69 svcvs 0x004d6e69
f4: 6d006564 cfstr32vs mvfx6, [r0, #-400] ; 0xfffffe70
f8: 0065646f rsbeq r6, r5, pc, ror #8
Disassembly of section .ARM.attributes:
00000000 <_stack-0x80000>:
0: 00003441 andeq r3, r0, r1, asr #8
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 0000002a andeq r0, r0, sl, lsr #32
10: 412d3705 ; <UNDEFINED> instruction: 0x412d3705
14: 070a0600 streq r0, [sl, -r0, lsl #12]
18: 09010841 stmdbeq r1, {r0, r6, fp}
1c: 0c050a02 stceq 10, cr0, [r5], {2}
20: 14041202 strne r1, [r4], #-514 ; 0xfffffdfe
24: 17011501 strne r1, [r1, -r1, lsl #10]
28: 19011803 stmdbne r1, {r0, r1, fp, ip}
2c: 1c011a01 stcne 10, cr1, [r1], {1}
30: 22061e01 andcs r1, r6, #1, 28
34: Address 0x0000000000000034 is out of bounds.
Thanks in advance
i think the tim=500000 can cause problems because the LED is switched on too short to be recognizable by human eye. RPi's processor has a speed around 1 GHz ( https://en.wikipedia.org/wiki/Raspberry_Pi ) what is 1.000.000.000 Hz
so the switched-on time of the LED is approx 0.5 ms. maybe try tim=5000000000 to try approx. 5s visibility or try other timings like delay(), sleep(),... ( implement time delay in c )
very slight modifications, the naked attributes are not required (what tools are you using?)
asm(".globl _start; _start: nop\n");
#ifndef GPIO_H
#define GPIO_H
#ifdef RPI2
#define GPIO_BASE 0x3F200000UL
#else
#define GPIO_BASE 0x20200000UL
#endif
#if defined( RPIBPLUS ) || defined( RPI2 )
#define LED_GPFSEL GPIO_GPFSEL4
#define LED_GPFBIT 21
#define LED_GPSET GPIO_GPSET1
#define LED_GPCLR GPIO_GPCLR1
#define LED_GPIO_BIT 15
#else
#define LED_GPFSEL GPIO_GPFSEL1
#define LED_GPFBIT 18
#define LED_GPSET GPIO_GPSET0
#define LED_GPCLR GPIO_GPCLR0
#define LED_GPIO_BIT 16
#endif
#define GPIO_GPFSEL0 0
#define GPIO_GPFSEL1 1
#define GPIO_GPFSEL2 2
#define GPIO_GPFSEL3 3
#define GPIO_GPFSEL4 4
#define GPIO_GPFSEL5 5
#define GPIO_GPSET0 7
#define GPIO_GPSET1 8
#define GPIO_GPCLR0 10
#define GPIO_GPCLR1 11
#define GPIO_GPLEV0 13
#define GPIO_GPLEV1 14
#define GPIO_GPEDS0 16
#define GPIO_GPEDS1 17
#define GPIO_GPREN0 19
#define GPIO_GPREN1 20
#define GPIO_GPFEN0 22
#define GPIO_GPFEN1 23
#define GPIO_GPHEN0 25
#define GPIO_GPHEN1 26
#define GPIO_GPLEN0 28
#define GPIO_GPLEN1 29
#define GPIO_GPAREN0 31
#define GPIO_GPAREN1 32
#define GPIO_GPAFEN0 34
#define GPIO_GPAFEN1 35
#define GPIO_GPPUD 37
#define GPIO_GPPUDCLK0 38
#define GPIO_GPPUDCLK1 39
/** GPIO Register set */
volatile unsigned int* gpio;
/** Simple loop variable */
volatile unsigned int tim;
// Function to change a pin's mode
static int pinMode(int pinnum, int mode);
#endif
static int pinMode(int pinnum, int mode) {
// Variable declaration and initialization
int fsr = 0;
int fsrbit;
// Let's check the pin does exist
if (pinnum < 0 || pinnum > 53) {
// Abort, there is no such pin.
return 1;
}
else if (mode < 0 || mode > 1) {
// Abort, invalid mode (Actually there are 7 modes but we will only use 2)
return 1;
}
// Create a pointer to the GPIO perhiperal register so we can speak to it
gpio = (unsigned int*)GPIO_BASE;
// And calculate wich FSR we should use
/* do {
if (pinnum > 9) {
pinnum -= 10;
fsr++;
}
} while (pinnum > 9); */
if (pinnum > 9) {
while (pinnum > 9) {
pinnum -= 10;
fsr++;
}
}
// Then we calculate the bytes of the fsreg to use
fsrbit = pinnum * 3;
// Finally let's set the pin to the desired mode
gpio[fsr] |= (mode << fsrbit);
return 0;
}
int main(void)
{
gpio = (unsigned int*)GPIO_BASE;
/* Write 1 to the GPIO16 init nibble in the Function Select 1 GPIO
peripheral register to enable GPIO16 as an output */
// gpio[LED_GPFSEL] |= (1 << LED_GPFBIT);
pinMode(47, 1);
// Never return from here
while(1)
{
for(tim = 0; tim < 500000; tim++)
;
/* Set the LED GPIO pin low ( Turn OK LED on for original Pi, and off
for plus models )*/
gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);
for(tim = 0; tim < 500000; tim++)
;
/* Set the LED GPIO pin high ( Turn OK LED off for original Pi, and on
for plus models )*/
gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
}
}
along with some hackery to get it to link, not something you can use directly but main wont need to change, just bootstrap and linking.
00001000 <main>:
1000: e52de004 push {lr} ; (str lr, [sp, #-4]!)
1004: e3a00801 mov r0, #65536 ; 0x10000
1008: e3a0e000 mov lr, #0
100c: e59f3078 ldr r3, [pc, #120] ; 108c <main+0x8c>
1010: e59f2078 ldr r2, [pc, #120] ; 1090 <main+0x90>
1014: e5823000 str r3, [r2]
1018: e5932010 ldr r2, [r3, #16]
101c: e3822602 orr r2, r2, #2097152 ; 0x200000
1020: e1a0c003 mov r12, r3
1024: e5832010 str r2, [r3, #16]
1028: e59f1064 ldr r1, [pc, #100] ; 1094 <main+0x94>
102c: e59f3064 ldr r3, [pc, #100] ; 1098 <main+0x98>
1030: e583e000 str lr, [r3]
1034: e5932000 ldr r2, [r3]
1038: e1520001 cmp r2, r1
103c: 8a000005 bhi 1058 <main+0x58>
1040: e5932000 ldr r2, [r3]
1044: e2822001 add r2, r2, #1
1048: e5832000 str r2, [r3]
104c: e5932000 ldr r2, [r3]
1050: e1520001 cmp r2, r1
1054: 9afffff9 bls 1040 <main+0x40>
1058: e58c0028 str r0, [r12, #40] ; 0x28
105c: e583e000 str lr, [r3]
1060: e5932000 ldr r2, [r3]
1064: e1520001 cmp r2, r1
1068: 8a000005 bhi 1084 <main+0x84>
106c: e5932000 ldr r2, [r3]
1070: e2822001 add r2, r2, #1
1074: e5832000 str r2, [r3]
1078: e5932000 ldr r2, [r3]
107c: e1520001 cmp r2, r1
1080: 9afffff9 bls 106c <main+0x6c>
1084: e58c001c str r0, [r12, #28]
1088: eaffffe8 b 1030 <main+0x30>
108c: 20200000 eorcs r0, r0, r0
1090: 000110a4 andeq r1, r1, r4, lsr #1
1094: 0007a11f andeq r10, r7, pc, lsl r1
1098: 000110a0 andeq r1, r1, r0, lsr #1
0000109c <_start>:
109c: e1a00000 nop ; (mov r0, r0)
Disassembly of section .bss:
000110a0 <tim>:
110a0: 00000000 andeq r0, r0, r0
000110a4 <gpio>:
110a4: 00000000 andeq r0, r0, r0
so the first problem is here which comes straight from your code
fsrbit = pinnum * 3;
gpio[fsr] |= (mode << fsrbit);
100c: e59f3078 ldr r3, [pc, #120] ; 108c <main+0x8c>
1018: e5932010 ldr r2, [r3, #16]
101c: e3822602 orr r2, r2, #2097152 ; 0x200000
1024: e5832010 str r2, [r3, #16]
doing a read-modify-write is correct, but unless you knew the bits were zeros to start with it is best to zero them first
gpio[fsr] &= (~(7<<fsrbit));
gpio[fsr] |= (mode<<fsrbit);
by declaring tim as volatile the code as you can see actually counts takes a few instructions, yes it might be a 1GHZ processor but you are not running that fast, you are fetching from dram (slow), even with the cache, and you have pipe hazards, etc.
As pointed out though maybe make your loop count number larger. Another thing to try is to swap things around on/off state.
first this:
while(1)
{
gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);
for(tim = 0; tim < 500000; tim++) continue;
gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
for(tim = 0; tim < 500000; tim++) continue;
}
is it on, does it glow? then try this
while(1)
{
gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
for(tim = 0; tim < 500000; tim++) continue;
gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);
for(tim = 0; tim < 500000; tim++) continue;
}
if the led looks the same then your count may be too small, make it larger, control the bit then do the delay not the other way around. If it still glows and doesnt blink with set first then clear or clear first then set? then maybe too fast still, just do this
gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
with no loop
or
gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);
with no loop.
can you make it go on and stay on? can you make it go off and stay off? If not then there is something wrong in the code you use to make it go on and off, if so then there maybe something wrong with your delay. but examination of optimized code shown above the volatile is taking care of that and burning cycles.
your I solved with a naked answer, was deleted, so does that mean you didnt solve it? The baking pi tutorials are nice, glad they are there, but the baremetal forum at raspberry pi has over time been littered with it (baking pi) doesnt work questions, mostly makefile/directory issues, but perhaps others. Looks like though you get the gist of it, your gpio pointer/array style is interesting, I wouldnt go that way but so far it is working for you.
Ahh, wait and another bug...you didnt define RPI2 but clearly you had on the command line perhaps?
800c: e3433f20 movt r3, #16160 ; 0x3f20
so lets try my smaller build again
1034: e5804020 str r4, [r0, #32] ; 0x20
1048: e580e02c str lr, [r0, #44] ; 0x2c
much better GPSET1 and GPCLR1 where 47 is found...so no bug there.
actually instead of hardcoding 47 you should have finished out your header file and used some LED_GPIO_BIT in the pinMode() call insuring you matched the LED_otherstuff to the gpio pin.

Resources