Like any programmer, I’m too lazy to go check the ...
# kotlin-native
l
Like any programmer, I’m too lazy to go check the charging status of my car, so I’d like to spend time programming a microcontroller to send data it gets from CANBus over LoRa to my desktop, where it can be processed and sent to my phone. Normally, I’d reach for a RasPi pico and Rust, but I’d like to use Kotlin this time. Is zephyr support good enough that I could buy a disco board, or should I go for a RasPi zero and run Kotlin on embedded Linux? I’m a bit concerned about power consumption if I go full embedded Linux.
n
Don't bother with the STM32 Zephr K/N target since it isn't officially supported, and has many build issues (a significant amount of the build process isn't covered by Gradle). Also the use of Zephr as an RTOS will significantly reduce the amount of hardware resources that are made available to a Kotlin program. ROM space will be a big issue.
If power usage isn't a big issue then head down the easy route by using a Rpi Zero with Kotlin Native, and some major C libraries to cover the Embedded stuff.
Microcontroller Embedded development with Kotlin (via Kotlin Native) is a very low priority for the Kotlin team. If they were to do it in the future then the Rpi Pico would likely be the first Microcontroller board supported, alongside the RP2040 Microcontroller chip; bare metal without relying on an RTOS. By officially supporting the chip many other Microcontroller boards are supported as well (by proxy).
m
Well, zephyr can run on 8kb devices (https://docs.zephyrproject.org/2.6.0/samples/basic/minimal/README.html), while K/N runtime eats at least 250kb, so zephyr isn't resource hog here. But yes, that was failed attempt.
n
A Microcontroller board with a ROM size of 1 MB or greater would be sufficient. Although a ROM size of 2 MB would be better considering that Kotlin Native programs aren't very well optimised for binary size.
@Pavel Punegov [JB] - Presumably binary size isn't a high priority for Kotlin Native, yet ⏲️ .
@msink - If you were to port Kotlin to Microcontrollers again would you head down the ARM bare metal route, instead of using an RTOS?
m
Bare metal cannot be written in pure Kotlin, because of it's memory model, low-level layers anyway have to be written on something more low-level like C or Rust. So why not just use something already existing and tested like RTOS?
n
I don't think that is correct with Kotlin. There are some other languages using GC for memory management which work Bare Metal on uC's. One such language is Go (via TinyGo - https://tinygo.org/ ):

https://www.youtube.com/watch?v=75VGzwtmgXc

m
Well sure it can be done, but definitely it's not easy and requires much more human-resources than wrapping existing RTOS. And AFAIK currently K/N team at JetBrains just don't have resources for anything in this area.
n
Even though the K/N team don't have sufficient resources to port Kotlin to a uC, there will eventually be a situation where they will very likely make a big push for Kotlin in uC development 🔮. K/N is mainly focused on Mobile development, but will need its focus expanded in order for K/N to be a viable Kotlin development platform in the long run otherwise there isn't much point in continuing K/N. The Kotlin team might need to create a new Kotlin development platform called Kotlin Mobile, and deprecate K/N if K/N's focus isn't pushed far beyond Mobile development. Hopefully I don't think anyone wants to see that happen 🙏.
l
They're doing a lot in the native desktop platform right now. I think they need K/N on iOS to be as good as possible to bring people to the platform, so it makes sense to focus on that for now. As iOS support gets better, I hope they revisit uC platforms.
n
In the long run I think that the Embedded/IoT development areas will provide far more opportunities (aka "opens more doors") than iOS development. Desktop development does provide some opportunities for Kotlin to expand its reach. However Kotlin will go much further in the Embedded/IoT development areas. This could be Kotlin's long term future direction. I know that the Kotlin team weren't planning to expand Kotlin to additional platforms, however they will need to seriously reconsider their position ( https://youtrack.jetbrains.com/issue/KT-44498/Add-RP2040-As-A-Kotlin-Native-Target ; https://youtrack.jetbrains.com/issue/KT-43974/More-flexible-cross-compilation-in-KotlinNative ), especially for Kotlin's long term viability. With the Cross Compilation issue there is one use case that stands out far above the rest. Using Kotlin for uC development ( https://youtrack.jetbrains.com/issue/KT-43974/More-flexible-cross-compilation-in-KotlinNative#focus=Comments-27-4606068.0-0 ).
l
They removed the bitcode option from the gradle task, but it's still in the command line compiler. In theory, if someone could write a smaller runtime in C, it would be possible to compile to bitcode and use llvm to convert to machine code, then link against the smaller runtime binary. Maybe even remove some features like exceptions.
n
Removing Kotlin features to get Kotlin working in a uC environment potentially leads down a big rabbit hole. The big concern here is ensuring Kotlin for uC's is the same language that is used on other platforms (JVM, Linux, Embedded Linux etc), and not a foreign programming language that kind of looks/behaves like Kotlin. Some programming languages like Python, and Go fall into this programming language fragmentation trap.
@Landry Norris - If exceptions are being removed from Kotlin to get it working on uC's then what replaces it for error handling?
l
Maybe we could get exceptions, but without stacktraces when the RAM is too small?
n
That might work, along with a compiler option to ignore exceptions (that only works when applied to a uC target).
l
Why would you want to ignore exceptions, and how?
n
To gain the full performance benefits of not having exceptions. With Embedded development there is a huge focus on performance rather than developer productivity. The Kotlin compiler would generate alternative Kotlin Intermediate Bytecode without the exception handling in cases where exceptions are detrimental to performance (eg Embedded development).
m
About performance - main bottleneck here is that Kotlin actively uses heap memory, much more actively than typical embedded soft. Currently all Kotlin objects are placed on heap, even local. Opposite to embedded - hard real time soft like DSP do not use heap at all.
n
Value classes ( https://kotlinlang.org/docs/inline-classes.html ) should partially address the issue where Kotlin relies too heavily on the heap. More flexibility will need to be added to Value classes to make them more useful (eg multiple properties in the primary constructor), and cover additional use cases. There may be other stuff in the works for Kotlin where more of the stack can be used rather than the heap. It is very likely that many libraries in the Kotlin ecosystem will need to be significantly redesigned (undergo significant changes) in order to work on uC platforms like the RP2040 ( https://www.raspberrypi.com/products/rp2040/ ), and Raspberry Pi Pico ( https://www.raspberrypi.com/products/raspberry-pi-pico/ ) for example. One thing is for sure that there will need to be article(s) on the official Kotlin website that cover performance with uC development, like Embedded development best practises with Kotlin for example. What other Kotlin language features apart from Value classes use the stack instead of the heap?