44package freertos
55
66// #include <freertos/FreeRTOS.h>
7+ // #include <freertos/queue.h>
78// #include <freertos/semphr.h>
89// #include <freertos/task.h>
10+ // void freertos_callFunction(void (*function)(void *), void *parameter);
911import "C"
1012import (
1113 "sync"
14+ "time"
1215 "unsafe"
1316
1417 "internal/task"
@@ -19,30 +22,66 @@ func xTaskGetCurrentTaskHandle() C.TaskHandle_t {
1922 return C .TaskHandle_t (task .Current ())
2023}
2124
25+ //export xTaskCreate
26+ func xTaskCreate (pvTaskCode C.TaskFunction_t , pcName * C.char , usStackDepth uintptr , pvParameters unsafe.Pointer , uxPriority C.UBaseType_t , pxCreatedTask * C.TaskHandle_t ) C.BaseType_t {
27+ go func () {
28+ C .freertos_callFunction (pvTaskCode , pvParameters )
29+ }()
30+ if pxCreatedTask != nil {
31+ // Code expectes there to be *something*.
32+ var tcb int
33+ * pxCreatedTask = unsafe .Pointer (& tcb )
34+ }
35+ return 1 // pdPASS
36+ }
37+
38+ //export vTaskDelay
39+ func vTaskDelay (xTicksToDelay C.TickType_t ) {
40+ // The default tick rate appears to be 100Hz (10ms per tick).
41+ time .Sleep (time .Duration (xTicksToDelay ) * C .portTICK_PERIOD_MS * time .Millisecond )
42+ }
43+
2244type Semaphore struct {
2345 lock sync.Mutex // the lock itself
2446 task * task.Task // the task currently locking this semaphore
2547 count uint32 // how many times this semaphore is locked
2648}
2749
50+ //export xSemaphoreCreateCounting
51+ func xSemaphoreCreateCounting (uxMaxCount C.UBaseType_t , uxInitialCount C.UBaseType_t ) C.SemaphoreHandle_t {
52+ if uxMaxCount != 1 || uxInitialCount != 0 {
53+ println ("TODO: xSemaphoreCreateCounting that's not a mutex" )
54+ return nil
55+ }
56+ mutex := Semaphore {}
57+ return C .SemaphoreHandle_t (& mutex )
58+ }
59+
2860//export xSemaphoreCreateRecursiveMutex
2961func xSemaphoreCreateRecursiveMutex () C.SemaphoreHandle_t {
3062 var mutex Semaphore
31- return (C .SemaphoreHandle_t )(unsafe . Pointer ( & mutex ) )
63+ return (C .SemaphoreHandle_t )(& mutex )
3264}
3365
3466//export vSemaphoreDelete
3567func vSemaphoreDelete (xSemaphore C.SemaphoreHandle_t ) {
36- mutex := (* Semaphore )(unsafe . Pointer ( xSemaphore ) )
68+ mutex := (* Semaphore )(xSemaphore )
3769 if mutex .task != nil {
3870 panic ("vSemaphoreDelete: still locked" )
3971 }
4072}
4173
74+ //export xSemaphoreTake
75+ func xSemaphoreTake (xSemaphore C.QueueHandle_t , xTicksToWait C.TickType_t ) C.BaseType_t {
76+ mutex := (* Semaphore )(xSemaphore )
77+ mutex .lock .Lock ()
78+ return 1 // pdTRUE
79+ }
80+
4281//export xSemaphoreTakeRecursive
4382func xSemaphoreTakeRecursive (xMutex C.SemaphoreHandle_t , xTicksToWait C.TickType_t ) C.BaseType_t {
4483 // TODO: implement xTickToWait, or at least when xTicksToWait equals 0.
45- mutex := (* Semaphore )(unsafe . Pointer ( xMutex ) )
84+ mutex := (* Semaphore )(xMutex )
4685 if mutex .task == task .Current () {
4786 // Already locked.
4887 mutex .count ++
@@ -54,9 +93,16 @@ func xSemaphoreTakeRecursive(xMutex C.SemaphoreHandle_t, xTicksToWait C.TickType
5493 return 1 // pdTRUE
5594}
5695
96+ //export xSemaphoreGive
97+ func xSemaphoreGive (xSemaphore C.QueueHandle_t ) C.BaseType_t {
98+ mutex := (* Semaphore )(xSemaphore )
99+ mutex .lock .Unlock ()
100+ return 1 // pdTRUE
101+ }
102+
57103//export xSemaphoreGiveRecursive
58104func xSemaphoreGiveRecursive (xMutex C.SemaphoreHandle_t ) C.BaseType_t {
59- mutex := (* Semaphore )(unsafe . Pointer ( xMutex ) )
105+ mutex := (* Semaphore )(xMutex )
60106 if mutex .task == task .Current () {
61107 // Already locked.
62108 mutex .count --
@@ -67,3 +113,44 @@ func xSemaphoreGiveRecursive(xMutex C.SemaphoreHandle_t) C.BaseType_t {
67113 }
68114 panic ("xSemaphoreGiveRecursive: not locked by this task" )
69115}
116+
117+ //export xQueueCreate
118+ func xQueueCreate (uxQueueLength C.UBaseType_t , uxItemSize C.UBaseType_t ) C.QueueHandle_t {
119+ return chanMakeUnsafePointer (uintptr (uxItemSize ), uintptr (uxQueueLength ))
120+ }
121+
122+ //export vQueueDelete
123+ func vQueueDelete (xQueue C.QueueHandle_t ) {
124+ // TODO: close the channel
125+ }
126+
127+ //export xQueueReceive
128+ func xQueueReceive (xQueue C.QueueHandle_t , pvBuffer unsafe.Pointer , xTicksToWait C.TickType_t ) C.BaseType_t {
129+ // Note: xTicksToWait is ignored.
130+ chanRecvUnsafePointer (xQueue , pvBuffer )
131+ return 1 // pdTRUE
132+ }
133+
134+ //export xQueueSend
135+ func xQueueSend (xQueue C.QueueHandle_t , pvBuffer unsafe.Pointer , xTicksToWait C.TickType_t ) C.BaseType_t {
136+ // Note: xTicksToWait is ignored.
137+ chanSendUnsafePointer (xQueue , pvBuffer )
138+ return 1 // pdTRUE
139+ }
140+
141+ //export uxQueueMessagesWaiting
142+ func uxQueueMessagesWaiting (xQueue C.QueueHandle_t ) C.UBaseType_t {
143+ return C .UBaseType_t (chanLenUnsafePointer (xQueue ))
144+ }
145+
146+ //go:linkname chanMakeUnsafePointer runtime.chanMakeUnsafePointer
147+ func chanMakeUnsafePointer (elementSize uintptr , bufSize uintptr ) unsafe.Pointer
148+
149+ //go:linkname chanLenUnsafePointer runtime.chanLenUnsafePointer
150+ func chanLenUnsafePointer (ch unsafe.Pointer ) int
151+
152+ //go:linkname chanSendUnsafePointer runtime.chanSendUnsafePointer
153+ func chanSendUnsafePointer (ch , value unsafe.Pointer )
154+
155+ //go:linkname chanRecvUnsafePointer runtime.chanRecvUnsafePointer
156+ func chanRecvUnsafePointer (ch , value unsafe.Pointer )
0 commit comments