Spark Logic

HALMX :: MXBluePillF103C8 Roadmap

Vassilis Mon Apr 18, 2016 6:46 am

On March 2016 I started working on Sheepdoll’s (Julie S. Porter) great work on HALMX core files. I focused on STM32F103C8 MCU because it’s widely used by STM32Duino members. I think it is very hard for members to watch the whole forum posts and see what feature is added to the HALMX core.
I saw that Sheepdoll has a generic HALMX roadmap but the changes I have done so far are tested only MXBluePillF103C8 variant. Not to the entire HALMX variants. For that reason, I created this post that informs the members with the changes are made by me or any other member, to the MXBluePillF103C8 variant.

Things that work:

[14 May 2016]
* USBSerial. Added support to USB Virtual COM port.
* Bootloader. The Maple DFU firmware upload method is used to upload the compiled sketches to HALMX.

[09 May 2016]
* Added the interrupt based Serial transmission function on Serial1, 2 and 3 ports.

[19 April 2016]
* wiring_analog.c Support to AnalogRead() and AnalogWrite() functions

[14 April 2016]
* SPI library
* wiring.h The delayMicroseconds() was re-written for STM32. The previous assembly code wasn’t work correct to the tests I had made.
* wiring_digital.c The LOW and HIGH were placed in reverse on digitalRead(…). Fixed!

[09 April 2016]
* Hardware Serial ports. Serial 1, Serial 2 and Serial 3 work in Interrupt mode.

Things to do:
* Wiring library. Support to I2C interface
* SPI library in DMA and Interrupt mode.

Replies

Vassilis Mon Apr 18, 2016 5:43 pm

The analogRead() and analogWrite() functions are ready. I will send the PR in 1-2 days.

RogerClark Mon Apr 18, 2016 10:27 pm

Thanks Vassilis

Sorry I dont have time to do much of this myself.

Im not sure if you did a pull from my repo into yours, as I updated some files to allow use with the bootloader.

Re:Bootloader for all STM32

I dont think we can write one bootloader that would work for all.

I am not sure if all STM32 devices have USB support ??

We could write a serial bootloader for those devices that only have serial, but I doubt there would be much point as I suspect those devices have a built in serial bootloader, or people would just use STLink.

The F4 has built in DFU, but I dont know if its possible to enter DFU bootloader mode from code, or whether it can only be accessed by Boot0 and Boot1.

Anyway I think that writing new bootloaders would be the last think to do.

Vassilis Tue Apr 19, 2016 8:59 pm

I did a pull and I saw your files. Thanks!
On March I did some tests to combine the stm32duino bootloader with CubeMX. That was totally failure. I had changed the flash address from the *.ld file but … nothing. The bootloader was partially worked. I had unpluged the blupill from the usp port. I pressed the upload button on arduino IDE and simultaneously I plugged in the bluepill to the usb port. With that trick the bluepill was programed successfully.
I am thinking right now one more test to do but it is too late for that now. I will try it tomorrow.

RogerClark Tue Apr 19, 2016 9:15 pm

Vassilis

The only way I could get the BluePill to work with the bootloader was to unplug it, and then plug it back in, just when dfu-util was searching for dfu devices.

The maple mini worked better, as I just press the reset button when dfu-util is searching.

I dont know why the reset button is not resetting the usb on the BluePill, but the problem may also be because of the Skylake chipset in my new PC, as it is not BluePill friendly and it does not work with the GD32 at all.

Some of the problem with the BluePill is that when the sketch runs, the Windows device manager still shows the DFU device, even though the dfu code is no longer running in the BluePill.

We could force USB enumeration when the sketch starts, but it would then show probably show an unknown device.

I think we need to find some small CDC code to provide USB Serial, as the STM code seems far to big.

Perhaps the libopencm3 code, as used by the BMP could be used to provide the USB.
The interesting thing about the BMP is that it has 3 devices at the same time, i.e. it behaves as a composite device. I think this is the way forward, as I know there is a lot of interest in USB midi and also USB HID ( mouse and keyboard)

If we start with a USB composite device, even with only 1 sub device, it would make it much easier to add additional devices.

mrburnette Wed Apr 20, 2016 12:34 pm

RogerClark wrote:
<…>
The maple mini worked better, as I just press the reset button when dfu-util is searching.
<…>

