ChibiOS on the Spark Core

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
GiacomoB
Posts: 6
Joined: Mon Jul 07, 2014 2:30 pm

ChibiOS on the Spark Core

Post by GiacomoB »

Hi all,

I'm trying to run ChibiOS on the Spark Core http://docs.spark.io/hardware/.
It features a STM32F103CB, so I started by using the demo in demos/ARMCM3-STM32F103 as a template and modified main.c to just blink a led in a thread.
I copied board.c, board.h and board.mk from boards/MAPLEMINI_STM32_F103 (same MCU) to boards/SPARK_STM32_F103 and disabled everything in halconf.h except for TM and PAL.

Since the Spark Core comes with a bootloader https://github.com/spark/bootloader, I modified (as stated in various posts in these forums) the linker script with the new flash starting point (0x8005000 instead of 0x8000000) and set the CORTEX_VTOR_INIT to 0x5000 in chconf.h

Sadly, I don't have a JTAG, so my only means of debugging are the three leds on the board (RGB).

At first, nothing worked and fiddling with the code I found that CORTEX_VTOR_INIT was the culprit: by setting it to 0x0000 chSysInit() is executed without errors, otherwise it hangs.
With this fix, the leds started to turn on but they were not turning off because the code was entering chThdSleepMilliseconds and never leaving. Removing the call to chThdSleepMilliseconds and replacing it with a loop "solved" the issue and the led blinked.

I changed the main thread to blink the blue led and the other thread to blink the green led (both NORMALPRIO): only the main thread was blinking. Adding a chThdYield to both threads, they started to blink blue and green alternately.

I suspected that interrupts are not served correctly, expecially the SysTick, so I tried to turn on a led in the SysTick hook...and it seems to never be called...

Any suggestion/hint/idea of what is going wrong?

Thank you.

P.S.
I'm using the gcc arm toolchain with the ChibiOS Makefile. You can find in attachment the project together with the linker script and the original linker scripts of the Spark Core firmware.
Attachments
sparktest.zip
(217.93 KiB) Downloaded 477 times
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ChibiOS on the Spark Core

Post by Giovanni »

Your guess is right, the problem is that interrupts are not being serviced. You should look at the map file and see if the vector table is located where you expect it to be.

Bootloaders usually also have other problems, they initialize hardware and do not restore a post-reset situation properly before handing control to the application, this can cause problems to device drivers which expect HW to be in a known state.

Giovanni
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: ChibiOS on the Spark Core

Post by mobyfab »

It seems like the bootloader enables the IWDG: https://github.com/spark/bootloader/blo ... ain.c#L283

This should be handled in a thread or using a GPT/VT, else you are going to keep rebooting.

