16k USB devices and Chibios.

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

Moderator: RoccoMarco

rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

16k USB devices and Chibios.

Post by rew »

I have a project that I had intended on using the smalles STM32F042F device: the -4, with only 16k flash.

When I take: testhal/STM32/STM32F0xx/USB_CDC and remove the "test" functions I'm left with 18k. of "text".

Does anybody know a quick way to drop to say a few kb under 16k? Compiler options? chibios configuration options?

(one thing that I don't understand is "ctype" seems to be included in my project. I can't find who references it....)
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: 16k USB devices and Chibios.

Post by Giovanni »

Are compiler optimizations set to -Os ?

You can exclude a lot of things from chconf.h, there is also an option that allows to to optimize the kernel for size rather than for speed.

See where that brings you then we may discuss fine tuning.

Then there is the option NIL.

Giovanni
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Re: 16k USB devices and Chibios.

Post by rew »

Thanks. Generally speaking now down to about 8k for the demo project. That means I probably have 8k left to implement my application. :-)

Update: In my application it drops down to about 13k text, "load size 15248". Barely fits..... (not all code has been written yet), but I can compare the MAP files to see the big differences. I still don't have a compiler capable of LTO. Not sure if that makes a difference.
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Re: 16k USB devices and Chibios.

Post by rew »

With some additions to the code, the 16k limit quickly flies by!

I've replaced chprintf with tinyprintf. saves 400 bytes.

I've switched to -Os. saves 800 bytes.

I see the option -falign_functions=16 in the C options. When I change that to 4, nothing happens:

Code: Select all

                0x00000000080002b0        0x2 build/obj/crt1.o
                0x00000000080002b0                __late_init
 *fill*         0x00000000080002b2        0xe
 .text.__default_exit
                0x00000000080002c0        0x2 build/obj/crt1.o


I'm now trying to switch to "NIL". At the moment I can't find how to write to the USB-serial driver: chSequentialStreamPut is not defined if you switch to "NIL", and I can't find an alternative. Is there an alternative?

(Update: switching to "NIL" shaved off another 500 bytes, but then my device no longer enumerates. I have a problem somewhere...)
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: 16k USB devices and Chibios.

Post by Giovanni »

You could also use just the HAL.

The problem with NIL is probably caused by the usb_pump thread, it is started automatically by RT but you need to allocate a task for it in NIL explicitely, NIL cannot start threads.

Giovanni
ulikoehler
Posts: 71
Joined: Tue Mar 17, 2015 2:32 am
Been thanked: 3 times

Re: 16k USB devices and Chibios.

Post by ulikoehler »

I have realized a USB RS485 adapter using the STM32F042F4. ChibiOS RT didn't work for space reasons. ChibiOS/NIL works perfectly well and i still have a few kilobytes left!

While my application might be specific, I can share most of the code.

I also have some other code regarding efficient conversions int -> string, bin -> hex etc. Once I get around it, I can post that somewhere.

Best regards, Uli
ulikoehler
Posts: 71
Joined: Tue Mar 17, 2015 2:32 am
Been thanked: 3 times

Re: 16k USB devices and Chibios.

Post by ulikoehler »

@Giovanni: I have not dealt with the usb_pump thread at all, yet the adapter works perfectly.

However I have noticed that if I do not sleep at any time in my thread, the USB will not work. Maybe this is related.

I have also had some issues with the SDU output buffer that I have not pinned down:
It is something like that: If the the buffer is full, the buffer is transmitted over and over, if no data comes in.
I have solved it by resetting the buffer if less than 32 bytes are free (in a 1024b buffer).
Right now I am unsure if it's a bug, I'll nee to try it out with a minimal firmware.

Best regards, Uli
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: 16k USB devices and Chibios.

Post by Giovanni »

My fault, the thread is only present in the OTGv1 driver.

Interesting problem you are having, could you try if you get this only with NIL or also RT?

Giovanni
ulikoehler
Posts: 71
Joined: Tue Mar 17, 2015 2:32 am
Been thanked: 3 times

Re: 16k USB devices and Chibios.

Post by ulikoehler »

I'll try if I get a minimal firmware working to reproduce this bug (if it is a bug after all...). Although the RS485 firmware only has ~250 SLOC I suspect there might be other factors involved in this...

Basically the queue gets filled up by a UART. I have an accelerometer with 100 Hz output datarate attached and tapped it once (--> one acceleration peak). On my computer a visualization software is running. Under some circumstances that might depend on how full the SDU1 output buffer got before reading from the CDC port, the ODR of the adapter jumps to ~10000 Hz (maybe the maximum the USB can cope with!? amounts to ~200 kbytes payload data a second).. What is visible in the visualization is that the single tap is shown repeatedly multiple times every second. Maybe the data buffer is transmitted over-and-over or forwards-backwards-forwards. Visuallly it looked like the second case but I'm not really sure.

Uli
ulikoehler
Posts: 71
Joined: Tue Mar 17, 2015 2:32 am
Been thanked: 3 times

Re: 16k USB devices and Chibios.

Post by ulikoehler »

I just tested it using some minimal hello world firmware and the issue could not be reproduced. I also looked at the code in hal_queues.c and didn't find any obvious issues. Therefore I'd say it's a bug somewhere in my code and not in the HAL itself.

One tip regarding the USB stuff: If your USB device does not enumerate, add more delays in your program. Consider this.

Code: Select all

THD_WORKING_AREA(serialThreadWA, 512);
THD_FUNCTION(SerialIOThread, arg) {
  (void)arg;
  //Ensure IWDG does no reset us too early

  /*
   * Initializes a serial-over-USB CDC driver.
   */
  serialUSBInit();
  serialUSBConnect();

  int n = 0;
  while (true) {
    //Reset buffers if too full. Not sure why this is neccessary
    if(USBD1.state == USB_ACTIVE) { //ep0next --> terminal conn'd
      sdWrite(&SDU1, "Hello World!\r\n", 14);
      chThdSleepMilliseconds(5);
    } else {
      chThdSleepMilliseconds(10);
    }
  }
}


If you remove the chThdSleepMilliseconds(10), the device will not enumerate. This was 100% reproducible in my case, but I don't consider it a bug (I think it's inherently related to the way USB IO is handled in NIL, or maybe some weird preemption / USB timing stuff).
Basically you NEED sleeps of (I think) 5+ milliseconds at the right places, ESPECIALLY if USBD1.state != USB_ACTIVE, but maybe also in the other branch.

It was quite a hassle to debug that so I hope you (@rew) can use this to make it work right away.

Uli
Post Reply