Skip to content

Commit

Permalink
cgo: add FreeRTOS compatibility headers
Browse files Browse the repository at this point in the history
This is especially useful if we ever want to support the ESP-IDF.

Currently implemented:

  - xTaskGetCurrentTaskHandle
  - xSemaphoreCreateRecursiveMutex
  - xSemaphoreDelete
  - xSemaphoreTakeRecursive
  - xSemaphoreGiveRecursive
  • Loading branch information
aykevl committed Sep 27, 2021
1 parent 6542220 commit dcfa42c
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 0 deletions.
3 changes: 3 additions & 0 deletions compileopts/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ func (c *Config) RP2040BootPatch() bool {
// preprocessing.
func (c *Config) CFlags() []string {
var cflags []string
// Compatibility CFlags.
cflags = append(cflags, "-I"+filepath.Join(goenv.Get("TINYGOROOT"), "src/compat/freertos/include"))
// CFlags for the target.
for _, flag := range c.Target.CFlags {
cflags = append(cflags, strings.ReplaceAll(flag, "{root}", goenv.Get("TINYGOROOT")))
}
Expand Down
1 change: 1 addition & 0 deletions loader/goroot.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ func needsSyscallPackage(buildTags []string) bool {
func pathsToOverride(needsSyscallPackage bool) map[string]bool {
paths := map[string]bool{
"/": true,
"compat/": false,
"crypto/": true,
"crypto/rand/": false,
"device/": false,
Expand Down
69 changes: 69 additions & 0 deletions src/compat/freertos/freertos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Package freertos provides a compatibility layer on top of the TinyGo
// scheduler for C code that wants to call FreeRTOS functions. One example is
// the ESP-IDF, which expects there to be a FreeRTOS-like RTOS.
package freertos

// #include <freertos/FreeRTOS.h>
// #include <freertos/semphr.h>
// #include <freertos/task.h>
import "C"
import (
"sync"
"unsafe"

"internal/task"
)

//export xTaskGetCurrentTaskHandle
func xTaskGetCurrentTaskHandle() C.TaskHandle_t {
return C.TaskHandle_t(task.Current())
}

type Semaphore struct {
lock sync.Mutex // the lock itself
task *task.Task // the task currently locking this semaphore
count uint32 // how many times this semaphore is locked
}

//export xSemaphoreCreateRecursiveMutex
func xSemaphoreCreateRecursiveMutex() C.SemaphoreHandle_t {
var mutex Semaphore
return (C.SemaphoreHandle_t)(unsafe.Pointer(&mutex))
}

//export vSemaphoreDelete
func vSemaphoreDelete(xSemaphore C.SemaphoreHandle_t) {
mutex := (*Semaphore)(unsafe.Pointer(xSemaphore))
if mutex.task != nil {
panic("vSemaphoreDelete: still locked")
}
}

//export xSemaphoreTakeRecursive
func xSemaphoreTakeRecursive(xMutex C.SemaphoreHandle_t, xTicksToWait C.TickType_t) C.BaseType_t {
// TODO: implement xTickToWait, or at least when xTicksToWait equals 0.
mutex := (*Semaphore)(unsafe.Pointer(xMutex))
if mutex.task == task.Current() {
// Already locked.
mutex.count++
return 1 // pdTRUE
}
// Not yet locked.
mutex.lock.Lock()
mutex.task = task.Current()
return 1 // pdTRUE
}

//export xSemaphoreGiveRecursive
func xSemaphoreGiveRecursive(xMutex C.SemaphoreHandle_t) C.BaseType_t {
mutex := (*Semaphore)(unsafe.Pointer(xMutex))
if mutex.task == task.Current() {
// Already locked.
mutex.count--
if mutex.count == 0 {
mutex.lock.Unlock()
}
return 1 // pdTRUE
}
panic("xSemaphoreGiveRecursive: not locked by this task")
}
9 changes: 9 additions & 0 deletions src/compat/freertos/include/freertos/FreeRTOS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <stdint.h>

typedef uint32_t TickType_t;
typedef int BaseType_t;
typedef unsigned int UBaseType_t;

#define portMAX_DELAY (TickType_t)0xffffffffUL
3 changes: 3 additions & 0 deletions src/compat/freertos/include/freertos/queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

typedef struct QueueDefinition * QueueHandle_t;
12 changes: 12 additions & 0 deletions src/compat/freertos/include/freertos/semphr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

// Note: in FreeRTOS, SemaphoreHandle_t is an alias for QueueHandle_t.
typedef struct SemaphoreDefinition * SemaphoreHandle_t;

SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void);

void vSemaphoreDelete(SemaphoreHandle_t xSemaphore);

// Note: these two functions are macros in FreeRTOS.
BaseType_t xSemaphoreTakeRecursive(SemaphoreHandle_t xMutex, TickType_t xTicksToWait);
BaseType_t xSemaphoreGiveRecursive(SemaphoreHandle_t xMutex);
5 changes: 5 additions & 0 deletions src/compat/freertos/include/freertos/task.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

typedef void * TaskHandle_t;

TaskHandle_t xTaskGetCurrentTaskHandle(void);

0 comments on commit dcfa42c

Please sign in to comment.