Also I can see in the user app: NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x5000); (https://github.com/spark/core-firmware/ ... in.cpp#L86)

It should work using CORTEX_VTOR_INIT set at 0x8005000 in chconf.h (You need the full address, not just the offset, that's why it wouldn't work with 0x5000)
GiacomoB
Posts: 6
Joined: Mon Jul 07, 2014 2:30 pm

Re: ChibiOS on the Spark Core

Post by GiacomoB »

Thank you very much for your answers.

I added some led blinking to get the value of VTOR :shock: in _port_init (chcore_v7m.c):
- before setting the VTOR to CORTEX_VTOR_INIT, the value in the register is 0x8000000
- after seetting the VTOR to CORTEX_VTOR_INIT, the value is 0x8005000

an extract of ch.map follows:

Code: Select all

                0x0000000000000400                __main_stack_size__ = 0x400
                0x0000000000000400                __process_stack_size__ = 0x400
                0x0000000020000000                __ram_start__ = ORIGIN (ram)
                0x0000000000005000                __ram_size__ = 0x5000
                0x0000000020005000                __ram_end__ = (__ram_start__ + __ram_size__)
                0x0000000000000000                . = 0x0
                0x0000000000000000                _text = .

startup         0x0000000008005000       0xec
 *(vectors)
 vectors        0x0000000008005000       0xec build/obj/vectors.o
                0x0000000008005000                _vectors

constructors    0x00000000080050ec        0x0
                0x00000000080050ec                PROVIDE (__init_array_start, .)
 *(SORT(.init_array.*))
 *(.init_array)
                0x00000000080050ec                PROVIDE (__init_array_end, .)

destructors     0x00000000080050ec        0x0
                0x00000000080050ec                PROVIDE (__fini_array_start, .)
 *(.fini_array)
 *(SORT(.fini_array.*))
                0x00000000080050ec                PROVIDE (__fini_array_end, .)

.text           0x00000000080050f0      0xd8c
 *(.text.startup.*)
 .text.startup.main
                0x00000000080050f0       0xf0 build/obj/main.o
                0x00000000080050f0                main
 *(.text)
 *(.text.*)
 .text.__late_init
                0x00000000080051e0       0x10 build/obj/crt0.o
                0x00000000080051e0                __late_init
 .text._default_exit
                0x00000000080051f0       0x10 build/obj/crt0.o
                0x00000000080051f0                _default_exit
 .text.ResetHandler
                0x0000000008005200      0x110 build/obj/crt0.o
                0x0000000008005200                ResetHandler
 .text._unhandled_exception
                0x0000000008005310       0x10 build/obj/vectors.o
                0x0000000008005310                Vector58
                0x0000000008005310                VectorE8
                0x0000000008005310                Vector9C
                0x0000000008005310                VectorAC
                0x0000000008005310                Vector5C
                0x0000000008005310                NMIVector
                0x0000000008005310                Vector8C
                0x0000000008005310                VectorDC
                0x0000000008005310                VectorC8
                0x0000000008005310                Vector94
                0x0000000008005310                VectorA8
                0x0000000008005310                VectorB4
                0x0000000008005310                Vector74
                0x0000000008005310                UsageFaultVector
                0x0000000008005310                DebugMonitorVector
                0x0000000008005310                Vector40
                0x0000000008005310                VectorBC
                0x0000000008005310                Vector64
                0x0000000008005310                VectorCC
                0x0000000008005310                Vector54
                0x0000000008005310                Vector98
                0x0000000008005310                VectorD8
                0x0000000008005310                Vector24
                0x0000000008005310                Vector84
                0x0000000008005310                BusFaultVector
                0x0000000008005310                VectorD0
                0x0000000008005310                VectorE4
                0x0000000008005310                VectorC0
                0x0000000008005310                SVCallVector
                0x0000000008005310                HardFaultVector
                0x0000000008005310                VectorE0
                0x0000000008005310                MemManageVector
                0x0000000008005310                Vector6C
                0x0000000008005310                VectorA0
                0x0000000008005310                VectorC4
                0x0000000008005310                Vector7C
                0x0000000008005310                VectorB0
                0x0000000008005310                Vector90
                0x0000000008005310                Vector60
                0x0000000008005310                Vector1C
                0x0000000008005310                Vector48
                0x0000000008005310                Vector70
                0x0000000008005310                VectorD4
                0x0000000008005310                Vector4C
                0x0000000008005310                Vector80
                0x0000000008005310                Vector68
                0x0000000008005310                Vector78
                0x0000000008005310                _unhandled_exception
                0x0000000008005310                Vector88
                0x0000000008005310                Vector50
                0x0000000008005310                Vector44
                0x0000000008005310                Vector28
                0x0000000008005310                VectorB8
                0x0000000008005310                Vector34
                0x0000000008005310                VectorA4
                0x0000000008005310                Vector20
 .text._port_switch_from_isr
                0x0000000008005320       0x20 build/obj/chcore_v7m.o
                0x0000000008005320                _port_switch_from_isr
 .text.PendSVVector
                0x0000000008005340       0x10 build/obj/chcore_v7m.o
                0x0000000008005340                PendSVVector
 .text._port_init
                0x0000000008005350       0x40 build/obj/chcore_v7m.o
                0x0000000008005350                _port_init
 .text._port_irq_epilogue
                0x0000000008005390       0x70 build/obj/chcore_v7m.o
                0x0000000008005390                _port_irq_epilogue
 .text.SysTickVector
                0x0000000008005400       0x20 build/obj/chcore_v7m.o
                0x0000000008005400                SysTickVector


It seems correct to me...

However, with these settings, chSysInit hangs in the call to chSysEnable at

Code: Select all

asm volatile ("cpsie   i" : : : "memory")

both with CORTEX_SIMPLIFIED_PRIORITY and without.

Same story with CORTEX_VTOR_INIT=0x5000.

Any ideas?

Thanks.

P.S.
At this point I (also :oops: ) don't understand why CORTEX_VTOR_INIT is set at 0 by default in the port. Shouldn't it be 0x8000000?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ChibiOS on the Spark Core

Post by Giovanni »

It is possible that the bootloader leaves some non-served interrupts, when interrupts are enabled again it goes into the default service routine: an infinite loop.

We cannot go imagining what the bootloader could possibly do, you need debug capability and to talk with the author if possible.

Giovanni
GiacomoB
Posts: 6
Joined: Mon Jul 07, 2014 2:30 pm

Re: ChibiOS on the Spark Core

Post by GiacomoB »

Thank you very much!

The bootloader enables EXTI2, TIM1 and USB_LP_RX. The culprit was EXTI2, triggering Vector60 and hence _unhandled_exception.
Adding an ISR or disabling the IRQ solves the problem!

I finally have my leds blinking correctly :D
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: ChibiOS on the Spark Core

Post by mobyfab »

I see that the bootloader does not disable interrupts before booting so that's the source of your problems.

Maybe there's a reason behind that, because it's not something to dismiss...
Post Reply