RIOT-OS / RIOT

RIOT - The friendly OS for IoT
https://riot-os.org
GNU Lesser General Public License v2.1
4.94k stars 1.99k forks source link

Support for EFM32 #1123

Closed rasgo-cc closed 6 years ago

rasgo-cc commented 10 years ago

Are there any plans to port RIOT to EFM32 microcontrollers? (ARM Cortex-M0/M3)

OlegHahm commented 10 years ago

The former Energy Micro Cortexes are definitely very interesting (particular in terms of power consumption). So far, there are no concrete plans for RIOT, but if you could point out an interesting platform with some low-power radio on it, I'm pretty sure, that you will find people interested in this task - or at least some help to do it yourself.

rasgo-cc commented 10 years ago

Actually I changed my mind a little bit. I'm currently developing a modular platform for smart devices (sensors/actuators) and I'm interested in using RIOT OS in EFM32 because I really like its simplicity, modularity and the way it is written but in this case I'm planning to use only the kernel features (threads, mutexes, etc). For the network part I'm using an atmega256rfr2 which already includes the radio. It will be great to have RIOT fully supported on that chip (MAC + 6lowpan). Unfortunately the only thing I can do as of now is showing some interest. As soon as I have some time to do some experiments I'll get back with some feedback.

ryankurte commented 10 years ago

Still any interest in this? I have a port to the EFM32GG here: https://github.com/ryankurte/RIOT running on the ST3700 evaluation kit, which should be pretty simple to extend to other efm32 families (copy a few files around). It basically just wraps the Silicon Labs libraries, with minimal modification so they can be dropped in when updated. Will look at a pull request when I can test it on a couple more CPUs.

librae8226 commented 10 years ago

This topic seems cool :+1: A quick question @ryankurte, I took a look at your porting, the silicon labs peripheral/cpu library is used, will it cause any issue for the RIOT? For example, there are some peripheral access using busy wait while in an RTOS, it should be sleeping on a semaphore or something similar, right?

ryankurte commented 10 years ago

