-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtask.hpp
160 lines (130 loc) · 4.41 KB
/
task.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*================================================================================
* Multitasking helper functions
*================================================================================*/
#define TASK1_CORE 1
#define TASK2_CORE 0
#define TASK1_STACK 8192
#define TASK2_STACK 8192
#define TASK1_PRIORITY 2
#define TASK2_PRIORITY 1
// Message queue sent from task 1 to task 2
typedef struct {
uint8_t bank; // Exclusive bank numbers for Task 1 and Task 2
uint32_t start; // Task 1 start time
uint32_t finish; // Task 1 Finish Time
} MessageQueue_t;
// Define two tasks on the core
void Task1(void *pvParameters);
void Task2(void *pvParameters);
// Define pointers to the tasks
static void (*Process1)(uint8_t bank);
static void (*Process2)(uint8_t bank, uint32_t start, uint32_t finish);
// Message queues and semaphores for handshaking
static TaskHandle_t taskHandle[2];
static QueueHandle_t queHandle;
static SemaphoreHandle_t semHandle;
#define HALT() { for(;;) delay(1000); }
#define WAIT_QUEUE portTICK_PERIOD_MS // portMAX_DELAY
#define NOT_UPDATED 0xFF
// The setup function runs once when press reset or power on the board
void task_setup(void (*task1)(uint8_t), void (*task2)(uint8_t, uint32_t, uint32_t)) {
// Pointers to the tasks to be executed.
Process1 = task1;
Process2 = task2;
// Task1 start immediately --> Process1 --> Task1 send queue --> Task1 wait for semaphre
// --> Task2 receive queue --> Process2 --> Task2 give semaphre --> Task2 wait queue
// --> Task1 take sepahore --> Process1 --> ...
semHandle = xSemaphoreCreateCounting(1, TASK1_CORE != TASK2_CORE ? 0 : 0);
queHandle = xQueueCreate(1, sizeof(MessageQueue_t));
// Check if the queue or the semaphore was successfully created
if (queHandle == NULL || semHandle == NULL) {
DBG_EXEC(printf("Can't create queue or semaphore.\n"));
HALT();
}
// Set up sender task in core 1 and start immediately
xTaskCreatePinnedToCore(
Task1, "Task1",
TASK1_STACK, // The stack size
NULL, // Pass reference to a variable describing the task number
TASK1_PRIORITY, // priority
&taskHandle[0], // Pass reference to task handle
TASK1_CORE
);
// Set up receiver task on core 0 and start immediately
xTaskCreatePinnedToCore(
Task2, "Task2",
TASK2_STACK, // The stack size
NULL, // Pass reference to a variable describing the task number
TASK2_PRIORITY, // priority
&taskHandle[1], // Pass reference to task handle
TASK2_CORE
);
}
/*--------------------------------------------------*/
/*------------------- Handshake --------------------*/
/*--------------------------------------------------*/
uint8_t SendQueue(uint8_t bank, uint32_t start, uint32_t finish) {
MessageQueue_t queue = {
bank, start, finish
};
if (xQueueSend(queHandle, &queue, portMAX_DELAY) == pdTRUE) {
// DBG_EXEC(printf("Give queue: %d\n", queue.bank));
} else {
DBG_EXEC(printf("unable to send queue\n"));
}
return !bank;
}
MessageQueue_t ReceiveQueue() {
MessageQueue_t queue;
if (xQueueReceive(queHandle, &queue, portMAX_DELAY) == pdTRUE) {
// DBG_EXEC(printf("Take queue: %d\n", queue.bank));
} else {
DBG_EXEC(printf("Unable to receive queue.\n"));
}
return queue;
}
bool ScanQueue(MessageQueue_t &queue) {
if (xQueueReceive(queHandle, &queue, WAIT_QUEUE) == pdTRUE) {
return true;
} else {
return false;
}
}
void TakeSemaphore(void) {
if (xSemaphoreTake(semHandle, portMAX_DELAY) == pdTRUE) {
// DBG_EXEC(printf("Take semaphore.\n"));
} else {
DBG_EXEC(printf("Unable to take semaphore.\n"));
}
}
void GiveSemaphore(void) {
if (xSemaphoreGive(semHandle) == pdTRUE) {
// DBG_EXEC(printf("Give semaphore.\n"));
} else {
DBG_EXEC(printf("Unable to give semaphore.\n"));
}
}
/*--------------------------------------------------*/
/*--------------------- Tasks ----------------------*/
/*--------------------------------------------------*/
void Task1(void *pvParameters) {
uint8_t bank = 0;
while (true) {
uint32_t start = millis();
Process1(bank);
bank = SendQueue(bank, start, millis());
TakeSemaphore();
}
}
void Task2(void *pvParameters) {
MessageQueue_t queue;
while (true) {
if (ScanQueue(queue)) {
GiveSemaphore();
} else {
queue.bank = NOT_UPDATED;
}
Process2(queue.bank, queue.start, queue.finish);
yield(); // Prevent the watchdog from firing
}
}