Slammer Mon Apr 25, 2016 9:11 am

I used CubeMX to add support for CDC serial device. I managed to get/put bytes to USB serial but, indeed, the code is much larger than libmaple.
Code raised to 17KB, and the BSS segment to 5KB!, for the typical blink program with some printing. The same code with libmaple is about 14.5KB/1KB.
While this size increase is not a problem for larger devices, is a serious drawback for the small.
I am examining the map file to see what is allocated and why. Maybe, we have to “touch” the MX generated code specially in small devices like “Pills”.

RogerClark Mon Apr 25, 2016 10:28 am

@slammer

I presume somehow the linker is linking functions that are not actually used.

We use the –whole-archive flag on libmaple, on the “archive” code, to ensure that things like the hardware timer ISR’s get linked correctly.

I tried removing it from the HALMX core, but unfortunately it didnt seem to reduce the code size.
So either I modified the wrong code in platform.txt, or its not the –whole-archive flag that could be causing the large code.

The other thing that could be tried is somehow compiling the code from the Cube using just a makefile, and see if the CDC code is still too large.

I think @sheepdoll has been trying to compile using Eclipse on OSX, but I’m not sure if she was using an Arduino plugin, or just the files from the Cube.

Slammer Mon Apr 25, 2016 10:39 am

I am building the code outside Arduino environment using makefile. Comparison is done using the same makefile and maybe the results are a bit different than Arduino’s build system. I will play with cflags to see if there is change in size. I am pretty sure that some cleanup is needed specially in arduino core files as many functions are almost implemented in HAL.
The most important is that the code works! Nice job Vassilis and Sheepdoll!

Here is the size report of libcore.a (is the library of all sources):
arm-none-eabi-size _build/g103c/libcore.a
text data bss dec hex filename
49 0 0 49 31 dtostrf.o (ex _build/g103c/libcore.a)
200 0 0 200 c8 itoa.o (ex _build/g103c/libcore.a)
16 0 0 16 10 new.o (ex _build/g103c/libcore.a)
904 0 0 904 388 Print.o (ex _build/g103c/libcore.a)
56 0 0 56 38 RingBuffer.o (ex _build/g103c/libcore.a)
891 0 0 891 37b Stream.o (ex _build/g103c/libcore.a)
292 0 4 296 128 syscalls.o (ex _build/g103c/libcore.a)
594 0 2 596 254 UARTClass.o (ex _build/g103c/libcore.a)
94 0 0 94 5e USARTClass.o (ex _build/g103c/libcore.a)
6 0 0 6 6 wiring.o (ex _build/g103c/libcore.a)
132 0 0 132 84 wiring_digital.o (ex _build/g103c/libcore.a)
144 0 0 144 90 wiring_shift.o (ex _build/g103c/libcore.a)
78 0 0 78 4e WMath.o (ex _build/g103c/libcore.a)
1897 0 1 1898 76a WString.o (ex _build/g103c/libcore.a)
372 0 0 372 174 startup_stm32f103xb.o (ex _build/g103c/libcore.a)
184 4 0 188 bc system_stm32f1xx.o (ex _build/g103c/libcore.a)
342 0 4 346 15a stm32f1xx_hal.o (ex _build/g103c/libcore.a)
518 0 0 518 206 stm32f1xx_hal_cortex.o (ex _build/g103c/libcore.a)
1778 0 0 1778 6f2 stm32f1xx_hal_dma.o (ex _build/g103c/libcore.a)
826 0 0 826 33a stm32f1xx_hal_flash.o (ex _build/g103c/libcore.a)
1136 0 0 1136 470 stm32f1xx_hal_flash_ex.o (ex _build/g103c/libcore.a)
680 0 0 680 2a8 stm32f1xx_hal_gpio.o (ex _build/g103c/libcore.a)
7434 0 0 7434 1d0a stm32f1xx_hal_i2c.o (ex _build/g103c/libcore.a)
2146 0 0 2146 862 stm32f1xx_hal_pcd.o (ex _build/g103c/libcore.a)
50 0 0 50 32 stm32f1xx_hal_pcd_ex.o (ex _build/g103c/libcore.a)
524 0 0 524 20c stm32f1xx_hal_pwr.o (ex _build/g103c/libcore.a)
2716 0 0 2716 a9c stm32f1xx_hal_rcc.o (ex _build/g103c/libcore.a)
606 0 0 606 25e stm32f1xx_hal_rcc_ex.o (ex _build/g103c/libcore.a)
4440 0 0 4440 1158 stm32f1xx_hal_spi.o (ex _build/g103c/libcore.a)
128 0 1 129 81 stm32f1xx_hal_spi_ex.o (ex _build/g103c/libcore.a)
0 0 0 0 0 stm32f1xx_hal_tim.o (ex _build/g103c/libcore.a)
0 0 0 0 0 stm32f1xx_hal_tim_ex.o (ex _build/g103c/libcore.a)
2590 0 0 2590 a1e stm32f1xx_hal_uart.o (ex _build/g103c/libcore.a)
2054 0 0 2054 806 stm32f1xx_ll_usb.o (ex _build/g103c/libcore.a)
578 272 1 851 353 usbd_cdc.o (ex _build/g103c/libcore.a)
664 0 0 664 298 usbd_core.o (ex _build/g103c/libcore.a)
906 0 1 907 38b usbd_ctlreq.o (ex _build/g103c/libcore.a)
150 0 0 150 96 usbd_ioreq.o (ex _build/g103c/libcore.a)
396 0 0 396 18c _spi.o (ex _build/g103c/libcore.a)
128 0 0 128 80 gpio.o (ex _build/g103c/libcore.a)
184 0 0 184 b8 i2c.o (ex _build/g103c/libcore.a)
200 0 0 200 c8 main.o (ex _build/g103c/libcore.a)
116 0 0 116 74 stm32f1xx_hal_msp.o (ex _build/g103c/libcore.a)
98 0 0 98 62 stm32f1xx_it.o (ex _build/g103c/libcore.a)
360 0 0 360 168 usart.o (ex _build/g103c/libcore.a)
56 0 0 56 38 usb_device.o (ex _build/g103c/libcore.a)
124 16 0 140 8c usbd_cdc_if.o (ex _build/g103c/libcore.a)
588 0 544 1132 46c usbd_conf.o (ex _build/g103c/libcore.a)
243 52 0 295 127 usbd_desc.o (ex _build/g103c/libcore.a)
448 4 624 1076 434 variant.o (ex _build/g103c/libcore.a)

