Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6fb5ec0

Browse filesBrowse files
committed
Added some examples
Based on examples from: https://github.com/greiman/FreeRTOS-Arduino Signed-off-by: Frederic.Pillon <frederic.pillon@st.com>
1 parent 4f0b266 commit 6fb5ec0
Copy full SHA for 6fb5ec0

File tree

Expand file treeCollapse file tree

2 files changed

+256
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+256
-0
lines changed
+72Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Test to determine context switch time with a semaphore
2+
// Connect a scope to LED_BUILTIN pin
3+
// Measure difference in time between first pulse with no context switch
4+
// and second pulse started in ledControl and ended in ledOffTask.
5+
// This is the time for the semaphore and a context switch.
6+
#include <STM32FreeRTOS.h>
7+
8+
#define LED_PIN LED_BUILTIN
9+
// Semaphore to trigger context switch
10+
SemaphoreHandle_t xSemaphore;
11+
//------------------------------------------------------------------------------
12+
// high priority thread to set pin low
13+
static void ledOffTask(void *pvParameters) {
14+
for (;;) {
15+
xSemaphoreTake(xSemaphore, portMAX_DELAY);
16+
digitalWrite(LED_PIN, LOW);
17+
}
18+
}
19+
//------------------------------------------------------------------------------
20+
// lower priority thread to toggle LED and trigger thread 1
21+
static void ledControl(void *pvParameters) {
22+
for (;;) {
23+
// first pulse to get time with no context switch
24+
digitalWrite(LED_PIN, HIGH);
25+
digitalWrite(LED_PIN, LOW);
26+
27+
// start second pulse
28+
digitalWrite(LED_PIN, HIGH);
29+
30+
// trigger context switch for task that ends pulse
31+
xSemaphoreGive(xSemaphore);
32+
33+
// sleep until next tick
34+
vTaskDelay(1);
35+
}
36+
}
37+
//------------------------------------------------------------------------------
38+
void setup() {
39+
Serial.begin(9600);
40+
pinMode(LED_PIN, OUTPUT);
41+
42+
// create high priority thread
43+
xTaskCreate(ledOffTask,
44+
"Task1",
45+
configMINIMAL_STACK_SIZE,
46+
NULL,
47+
tskIDLE_PRIORITY + 2,
48+
NULL);
49+
50+
// create lower priority thread
51+
xTaskCreate(ledControl,
52+
"Task2",
53+
configMINIMAL_STACK_SIZE,
54+
NULL,
55+
tskIDLE_PRIORITY + 1,
56+
NULL);
57+
58+
// create semaphore
59+
vSemaphoreCreateBinary(xSemaphore);
60+
61+
// start FreeRTOS
62+
vTaskStartScheduler();
63+
64+
// should never return
65+
Serial.println("Die");
66+
while(1);
67+
}
68+
//------------------------------------------------------------------------------
69+
void loop() {
70+
// Not used - idle loop has a very small, configMINIMAL_STACK_SIZE, stack
71+
// loop must never block
72+
}
+184Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// Data logger based on a FIFO to decouple SD write latency from data
2+
// acquisition.
3+
4+
// The FIFO uses two semaphores to synchronize between tasks.
5+
6+
#include <SPI.h>
7+
#include <STM32FreeRTOS.h>
8+
#include <SD.h>
9+
10+
// interval between points in units of 1000 usec
11+
const uint16_t intervalTicks = 1;
12+
//------------------------------------------------------------------------------
13+
// SD file definitions
14+
const uint8_t sdChipSelect = SS;
15+
File file;
16+
//------------------------------------------------------------------------------
17+
// Fifo definitions
18+
19+
// size of fifo in records
20+
const size_t FIFO_SIZE = 200;
21+
22+
// count of data records in fifo
23+
SemaphoreHandle_t fifoData;
24+
25+
// count of free buffers in fifo
26+
SemaphoreHandle_t fifoSpace;
27+
28+
// data type for fifo item
29+
struct FifoItem_t {
30+
uint32_t usec;
31+
int value;
32+
int error;
33+
};
34+
// array of data items
35+
FifoItem_t fifoArray[FIFO_SIZE];
36+
//------------------------------------------------------------------------------
37+
// handle for sensor task
38+
TaskHandle_t sens;
39+
static void Task1(void *arg) {
40+
// index of record to be filled
41+
size_t fifoHead = 0;
42+
43+
// count of overrun errors
44+
int error = 0;
45+
46+
// dummy data
47+
int count = 0;
48+
49+
// initialise the ticks variable with the current time.
50+
TickType_t ticks = xTaskGetTickCount();
51+
52+
while (1) {
53+
// wait until time for next data point
54+
vTaskDelayUntil(&ticks, intervalTicks);
55+
56+
// get a buffer
57+
if (xSemaphoreTake(fifoSpace, 0) != pdTRUE) {
58+
// fifo full - indicate missed point
59+
error++;
60+
continue;
61+
}
62+
FifoItem_t* p = &fifoArray[fifoHead];
63+
p->usec = micros();
64+
65+
// replace next line with data read from sensor
66+
// f
67+
p->value = count++;
68+
69+
p->error = error;
70+
error = 0;
71+
72+
// signal new data
73+
xSemaphoreGive(fifoData);
74+
75+
// advance FIFO index
76+
fifoHead = fifoHead < (FIFO_SIZE - 1) ? fifoHead + 1 : 0;
77+
}
78+
}
79+
//------------------------------------------------------------------------------
80+
// SD write task
81+
static void Task2(void *arg) {
82+
// FIFO index for record to be written
83+
size_t fifoTail = 0;
84+
85+
// time in micros of last point
86+
uint32_t last = 0;
87+
88+
while(1) {
89+
// wait for next data record
90+
xSemaphoreTake(fifoData, portMAX_DELAY);
91+
92+
FifoItem_t* p = &fifoArray[fifoTail];
93+
94+
// print interval between points
95+
if (last) {
96+
file.print(p->usec - last);
97+
} else {
98+
file.write("NA");
99+
}
100+
last = p->usec;
101+
file.write(',');
102+
file.print(p->value);
103+
file.write(',');
104+
file.println(p->error);
105+
106+
// release record
107+
xSemaphoreGive(fifoSpace);
108+
109+
// advance FIFO index
110+
fifoTail = fifoTail < (FIFO_SIZE - 1) ? fifoTail + 1 : 0;
111+
112+
// check for end run
113+
if (Serial.available()) {
114+
// close file to insure data is saved correctly
115+
file.close();
116+
117+
// print messages
118+
Serial.println(F("Done"));
119+
Serial.print(F("Task1 unused stack entries: "));
120+
Serial.println(uxTaskGetStackHighWaterMark(sens));
121+
Serial.print(F("Task2 unused stack entries: "));
122+
Serial.println(uxTaskGetStackHighWaterMark(0));
123+
// ARM free heap not implemented yet
124+
// Serial.print(F("Free heap (bytes): "));
125+
// Serial.println(freeHeap());
126+
while(1);
127+
}
128+
}
129+
}
130+
//------------------------------------------------------------------------------
131+
void setup() {
132+
// task creation status
133+
portBASE_TYPE s1, s2;
134+
135+
Serial.begin(9600);
136+
while(!Serial);
137+
Serial.println(F("Type any character to begin"));
138+
while(!Serial.available());
139+
140+
// open file
141+
if (!SD.begin(sdChipSelect)) {
142+
Serial.println("Card failed, or not present");
143+
// don't do anything more:
144+
while(1);
145+
}
146+
Serial.println("card initialized.");
147+
148+
file = SD.open("DATA.CSV", FILE_WRITE);
149+
if(!file) {
150+
Serial.println("error opening DATA.CSV");
151+
while(1);
152+
}
153+
// initialize fifoData semaphore to no data available
154+
fifoData = xSemaphoreCreateCounting(FIFO_SIZE, 0);
155+
156+
// initialize fifoSpace semaphore to FIFO_SIZE free records
157+
fifoSpace = xSemaphoreCreateCounting(FIFO_SIZE, FIFO_SIZE);
158+
159+
// create sensor task at priority two
160+
s1 = xTaskCreate(Task1, NULL, configMINIMAL_STACK_SIZE, NULL, 2, &sens);
161+
162+
// create SD write task at priority one
163+
s2 = xTaskCreate(Task2, NULL, configMINIMAL_STACK_SIZE + 200, NULL, 1, NULL);
164+
165+
// check for creation errors
166+
if (fifoData == NULL || fifoSpace == NULL || s1 != pdPASS || s2 != pdPASS ) {
167+
Serial.println(F("Creation problem"));
168+
while(1);
169+
}
170+
// throw away serial input
171+
while (Serial.available()) Serial.read();
172+
Serial.println(F("Type any character to end"));
173+
174+
// start scheduler
175+
vTaskStartScheduler();
176+
Serial.println(F("Insufficient RAM"));
177+
while(1);
178+
}
179+
//------------------------------------------------------------------------------
180+
// WARNING idle loop has a very small stack (configMINIMAL_STACK_SIZE)
181+
// loop must never block
182+
void loop() {
183+
// not used
184+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.