tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
15.53k stars 915 forks source link

Feasibility of linking tinygo with existing C project #2121

Open BenShen98 opened 3 years ago

BenShen98 commented 3 years ago

Background: I am working on an IoT project involving ZigBee SDK (pre-compiled archive & C code) and FreeRTOS (C & ASM). Targeted for nrf52840 (1MB flash, 256KB RAM) and similar board.

I was writing code in pure C, mainly 1) RTOS scheduling for running tasks 2) Protothread-like scheduling for event-based "jobs" within a task (using full-blown RTOS task would create too much overhead) 3) I am also thinking to add a consensus algorithm for job configurations

I am considering replacing 2) and 3) with golang, since the language got concurrency build in. And I might be able to use an existing consensus algorithm written in go (e.g. etcd/raft).

Question:

  1. I understand tinygo uses LLVM to produce an optimised objective file. The Call-Convention section in the docs mentioned the argument with only integer and pointers will be stable. Does it mean I can invoke functions written in go with a pointer to a C struct, and by using cgo, I can parse the C struct in go without any problem?
  2. On the tinygo documentation, I see more of how to use c code within go. Rather than how to link go code to existing C project. Is this intentional, what are the downsides of doing this?

PS: I know here is not the best place to ask newbie questions, but I can't find a forum online. Hope it will be informative to other people as well.

deadprogram commented 3 years ago

@BenShen98 you might be better off asking in our Slack channel here https://app.slack.com/client/T029RQSE6/CDJD3SUP6

aykevl commented 3 years ago

Does it mean I can invoke functions written in go with a pointer to a C struct, and by using cgo, I can parse the C struct in go without any problem?

Yes, this should work correctly.

  1. On the tinygo documentation, I see more of how to use c code within go. Rather than how to link go code to existing C project. Is this intentional, what are the downsides of doing this?

This is not really a supported configuration. At the moment, all baremetal targets (including nrf52840) assume that the runtime will initialize the whole system. For example, the following:

Very small pieces of code may be able to run without these things initialized, but any significant amount of code will require these things to be initialized. So it's important that the runtime is initialized. This normally means that the runtime will handle all the chip initialization.

As one example, if you want to use the concurrency primitives in Go, you have to use the TinyGo scheduler (not the FreeRTOS scheduler). The FreeRTOS scheduler could technically be used instead, but this is not implemented.