RogerClark Mon Apr 25, 2016 10:49 am

Ummm

Perhaps there are some postings on STM’s own forums about the code size when using the Cube.

Its strange that compiler must be linking so much code that is never being used.

Slammer Mon Apr 25, 2016 11:10 am

If you examine the sizes of core files, always the *_ex.o modules are very big.
These are the extended HAL modules, they provide extended functionality on corresponding core modules. I am not sure if we need this functionality.

RogerClark Mon Apr 25, 2016 11:19 am

Slammer wrote:I you examine the sizes of core files, always the *_ex.o modules are very big.
These are the extended HAL modules, they provide extended functionality on corresponding core modules. I am not sure if we need this functionality (for example fifo in i2c/spi etc….)

sheepdoll Mon Apr 25, 2016 5:30 pm

RogerClark wrote:

I think @sheepdoll has been trying to compile using Eclipse on OSX, but I’m not sure if she was using an Arduino plugin, or just the files from the Cube.

Slammer Mon Apr 25, 2016 8:58 pm

I am not familiar with arduino building system and I am making tests using makefile and compare the results. There are noticeable differences….
As I understand every source file inside cores/mapleMX directory is compiled and placed in the core.a static library, but every file in variants directory (for the selected board) is compiled and linked as object file. The linker is very capable to find the required functions from core.a rejecting all unneeded code but when tries to link objects that explicitly named, into binary is less sensitive, keeping much more functions (all objects from variant are explicitly named) .

I tried to put every source file from both cores/variants directories into core.a using makefile, and create the binary, linking the main source file (1 file sketch for simplicity) with core.a
The linker outputs some warnings about some libc functions, actually there are some problems with linking and some objects must be linked explicitly and not as part of core.a (I am still working on this, to figure out why this is happening and for which files).
Using makefile it is possible to compile and link the sketch successfully, and the size of executable binary is smaller! For example the blink sketch is about 11.5KB when using arduino build system and with makefile and big-core.a is about 8KB, keeping the CCFLAGS the same.
Maybe someone with deeper knowledge of linker internals can help to clarify these issues, if the MX sources must be included in core.a for effective linking we have to change the structure of files. It seems that variant directory is intended for some header files or small piece of code and not for frameworks.
I will make some more tests, keep this info as preliminary, I am still trying….

