Introduce embedded development using Swift

Hi @wally4u

But I would consider a NXP RT10xx series Cortex M7 way overpowered for typical embedded work. Not many manufactures will put a $12 MCU in cheap embedded hardware. Most if the embedded devices I have seen used in the field are Cortex M0 / M3 variant, with limited code memory (as you pointed out this is an issue with the std lib) and RAM. Setting the hardware targets high would limit the potential of Swift embedded only to well funded hobbyist or niche embedded markets.

The price you pointed out is not correct. When NXP released the RT10xx MCU, they announced it was the most cost-effective MCU in the market. The 1k price is about $3 each. But due to the chip shortage, it’s really hard to order them now. The actual price is about $4 - $6 if you can find a good supplier. But you need to wait more than 50 weeks to get (or keep waiting) your order. If the quantify is too small, you have to find a retailer such as Digi-Key, the price is from $10 - $20. This is a supply chain problem and it’s out of our control.

A secondary item (much lower priority than getting a hello world fit in 64k), would be CMSIS support, as you would need some proper way of accessing the hardware peripherals from within Swift code. I'm not really sure how the compiler would handle the CMSIS-Core Device Templates (C code/asm/macros) for getting the bare mental up and running.

The CMSIS stuff is already handled by Zephyr. There are so many different hardware archs in the embedded world. It’s definitely a disaster if you need to deal with each of them. We choose Zephyr to avoid any hardware details. Zephyr provides standard APIs to visit those peripherals. So once Zephyr provides RISC-V support, it’s not hard to port our work to the arch.

1 Like

Hi @ericlewis, happy to hear that someone is working on the same target : )

Very good question : )

Firstly, as I said, RTOS is normally provided at source code level. It is just a batch of C code. It's a very ordinary library whose name is “RTOS”. Your app code and the RTOS code form the final application which runs on bare-metal. So using a toolchain targeting bare-metal is the normal case no matter if you use an RTOS.

Secondly, the OS in the target triple is used by the compiler to invoke some standard OS APIs. The main general OSes provide similar APIs for the fundamental operations, there’s only tiny difference between them. Unfortunately, this standard doesn’t exist in RTOS world. There are hundreds of different RTOSes. Just chaos.

Since Zephyr has the ambition to rule the place that Linux cannot cover, I believe the situation would be different in the near future. They do have the plan to add the zephyr target into GCC compiler. Once they don't change their API day to day :sweat_smile:, that’s the time we can start considering adding it into Swift/LLVM toolchain.

1 Like

Hi @andyliu,
I just went to findchips for the pricing info. And yes, it is mostly a supply constraint at the moment.
What I was trying to say was (at least in my experience) that the most embedded chips are not 600MHz Cortex M7 chips but more lower end MCU like the Cortex M0/M3 types.
If the idea is to support lower end chips eventually but to get it working on a higher end first (more room / faster etc) I fully understand, since there is little to no room on an M0. But I would like to make the point that lower end MCUs are in much larger volume and not taking these into account for swift embedded would be missing a large target audience.

I'm happy to read that CMSIS support is already in Zephyr, although in a limited fashion. I will take a further look into Zephyr. A quick read of the original link didn't mention CMSIS (my assumption that it was missing was incorrect) but I am more familiar with RTX / FreeRTOS / SafeRTOS, which are CMSIS compliant.

Please do not misunderstand me that I am criticizing what you are tying to do, I fully support your idea :100: and the time you are spending on this. I am just trying to give some input from someone who spend the last 20 years working on embedded devices.

2 Likes

Never thought to meet any embedded engineer here :handshake:

I really appreciate your advice. And you are right, our plan is to use this high-end chip to find out the limitation of Swift in this area. If everything goes well, we can do some cost-down work then. Due to the chip shortage, seems there is still a long way to go :joy:

2 Likes

Good to hear. I can’t wait to program my keyboard using swift. https://zmk.dev/

1 Like

Very interesting! I know that some RTOS provide posix compatibility layers, like freeRTOS. Would make targeting generic unix pretty easy.

1 Like

Zephyr is very promising. Of course, they won't miss this part :joy:. But it is still tough to combine all these stuff together.

Something I have found really interesting is the way SwiftWASM has approach their project. If you look closely at their additions to the codebases you can see how similar it is to bare-metal-esque targets. I have been reading into it even more and am slowly working towards creating something similar for thumbv7em targets, with the hope that it can be kept in sync with upstream until it can be upstreamed.

edit: assuming we use the thumbv7em target that is already in LLVM.

2 Likes

I'm working on the Swift 5.6 source recently (Not finished yet). This commit is all the modification you need to add thumbv7em triple.

1 Like

Yeah, I followed this patch: Driver: add support for baremetal targets by compnerd · Pull Request #35970 · apple/swift · GitHub which does something similar except doesn't add the os(MadMachine) but instead just os(none) switch.

edit: at least it should do that. I have trouble with this sometimes lol.

I'm a huge proponent of being able to use Swift in embedded projects, so this is great work! But I do think we need to be able to target Cortex M0 and M4 MCUs, as well.

4 Likes

This is awesome! Would love to be able to use swift develop firmware:

possibly/maybe related to the C++ Interop work group?

1 Like

Thank you for this great post, @andyliu! I've sent out a call for interest for a video call to kickoff more community discussion in these areas:

7 Likes

I have already sent the survey. Thank you for arranging such a discussion :grin:

1 Like

Sort of off topic - but I believe that M4 and M7 use the same instruction set so it would probably work?

Yeah, M4 and M7 mostly share the same instruction set. The only critical problems are still the runtime binding and std size.

I can add extra Flash and RAM to the M7 MCU easily, but this is hard to do with most M4 based MCU :face_exhaling:

1 Like

Did anyone work on getting Swift usable on RISC-V yet? In particular the ESP-C3 looks like an interesting target.

4 Likes

I've build Swift for RISCV64 and Buildroot. The caveat is that I only was able to compile targeting Soft Float.

3 Likes

In the previous release, I added flags to the Swift frontend, but I found that there were standard flags later.

Now I use -Xcc -mhard-float, -Xcc -mfloat-abi=hard flags to tell the compiler to generate hard float instruction and ABI. I don't know if this would work in RISCV64.

2 Likes

I did try that, it was an issue of Clang assuming soft float for Swift when specifying the triple. Wasn't a dealbreaker for me.

3 Likes