Help getting started with a Kotlin native port #17
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#17
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
With the SDK there is no CMake target for generating static C libraries. For some programming languages like Kotlin it needs the header files, and the dynamic/static library files in order to do interop with the C libraries. Rust also has similar requirements.
The maintainers need to decide if the SDK will be accessible to programming languages other than C/C++ like Kotlin, and Rust for example.
Well, usually it works just opposite - Kotlin (or Rust, or whatever) creates static library (*.a) file, and that file is linked by SDK to create flashable image file.
That is certainly the preferred approach. Just having a static library of the SDK linked in to your "kotlin" is unlikely to work.
@napperley would be really good to know your exact use case (in terms of how much runtime scaffolding you need under Kotlin native)
I have made this standalone example in branch of pico-playground
https://github.com/raspberrypi/pico-playground/tree/wip_make_helper/standalone/static_sdk
which isn't the solution, but might help you if you really need it
Wouldn't the elf2uf2 tool (included in the SDK) fix the problem?
No; elf2uf2 just translates the mapped segments in the ELF into UF2 sectors, it doesn't modify the binary itself
It is hard to help you further when you haven't answered any of the questions that have been asked.
Asked another way, what do you need?
etc.
If you are just taking a native application and hoping to link it for the RP2040/Pico then, once again, far and away the simplest/best thing to do is to create a static library with your stuff, and link it into a binary using the SDK build
Anything else requires more thought, and more information
In response to your questions:
Since static libraries don't have an entry point how is the SDK going to link a static library with a binary? What is providing the binary that knows how to call the static library, and what is the standard structure used by a static library?
Ok, so you arent needing to do something low level like Rust, you are basically a C app with some extra libraries (and static compiled Kotlin code)?
To link the static library, i had intended that you create a bootstrap main() method app which calls a method in your static library with calls your main
Correct. Kotlin unlike Rust is a high level, statically typed programming language. With Linux for example Kotlin can be used to do high level Linux development (aka user space programs), and Kotlin's C/platform interop/integration is deep enough that many existing tools which support C programs can be used with Kotlin programs (readelf, gdb, lldb etc).
Sounds like some thought needs to be put into the SDK with how the embedded software life cycle works, and how to architect embedded programs. Your proposed structure is ok, however it would be better to call the method onApplicationStart since that method handles the event when the application starts up. The name main is a bit confusing since it implies a entry point in a program, when in fact a static library is being used as part of the bootstrapping process.
Yup, I know what Kotlin is (ardent IntelliJ user), however I haven't looked at Kotlin native, so was asking.
We provide scaffolding that does c-runtime initialization and calls main(), because that seemed friendly to C users. I assume your Kotlin runtime starts at main() too.
You can call your method whatever you like... you said that your static library had no entry point, so I said make one and call it from the main method.
Currently Kotlin/Native does not support baremetall applications in default distribution, but two years ago it experimented with Zephyr RTOS on STM32F4 board (essentially same as RPi Pico)
LED blinking example: https://github.com/JetBrains/kotlin-native/blob/master/samples/zephyr/src/main.kt
That's cool; it shouldn't be too hard to get going, and we'd love to help more, but we're working on lots of things right now!
The SDK works the way it does with good reasons; it isn't the same for embedded as it is for your desktop compile source, link against a library and run. However we designed the CMake build to hide lots of complexity from you and build nicely tuned binaries off the bat, and give the user the power to cleanly have finer control if they want. A c user is very familiar with a main() method that runs their code.
You can read https://datasheets.raspberrypi.org/pico/sdk/pico_c_sdk.pdf for some intro on this.
Yes, although the type signature(s) are different from the C version:
Plain Version
Program Arguments Version
If Kotlin Native is used then the entry point (usually packageName.fileName without the kt file extension) needs to be passed to konan (the Kotlin Native compiler), eg with the main function in the main.kt file (in the org.example.blinky package) that would be org.example.blinky.main.
See Kotlin/Native runtime:
github.com/JetBrains/kotlin-native@1f0dd81742/runtime/src/launcher/cpp/launcher.cpp (L66)inactive