PS. Roger a small fix about naming of include<arduino.h> in variant.cpp file, Linux is case sensitive…. I send pull request…

Slammer Tue Apr 26, 2016 1:37 am

OK!… I think that I resolved the “mystery” with the linker…..
The problem is the file with the interrupt vectors stm32f1xx_it.c. All interrupt vectors are weakly defined in startup.S to Default_Handler, if the stm32f1xx_it.c is included in a static library, the linker keeps the definitions of startup.S and all other definitions are discarded. The program is not running as the Default_Handler is while(1); loop. I tried to change the position of library in linker command line but the result was the same.
When the stm32f1xx_it is included in linker command line as object together with static library (with all other files) and sketch object the interrupt vectors are taking the correct values and the program executes normally. With this configuration there is no need to use the -whole-archive flag (which includes all library functions) and the linker resolves correctly the required symbols, discarding any no needed functions.
I did not find a working solution to use the stm32f1xx_it.c inside the static library…. maybe some modification in startup is needed, but this will brake the automatic generation of code from CubeMX.

RogerClark Tue Apr 26, 2016 1:51 am

@slammer

We already need to make some changes to the auto generated code, so I don’t think it matters that the code needs to be changed.

I already had to change the file that hard codes the start offset vector to 0x00 as we need to move the start vector when using the bootloader, so I had to wrap the existing definition in an ifndef block, so that we can define it as a compiler command line argument.

stevech Tue Apr 26, 2016 4:10 am

I use CubeMX and…
Relocating the exception vectors table.. I do that at run time by writing a register in the STM32Fxxx. At compile time I have the linker config script file place the power-up default for the table at the usual place so that the auto-generated code will work.

My main reason for relocating the table is to have two versions of the app in flash, and use one as power-up default and then it decides whether to run the other version (moving the vector table pointer in hardware to the flash for that 2nd code), or to download and re-flash new version of 2nd copy of code.

This is a way to do two versions of code and in-place reflash, unattended, without needed an STM32 that has double flash size and the hardware remapping of two banks of flash. Saves cost of the double sized flash like the STM32F42x has, whereas the STM32F41x (or 40x) have half that much and no bank switching.

Vassilis Tue Apr 26, 2016 1:40 pm

@Roger I sent again a PR for supporting ananogRead() and analogWrite() functions (wiring_analog.c file).

I had sent a PR from my windows Github but as it seems, you have never received it.
I think, I will do the PRs from the web based Github (for sure ).

RogerClark Tue Apr 26, 2016 9:43 pm

Hi Vassilis

I did not receive the other PR.

I have never tried to send a PR directly from Windows. Perhaps it doesn’t work.

Slammer Wed Apr 27, 2016 11:10 am

Here is the micros() implementation ported from libmaple using HAL:

// Adopted from libmaple with Hal

uint32_t micros(void)
{
uint32_t ms;
uint32_t cycle_cnt;

do {
ms = HAL_GetTick();
cycle_cnt = SysTick->VAL;
asm volatile("nop"); //allow interrupt to fire
asm volatile("nop");
} while (ms != HAL_GetTick());

return ( ms * 1000 + ( SysTick->LOAD + 1 - cycle_cnt ) / ( SystemCoreClock / 1000000 ) ) ;
}

Vassilis Wed Apr 27, 2016 12:12 pm

Slammer wrote:Here is the micros() implementation ported from libmaple using HAL:

// Adopted from libmaple with Hal

uint32_t micros(void)
{
uint32_t ms;
uint32_t cycle_cnt;

do {
ms = HAL_GetTick();
cycle_cnt = SysTick->VAL;
asm volatile("nop"); //allow interrupt to fire
asm volatile("nop");
} while (ms != HAL_GetTick());

return ( ms * 1000 + ( SysTick->LOAD + 1 - cycle_cnt ) / ( SystemCoreClock / 1000000 ) ) ;
}

Sign in to reply