The silicon labs peripheral library basically just provides abstraction from the required register operation, the same thing is used for the STM32 ports. Just have to make sure the appropriate methods are called. The drivers I have implemented match those in the STM32F0 project, having both interrupt driven and blocking calls (though SPI isn't finished). I haven't worked out how asynchronous mode is used in the kernel yet, presumably that is where sleeping should be implemented?

LudwigKnuepfer commented 10 years ago

http://riot-os.org/api/group__core__sched.html#details

haukepetersen commented 10 years ago

@ryankurte: You support for the EFM32 platform looks very promising indeed. Do you think there is a way to strip it down a bit by omitting the Silicon Labs libraries and building the port just on the CMSIS header as in cpu/efm32_common/Device/SiliconLabs/EFM32xx/Include/ as its done for the the existing ports?

ryankurte commented 10 years ago

There are definitely a few things I can clean up! At the moment the layout is:

Which was to minimize duplication, make it easy to switch between EFM32 processors, and to update if the Silabs files change (copy from paste the three efm32_common folders from the IDE).

My thoughts:

haukepetersen commented 10 years ago

Good to know that our CMSIS headers are outdated, we should update them in the cortex-m_common folders I guess. Then you can base your port on the common folder as well, so you don't need to worry about task switching and the other stuff that is in there.

The plan for the rest of the library sound good to me, looking forward to get your port into RIOT!

PeterKietzmann commented 9 years ago

@cidadao, anything in progress?

basilfx commented 8 years ago

I have created this script which initializes a cpu/exm32xx folder for each target that currently is supported by emlib (mentioned above). It creates configuration files, makefiles and linker scripts, based on actual parameters scraped from emlib. Although it is not ready yet and I certainly cannot test all targets, I hope to have it running on my STK3600 development kit soon. Just wanted to share this with anybody interested.

I have seen the support for EZR32WG by @haukepetersen which doesn't use emlib, but I think emlib doesn't add much overhead and certainly helps to bring RIOT-OS to more targets sooner. After all this issue is open for 1.5 years already.

haukepetersen commented 8 years ago

I must confess that I am not a big fan of vendor supplied board support libraries in general. In my experience they are often bloated and inefficient. Further they make portability over vendor borders not necessarily easier - often even in contrary... Above that I found, that it is also not much harder to configure and program a MCU on register level - as you have to understand how the peripherals are working in any case...

But in general I don't see a reason in using the emlib, as long as we can show that the overhead is indeed not that big. Further I would strongly vote for using RIOTs cortexm_common linkerscript, as we should use as much of the shared code as possible to simply maintenance for the future!

rasgo-cc commented 8 years ago

Hi all,

​​ Regarding the usage of emlib, it's actually not a board support package (BSP) but a generic peripheral library, so even if you code it by yourself, on register level, you'll end up doing similar things, and since emlib is developed and maintained by the SiliconLabs I guess it contains the "best practices" to use their own peripherals and eventually some workarounds to erratas. So, if I'm allowed to, I would like to vote this up in the hope it would accelerate the port to EFM32 and also to facilitate its maintenance.

On 17 November 2015 at 12:29, Hauke Petersen notifications@github.com wrote:

I must confess that I am not a big fan of vendor supplied board support libraries in general. In my experience they are often bloated and inefficient. Further they make portability over vendor borders not necessarily easier - often even in contrary... Above that I found, that it is also not much harder to configure and program a MCU on register level - as you have to understand how the peripherals are working in any case...

But in general I don't see a reason in using the emlib, as long as we can show that the overhead is indeed not that big. Further I would strongly vote for using RIOTs cortexm_common linkerscript, as we should use as much of the shared code as possible to simply maintenance for the future!

— Reply to this email directly or view it on GitHub https://github.com/RIOT-OS/RIOT/issues/1123#issuecomment-157357450.

Mário Ribeiro

haukepetersen commented 8 years ago

I fully understand, periph lib is what I meant (BSP was the wrong expression)...

I guess it contains the "best practices" to use their own peripherals and eventually some workarounds to erratas.

This is what one would think, but at least for other vendors this is not always the case...

Anyway, I'd say go ahead with the emlib inclusion for now and let's see where that leads. I think we have always the option to implement our periph interface using emlib functions and if we find these to be too in-efficient we can always switch to direct implementations as started for the wonder gecko.

The only thing I would really like to see is that we use as much of the existing infrastructure as possible, especially the common linkerscript!

ryankurte commented 8 years ago

In my opinion the Silabs extended CMSIS is pretty top notch, and any overhead should be optimised out anyway.

There are some peripheral implementations in the branch I started working on (https://github.com/ryankurte/RIOT/tree/efm32-support).

I did however have an issue with the common linker script, iirc the naming of vectors is the same but the capitalisation is not, so something might be needed to adapt the two.

basilfx commented 8 years ago

To demonstrate, I have merged an initial structure (via the bootstrap script) in my branch: https://github.com/basilfx/RIOT/tree/feature/efm32/cpu and https://github.com/basilfx/RIOT/tree/feature/efm32/boards. Note that I have remove the existing ezr32wg for now (when finished, I will not submit a PR for this branch without the existing ezr32wg).

I have re-used as much as possible from the existing cortex-m infrastructure.

The code compiles emlib, but the actual driver implementations are missing, so I'm currently at:

/Users/basilfx/SimplicityStudio/v3_workspace/src/bin/stk3600/uart_stdio.a(uart_stdio.o): In function `uart_stdio_init':
/Users/basilfx/SimplicityStudio/v3_workspace/lib/sys/uart_stdio/uart_stdio.c:73: undefined reference to `uart_init'
/Users/basilfx/SimplicityStudio/v3_workspace/src/bin/stk3600/uart_stdio.a(uart_stdio.o): In function `uart_stdio_write':
/Users/basilfx/SimplicityStudio/v3_workspace/lib/sys/uart_stdio/uart_stdio.c:87: undefined reference to `uart_write'
/Users/basilfx/SimplicityStudio/v3_workspace/src/bin/stk3600/stk3600_base.a(board.o): In function `board_init':
/Users/basilfx/SimplicityStudio/v3_workspace/lib/boards/stk_common/board.c:29: undefined reference to `gpio_init'
/Users/basilfx/SimplicityStudio/v3_workspace/lib/boards/stk_common/board.c:30: undefined reference to `gpio_set'
/Users/basilfx/SimplicityStudio/v3_workspace/lib/boards/stk_common/board.c:32: undefined reference to `gpio_init'
/Users/basilfx/SimplicityStudio/v3_workspace/lib/boards/stk_common/board.c:33: undefined reference to `gpio_init'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
haukepetersen commented 8 years ago

Looks interesting so far, though the most interesting part (implementation of the periph interfaces) is missing... Maybe you can start with uart, timer and gpio? Then we could compare the emlib based solution against my efm32wg port to figure out the pros/cons of both approaches. Easiest would be if you just open a PR with your changes and we continue discussion there?!

One more thing: I don't think it makes sense to include all possible EFMxx CPUs that are available... So far we only include CPU(models) that are actually used on a board that RIOT supports. Otherwise we end up with millions of lines of unused header files...

basilfx commented 8 years ago

I have started to work on the peripheral drivers. It compiles, but it is not working yet (I have to attach the debugger and read the manual, but wanted to get the code compiling first). Especially the timer is tricky for me.

As soon as I have the Hello World running I will make a PR.

I see your point of not including all targets. I have not filtered them or checked for minimal requirements. However, the existing EZR32WG plus @ryankurte's EFM32G (in his branch), and I the EFM32LG, EFM32WG and EFM32GG (STK3600, STK3700 and STK3800 devkits) I have access to makes five of nine CPUs already.

haukepetersen commented 8 years ago

cool. So don't worry about this now, we ca sort that out together when shaping your code for merging...

basilfx commented 8 years ago

Quick update: got basic GPIO, USART and SPI working (and running). Now working on timer.

I did a quick comparison of the binary sizes between the register-based approach (my initial attempt based on EZR32WG) and the emlib-based approach:

Register-based:

   text    data     bss     dec     hex filename
   7816     128    2744   10688    29c0 hello-world.elf

emlib-based:

   text    data     bss     dec     hex filename
  9544      136    2752   12432    3090 hello-world.elf

Not much difference, yet I can probably squeeze some more. But the code is more readable now, IMHO.

OlegHahm commented 8 years ago

I must confess I have little knowledge here, but 1.7kB aka 20% overhead in ROM doesn't seem to be negligible to me.

haukepetersen commented 8 years ago

The results look about what I had expected, in terms of efficiency even the best peripheral lib cannot compete with the direct register based approach in terms of run-time and memory.

So IMHO we should proceed like this:

basilfx commented 8 years ago

The MCU I test on has 256kb of flash. Therefore I find the additional 1.7kb not much :-)

I have compared both *.map (using amap) files and found out:

  1. About ~1kb of flash is used by the CMU_* methods. The CMU is used for setting up clocks/baudrate/speed calculations. Almost all peripherals use it.
  2. Another part of flash is occupied by initialization methods from emlib (e.g. USART_InitAsync). These methods ensure a consistent and valid initialization, depending on clocks/model/etc.
  3. Get/set/read/write/isr-related methods are negligible/not present. They are inlined or defined as macros, resulting in similar/same code as register-based ones.

The additional cost of (1) is expected to be 'constant': adding other peripherals will depend on the same methods. The cost of (2) is only during boot.

@haukepetersen I agree. Will try to keep code compatible both ways.

haukepetersen commented 8 years ago

Cool, then I am looking forward to your PR!

basilfx commented 8 years ago

Small update:

The new EFM32 Gemstone CPUs are a bit different. The peripherial clocks changed, GPIO interrupts changed and peripheral pin location is now flexible (for instance UART1 RX can be at location 1 while UART1 TX can be at location 7). There is now a proper RTC (not an RTT named RTC) and an extended crypto peripheral (have to investigate use for RNG).

I bought the SLSTK3401a and STK3200 devkits to test other platforms too. As a side project I also try to integrate u8glib as a package (different branch), to drive the LCDs on these devkits.

I still have to do a benchmark of code sizes and energy consumption. I don't regret the decision of picking the emlib, even if this means it will not get merged into RIOT-OS. It suites my needs and I learned a lot :-)

basilfx commented 8 years ago

I created PR #4722.

miri64 commented 8 years ago

Just to be clear: is #5652 still aiming to fix this issue?

basilfx commented 8 years ago

@miri64 Yes, I am still working on it.

PeterKietzmann commented 6 years ago

Now that #7929 and #8139 are merged we can close this issue I guess.

miri64 commented 6 years ago

8139 are merged

8139 isn't merged yet (maybe you referenced the wrong PR?), but I agree, that since we have support for this platform now, we can close this issue.