4
4
package freertos
5
5
6
6
// #include <freertos/FreeRTOS.h>
7
+ // #include <freertos/queue.h>
7
8
// #include <freertos/semphr.h>
8
9
// #include <freertos/task.h>
10
+ // void freertos_callFunction(void (*function)(void *), void *parameter);
9
11
import "C"
10
12
import (
11
13
"sync"
14
+ "time"
12
15
"unsafe"
13
16
14
17
"internal/task"
@@ -19,30 +22,66 @@ func xTaskGetCurrentTaskHandle() C.TaskHandle_t {
19
22
return C .TaskHandle_t (task .Current ())
20
23
}
21
24
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
+
22
44
type Semaphore struct {
23
45
lock sync.Mutex // the lock itself
24
46
task * task.Task // the task currently locking this semaphore
25
47
count uint32 // how many times this semaphore is locked
26
48
}
27
49
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
+
28
60
//export xSemaphoreCreateRecursiveMutex
29
61
func xSemaphoreCreateRecursiveMutex () C.SemaphoreHandle_t {
30
62
var mutex Semaphore
31
- return (C .SemaphoreHandle_t )(unsafe . Pointer ( & mutex ) )
63
+ return (C .SemaphoreHandle_t )(& mutex )
32
64
}
33
65
34
66
//export vSemaphoreDelete
35
67
func vSemaphoreDelete (xSemaphore C.SemaphoreHandle_t ) {
36
- mutex := (* Semaphore )(unsafe . Pointer ( xSemaphore ) )
68
+ mutex := (* Semaphore )(xSemaphore )
37
69
if mutex .task != nil {
38
70
panic ("vSemaphoreDelete: still locked" )
39
71
}
40
72
}
41
73
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
+
42
81
//export xSemaphoreTakeRecursive
43
82
func xSemaphoreTakeRecursive (xMutex C.SemaphoreHandle_t , xTicksToWait C.TickType_t ) C.BaseType_t {
44
83
// TODO: implement xTickToWait, or at least when xTicksToWait equals 0.
45
- mutex := (* Semaphore )(unsafe . Pointer ( xMutex ) )
84
+ mutex := (* Semaphore )(xMutex )
46
85
if mutex .task == task .Current () {
47
86
// Already locked.
48
87
mutex .count ++
@@ -54,9 +93,16 @@ func xSemaphoreTakeRecursive(xMutex C.SemaphoreHandle_t, xTicksToWait C.TickType
54
93
return 1 // pdTRUE
55
94
}
56
95
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
+
57
103
//export xSemaphoreGiveRecursive
58
104
func xSemaphoreGiveRecursive (xMutex C.SemaphoreHandle_t ) C.BaseType_t {
59
- mutex := (* Semaphore )(unsafe . Pointer ( xMutex ) )
105
+ mutex := (* Semaphore )(xMutex )
60
106
if mutex .task == task .Current () {
61
107
// Already locked.
62
108
mutex .count --
@@ -67,3 +113,44 @@ func xSemaphoreGiveRecursive(xMutex C.SemaphoreHandle_t) C.BaseType_t {
67
113
}
68
114
panic ("xSemaphoreGiveRecursive: not locked by this task" )
69
115
}
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
+ // Nothing to do. The garbage collector will clean up the queue.
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