After a successful build, I decided to try flashing the image. I used "make jtag" then with openocd and my STlink V2 I flashed the image just as I always have done with my own bare metal code.
The download complained after verifying that the reset had failed. And nothing seems to be running. No lights are blinking. And I cannot flash more code, at least not without moving jumpers.
My device was easily restored by setting the BOOT0 jumper to 1 so that it was forced to run the boot loader in system memory. This allowed me to load my blink demo and now the device is back to normal.
My guess is whatever code had been loaded either had the device in a tight loop or caused some exception to lock it up. (This turns out to be not true. The device is running fine, but is blinking and LED on a wrong pin. Why I cannot flash again without moving jumpers is an unsolved problem).
arm-none-eabi-g++ -Os -g3 -gdwarf-2 -nostdlib -ffunction-sections -fdata-sections -Wl,--gc-sections -mcpu=cortex-m3 -march=armv7-m -mthumb -DBOARD_maple_mini -DMCU_STM32F103CB -DERROR_LED_PORT=GPIOB -DERROR_LED_PIN=1 -DVECT_TAB_FLASH -I./libmaple/include/libmaple -I./wirish/include/wirish -I./libraries -DBOOTLOADER_maple -fno-rtti -fno-exceptions -Wall -mcpu=cortex-m3 -march=armv7-m -mthumb -DBOARD_maple_mini -DMCU_STM32F103CB -DERROR_LED_PORT=GPIOB -DERROR_LED_PIN=1 -DVECT_TAB_FLASH -I./libmaple/include/libmaple -I./wirish/include/wirish -I./libraries -I./libmaple/include -I./libmaple/stm32f1/include -I./wirish/include -I./wirish/boards/maple_mini/include -o build/main.o -c main.cpp arm-none-eabi-g++ -Xlinker -T./support/ld/flash.ld -L ./support/ld/stm32/series/stm32f1/performance -L ./support/ld/stm32/mem/sram_20k_flash_128k -L ./support/ld -L ./support/ld/toolchains/generic -mcpu=cortex-m3 -mthumb -Xlinker --gc-sections -Xassembler --march=armv7-m -Wall -o build/maple_mini.elf build/./libmaple/adc.o build/./libmaple/dac.o build/./libmaple/dma.o build/./libmaple/exti.o build/./libmaple/flash.o build/./libmaple/gpio.o build/./libmaple/iwdg.o build/./libmaple/nvic.o build/./libmaple/pwr.o build/./libmaple/rcc.o build/./libmaple/spi.o build/./libmaple/systick.o build/./libmaple/timer.o build/./libmaple/usart.o build/./libmaple/usart_private.o build/./libmaple/util.o build/./libmaple/i2c.o build/./libmaple/exc.o build/./libmaple/usb/stm32f1/usb.o build/./libmaple/usb/stm32f1/usb_reg_map.o build/./libmaple/usb/stm32f1/usb_cdcacm.o build/./libmaple/usb/usb_lib/usb_core.o build/./libmaple/usb/usb_lib/usb_init.o build/./libmaple/usb/usb_lib/usb_mem.o build/./libmaple/usb/usb_lib/usb_regs.o build/./libmaple/stm32f1/performance/isrs.o build/./libmaple/stm32f1/performance/vector_table.o build/./libmaple/stm32f1/adc.o build/./libmaple/stm32f1/bkp.o build/./libmaple/stm32f1/dma.o build/./libmaple/stm32f1/exti.o build/./libmaple/stm32f1/fsmc.o build/./libmaple/stm32f1/gpio.o build/./libmaple/stm32f1/i2c.o build/./libmaple/stm32f1/rcc.o build/./libmaple/stm32f1/spi.o build/./libmaple/stm32f1/timer.o build/./libmaple/stm32f1/usart.o build/./wirish/start.o build/./wirish/start_c.o build/./wirish/syscalls.o build/./wirish/stm32f1/util_hooks.o build/./wirish/boards.o build/./wirish/cxxabi-compat.o build/./wirish/ext_interrupts.o build/./wirish/HardwareSerial.o build/./wirish/HardwareTimer.o build/./wirish/Print.o build/./wirish/pwm.o build/./wirish/usb_serial.o build/./wirish/HardwareSPI.o build/./wirish/wirish_analog.o build/./wirish/wirish_digital.o build/./wirish/wirish_math.o build/./wirish/wirish_shift.o build/./wirish/wirish_time.o build/./wirish/stm32f1/boards_setup.o build/./wirish/stm32f1/wirish_digital.o build/./wirish/stm32f1/wirish_debug.o build/./wirish/boards/maple_mini/board.o build/./libraries/Servo/Servo.o build/./libraries/LiquidCrystal/LiquidCrystal.o build/./libraries/Wire/WireBase.o build/./libraries/Wire/HardWire.o build/./libraries/Wire/Wire.o build/main.o -Wl,-Map,build/maple_mini.map arm-none-eabi-objcopy -v -Obinary build/maple_mini.elf build/maple_mini.bin 1>/dev/null arm-none-eabi-objdump -d build/maple_mini.elf > build/maple_mini.disasThe resulting "bin" file is 15140 bytes, which isn't as frightening as the 731192 bytes in the elf file.
A look at maple_mini.disas shows the text section beginning at 0x08005000, with the whole thing starting off with a vector table. This would explain why just shoving the thing in over the SWD port and expecting it to just run isn't working out. I see this:
08005000 <__stm32_vector_table>: 8005000: 00 50 00 20 49 73 00 08 91 5b 00 08 95 5b 00 08 .P. Is...[...[.. 8005010: 99 5b 00 08 9d 5b 00 08 a1 5b 00 08 2b 6d 00 08 .[...[...[..+m..
The source that yields the above is in "libmaple/libmaple/stm32f1/performance/vector_table.S" and is as follows:
.section ".stm32.interrupt_vector" .globl __stm32_vector_table .type __stm32_vector_table, %object __stm32_vector_table: .long __msp_init .long __exc_reset .long __exc_nmiBut if you build with "make jtag", everything ends up at 0x08000000 as it should, so hmmm.
One of my working projects starts out like this at address 0x08000000
.word 0x20005000 /* stack top address */ .word _reset /* 1 Reset */ .thumb_func _reset: bl startup b .So I try the jtag build again and get the same failure. It programs 15360 bytes (which is 30*512) and then verifies 15140 bytes OK. 15140 is the size of the bin file, which seems just right. It fails when resetting the target and doesn't give a complete error, only:
** Resetting Target ** in procedure 'program' in procedure 'reset' called at file "embedded:startup.tcl", line 540 in procedure 'ocd_bouncer'In any case though, resetting the board doesn't yield proper behavior either, so the problem does not lie with openocd despite its incomplete message.
I copy my blink1 demo, which is 100 lines of self contained C code that will blink the PC13 LED (which is a red LED on my board). I make sure everything in here is static, except for "tom_startup()" and append this code to start_c.c I put a call to tom_startup at the head of start_c(), compile the mess and load it into my device. It runs and blinks the LED!!
Oddly though, I cannot just reflash again and again using the STLINK as I can with my own demos, but this is progress of a sort. Being able to flash once is a big step forward.
Now I move my call to just before the call to main(). I get an error from openocd about resetting the chip, and now the LED is blinking very fast. I am also unable to connect to the target. So this is all the same as the original problem, but now with the LED flashing like crazy. I move my call to just before "__libc_init_array()" and we are back to blinking at a normal rate.
The routine "libc_init_array()" is supplied as part of the compiler toolchain. It supports C++ constructors and the ".init_array". There is no reason for me to dig any deeper into these details for now.
The rapid flashing makes sense. My simple blink demo did not set the PLL to bump the processor speed up to 72 Mhz, and apparently once the stuff triggered by libc_init_array() runs, libmaple has bumped up the CPU speed.
And indeed this works.
Second - we have an unsolved and mildly inconvenient mystery in flashing the maple software into the blue pill. We have to move the BOOT0 jumper, reset to get the in-chip boot loader to run, then we can flash our software. Then we move the jumper back and reset again to run the software we just flashed.
Tom's Computer Info / tom@mmto.org