first commit

This commit is contained in:
Alejandro Guerrero 2026-09-27 17:21:39 +02:00
commit e6a42e28e9
4355 changed files with 4626605 additions and 0 deletions

View file

@ -0,0 +1,121 @@
#include <Arduino_FreeRTOS.h>
#include <semphr.h> // add the FreeRTOS functions for Semaphores (or Flags).
// Declare a mutex Semaphore Handle which we will use to manage the Serial Port.
// It will be used to ensure only one Task is accessing this resource at any time.
SemaphoreHandle_t xSerialSemaphore;
// define two Tasks for DigitalRead & AnalogRead
void TaskDigitalRead( void *pvParameters );
void TaskAnalogRead( void *pvParameters );
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
}
// Semaphores are useful to stop a Task proceeding, where it should be paused to wait,
// because it is sharing a resource, such as the Serial port.
// Semaphores should only be used whilst the scheduler is running, but we can set it up here.
if ( xSerialSemaphore == NULL ) // Check to confirm that the Serial Semaphore has not already been created.
{
xSerialSemaphore = xSemaphoreCreateMutex(); // Create a mutex semaphore we will use to manage the Serial Port
if ( ( xSerialSemaphore ) != NULL )
xSemaphoreGive( ( xSerialSemaphore ) ); // Make the Serial Port available for use, by "Giving" the Semaphore.
}
// Now set up two Tasks to run independently.
xTaskCreate(
TaskDigitalRead
, "DigitalRead" // A name just for humans
, 128 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL //Parameters for the task
, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, NULL ); //Task Handle
xTaskCreate(
TaskAnalogRead
, "AnalogRead" // A name just for humans
, 128 // Stack size
, NULL //Parameters for the task
, 1 // Priority
, NULL ); //Task Handle
// Now the Task scheduler, which takes over control of scheduling individual Tasks, is automatically started.
}
void loop()
{
// Empty. Things are done in Tasks.
}
/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/
void TaskDigitalRead( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial monitor
This example code is in the public domain.
*/
// digital pin 2 has a pushbutton attached to it. Give it a name:
uint8_t pushButton = 2;
// make the pushbutton's pin an input:
pinMode(pushButton, INPUT);
for (;;) // A Task shall never return or exit.
{
// read the input pin:
int buttonState = digitalRead(pushButton);
// See if we can obtain or "Take" the Serial Semaphore.
// If the semaphore is not available, wait 5 ticks of the Scheduler to see if it becomes free.
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
// We were able to obtain or "Take" the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
// print out the state of the button:
Serial.println(buttonState);
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
}
vTaskDelay(1); // one tick delay (15ms) in between reads for stability
}
}
void TaskAnalogRead( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
for (;;)
{
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// See if we can obtain or "Take" the Serial Semaphore.
// If the semaphore is not available, wait 5 ticks of the Scheduler to see if it becomes free.
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
// We were able to obtain or "Take" the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
// print out the value you read:
Serial.println(sensorValue);
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
}
vTaskDelay(1); // one tick delay (15ms) in between reads for stability
}
}

View file

@ -0,0 +1,160 @@
/*
* Example of a basic FreeRTOS queue
* https://www.freertos.org/Embedded-RTOS-Queues.html
*/
// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>
// Include queue support
#include <queue.h>
// Define a Array
int pinReadArray[4]={0,0,0,0};
//Function Declaration
void TaskBlink(void *pvParameters);
void TaskAnalogReadPin0(void *pvParameters);
void TaskAnalogReadPin1(void *pvParameters);
void TaskSerial(void *pvParameters);
/*
* Declaring a global variable of type QueueHandle_t
*
*/
QueueHandle_t arrayQueue;
void setup() {
/**
* Create a queue.
* https://www.freertos.org/a00116.html
*/
arrayQueue=xQueueCreate(10, //Queue length
sizeof(int)); //Queue item size
if(arrayQueue!=NULL){
// Create task that consumes the queue if it was created.
xTaskCreate(TaskSerial,// Task function
"PrintSerial",// Task name
128,// Stack size
NULL,
2,// Priority
NULL);
// Create task that publish data in the queue if it was created.
xTaskCreate(TaskAnalogReadPin0, // Task function
"AnalogRead1",// Task name
128,// Stack size
NULL,
1,// Priority
NULL);
// Create other task that publish data in the queue if it was created.
xTaskCreate(TaskAnalogReadPin1,// Task function
"AnalogRead2",// Task name
128,// Stack size
NULL,
1,// Priority
NULL);
xTaskCreate(TaskBlink,// Task function
"Blink", // Task name
128,// Stack size
NULL,
0,// Priority
NULL);
}
}
void loop() {}
/**
* Analog read task for Pin A0
* Reads an analog input on pin 0 and send the readed value through the queue.
* See Blink_AnalogRead example.
*/
void TaskAnalogReadPin0(void *pvParameters){
(void) pvParameters;
for (;;){
pinReadArray[0]=0;
pinReadArray[1]=analogRead(A0);
/**
* Post an item on a queue.
* https://www.freertos.org/a00117.html
*/
xQueueSend(arrayQueue,&pinReadArray,portMAX_DELAY);
// One tick delay (15ms) in between reads for stability
vTaskDelay(1);
}
}
/**
* Analog read task for Pin A1
* Reads an analog input on pin 1 and send the readed value through the queue.
* See Blink_AnalogRead example.
*/
void TaskAnalogReadPin1(void *pvParameters){
(void) pvParameters;
for (;;){
pinReadArray[2]=1;
pinReadArray[3]=analogRead(A1);
/**
* Post an item on a queue.
* https://www.freertos.org/a00117.html
*/
xQueueSend(arrayQueue,&pinReadArray,portMAX_DELAY);
// One tick delay (15ms) in between reads for stability
vTaskDelay(1);
}
}
/**
* Serial task.
* Prints the received items from the queue to the serial monitor.
*/
void TaskSerial(void *pvParameters){
(void) pvParameters;
// Init Arduino serial
Serial.begin(9600);
// Wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
while (!Serial) {
vTaskDelay(1);
}
for (;;){
if(xQueueReceive(arrayQueue,&pinReadArray,portMAX_DELAY) == pdPASS ){
Serial.print("PIN:");
Serial.println(pinReadArray[0]);
Serial.print("value:");
Serial.println(pinReadArray[1]);
Serial.print("PIN:");
Serial.println(pinReadArray[2]);
Serial.print("value:");
Serial.println(pinReadArray[3]);
vTaskDelay(500/portTICK_PERIOD_MS);
}
}
}
/*
* Blink task.
* See Blink_AnalogRead example.
*/
void TaskBlink(void *pvParameters){
(void) pvParameters;
pinMode(LED_BUILTIN,OUTPUT);
digitalWrite(LED_BUILTIN,LOW);
for (;;){
digitalWrite(LED_BUILTIN,HIGH);
vTaskDelay(250/portTICK_PERIOD_MS);
digitalWrite(LED_BUILTIN,LOW);
vTaskDelay(250/portTICK_PERIOD_MS);
}
}

View file

@ -0,0 +1,24 @@
/*
* Example of FreeRTOS configASSERT macro
* https://www.freertos.org/a00110.html#configASSERT
*/
#include <Arduino_FreeRTOS.h>
const boolean valueToAssert = true;
// The setup function runs once when you press reset or power the board
void setup() {
// Assert value is true, execution doesn't stop.
configASSERT(valueToAssert == true);
// Assert value is false, FreeRTOS execution stops and start to blink main led two times with 4 second cycle.
configASSERT(valueToAssert == false);
}
void loop()
{
// Empty. Things are done in Tasks.
}

View file

@ -0,0 +1,107 @@
#include <Arduino_FreeRTOS.h>
// define two tasks for Blink & AnalogRead
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
}
// Now set up two tasks to run independently.
xTaskCreate(
TaskBlink
, "Blink" // A name just for humans
, 128 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, NULL );
xTaskCreate(
TaskAnalogRead
, "AnalogRead"
, 128 // Stack size
, NULL
, 1 // Priority
, NULL );
// Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}
void loop()
{
// Empty. Things are done in Tasks.
}
/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/
void TaskBlink(void *pvParameters) // This is a task.
{
(void) pvParameters;
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
Most Arduinos have an on-board LED you can control. On the UNO, LEONARDO, MEGA, and ZERO
it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN takes care
of use the correct LED pin whatever is the board used.
The MICRO does not have a LED_BUILTIN available. For the MICRO board please substitute
the LED_BUILTIN definition with either LED_BUILTIN_RX or LED_BUILTIN_TX.
e.g. pinMode(LED_BUILTIN_RX, OUTPUT); etc.
If you want to know what pin the on-board LED is connected to on your Arduino model, check
the Technical Specs of your board at https://www.arduino.cc/en/Main/Products
This example code is in the public domain.
modified 8 May 2014
by Scott Fitzgerald
modified 2 Sep 2016
by Arturo Guadalupi
*/
// initialize digital LED_BUILTIN on pin 13 as an output.
pinMode(LED_BUILTIN, OUTPUT);
for (;;) // A Task shall never return or exit.
{
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
}
}
void TaskAnalogRead(void *pvParameters) // This is a task.
{
(void) pvParameters;
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
Graphical representation is available using serial plotter (Tools > Serial Plotter menu)
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
for (;;)
{
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(sensorValue);
vTaskDelay(1); // one tick delay (15ms) in between reads for stability
}
}

View file

@ -0,0 +1,156 @@
#ifndef GA_HEADER_h // include guard
#define GA_HEADER_h
#ifdef __cplusplus
extern "C" {
#endif
#include <avr/io.h>
/*--------------------------------------------------*/
/*------------Often Configured Parameters-----------*/
/*--------------------------------------------------*/
#define SAMPLE_RATE 16000 // samples per second
#define DELAY 128000 // bytes of delay
/* Working buffer */
#define CMD_BUFFER_SIZE 8192 // size of working buffer (on heap)
/*--------------------------------------------------*/
/*---------------Public Functions-------------------*/
/*--------------------------------------------------*/
void AudioCodec_ADC_init(void) __attribute__((flatten));
void AudioCodec_ADC(uint16_t* _modvalue) __attribute__((hot, flatten));
void alaw_compress1(int16_t* linval, uint8_t* logval) __attribute__ ((hot, flatten));
void alaw_expand1(uint8_t* logval, int16_t* linval) __attribute__ ((hot, flatten));
void audioCodec_dsp( uint16_t* ch_A, uint16_t* ch_B) __attribute__ ((hot, flatten));
// prototype for the DSP function to be implemented.
// needs to at least provide *ch_A and *ch_B
// within Timer1 interrupt routine - time critical I/O. Keep it short and punchy!
/*--------------------------------------------------*/
void AudioCodec_ADC_init(void)
{
// setup ADCs
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(ADLAR) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0); // 2.56V reference with external capacitor at AREF pin - left justify - start sampling MIC input ADC7
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // ADC enable, auto trigger, ck/128 = 192kHz
ADCSRB = 0x00; // free running mode
DIDR0 = _BV(ADC7D) | _BV(ADC6D) | _BV(ADC2D) | _BV(ADC1D) | _BV(ADC0D); // turn off digital input for pin ADC6 Line and ADC7 Mic input (and ADC2, ADC1, & ADC0)
// Analogue Comparator Disable
// When the ACD bit is written logic one, the power to the Analogue Comparator is switched off.
// This bit can be set at any time to turn off the Analogue Comparator.
// This will reduce power consumption in Active and Idle mode.
// When changing the ACD bit, the Analogue Comparator Interrupt must be disabled by clearing the ACIE bit in ACSR.
// Otherwise an interrupt can occur when the ACD bit is changed.
ACSR &= ~_BV(ACIE);
ACSR |= _BV(ACD);
}
// adc sampling routine
void AudioCodec_ADC(uint16_t* _modvalue)
{
if (ADCSRA & _BV(ADIF)) // check if sample ready
{
*_modvalue = ADCW; // fetch ADCL first to freeze sample, then ADCH. It is done by the compiler.
ADCSRA |= _BV(ADIF); // reset the interrupt flag
}
}
/*
==========================================================================
FUNCTION NAME: alaw_compress11
DESCRIPTION: ALaw encoding rule according ITU-T Rec. G.711.
PROTOTYPE: int8_t alaw_compress1( int16_t linval )
PARAMETERS:
linval: (In) linear samples (only 12 MSBits are taken into account)
logval: (Out) compressed sample (8 bit right justified without sign extension)
RETURN VALUE: none.
==========================================================================
*/
void alaw_compress1 (int16_t* linval, uint8_t* logval)
{
uint16_t ix, iexp;
ix = *linval < 0 /* 0 <= ix < 2048 */
? ~*linval >> 4 /* 1's complement for negative values */
: *linval >> 4;
/* Do more, if exponent > 0 */
if (ix > 15) /* exponent=0 for ix <= 15 */
{
iexp = 1; /* first step: */
while (ix > 16 + 15) /* find mantissa and exponent */
{
ix >>= 1;
iexp++;
}
ix -= 16; /* second step: remove leading '1' */
ix += iexp << 4; /* now compute encoded value */
}
if (*linval >= 0) ix |= (0x0080); /* add sign bit */
*logval = (uint8_t)(ix ^ (0x0055)); /* toggle even bits */
}
/* ................... End of alaw_compress1() ..................... */
/*
==========================================================================
FUNCTION NAME: alaw_expand1
DESCRIPTION: ALaw decoding rule according ITU-T Rec. G.711.
PROTOTYPE: int16_t alaw_expand1( uint8_t logval )
PARAMETERS:
logval: (In) buffer with compressed samples (8 bit right justified,
without sign extension)
linval: (Out) buffer with linear samples (13 bits left justified)
RETURN VALUE: none.
============================================================================
*/
void alaw_expand1(uint8_t* logval, int16_t* linval)
{
uint8_t ix, iexp;
int16_t mant;
ix = (*logval ^ (0x55)); /* re-toggle toggled even bits */
ix &= 0x7F; /* remove sign bit */
iexp = ix >> 4; /* extract exponent */
mant = ix & 0x0f; /* now get mantissa */
if (iexp > 0)
mant = mant + 16; /* add leading '1', if exponent > 0 */
mant = (mant << 4) + (0x0008); /* now mantissa left justified and */
/* 1/2 quantization step added */
if (iexp > 1) /* now left shift according exponent */
mant = mant << (iexp - 1);
*linval = *logval > 127 /* invert, if negative sample */
? mant
: -mant;
}
/* ................... End of alaw_expand1() ..................... */
#ifdef __cplusplus
}
#endif
#endif // GA_HEADER_h end include guard

View file

@ -0,0 +1,436 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <util/atomic.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <SPI.h>
#include <SD.h>
// This example only works with Goldilocks Analogue, as DAC and SPI SRAM is required.
// INSTALLATION OF THE 4 FOLLOWING LIBRARIES REQUIRED!
// From Library: FreeRTOS
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
// From Library: AVR Real Time Clock Library
#include <AVR_RTC.h>
// From Library: Goldilocks Analogue DAC Library
#include <DAC.h>
// From Library: Goldilocks Analogue SPI RAM Library
#include <SPIRAM.h>
#include <SPIRAM_ringBuffer.h>
#include "GA_Header.h"
/*--------------------------------------------------*/
/*------------------- Globals ----------------------*/
/*--------------------------------------------------*/
DAC_value_t mod7_value; // location to store the ADC value before it is processed.
uint16_t ch_A_out; // storage for the values to be written to MCP4822
uint16_t ch_B_out;
SPIRAM_ringBuffer_t SRAM_delayBuffer; // structure to hold the SRAM ringbuffer info.
filter_t tx_filter; // instantiate a filter, which can be initialised to be a LPF (or BPF or HPF) later.
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;
static uint8_t * Buff = NULL; /* Put a working buffer on heap later (with pvPortMalloc). */
// change this to match your SD shield or module;
// GoldilocksAnalogue SD shield: pin 14
uint8_t const chipSelect = 14;
// Create a Semaphore binary flag for the Serial Port. To ensure only single access.
SemaphoreHandle_t xSerialSemaphore;
// define two tasks to operate this test suite.
static void TaskReport( void *pvParameters ); // Report on the status reguarly using USART.
static void TaskAnalogue( void *pvParameters ); // Manage Analogue set-up, then sleep.
// Test the SPI EEPROM device, prior to building the SPI SRAM Delay loop.
static int8_t testSPIEEPROM( uint_farptr_t p1, uint16_t p2 );
// p1 = address of the SPI memory to be tested
// p2 = number of bytes to be tested (allocates a RAM buffer of this size too)
/*--------------------------------------------------*/
/*-------------------- Set Up ----------------------*/
/*--------------------------------------------------*/
void setup() {
// put your setup code here, to run once:
// Open serial communications and wait for port to open:
Serial.begin(38400);
Serial.println(F("Hello World!\n"));
setup_RTC_interrupt();
{
tm CurrTimeDate; // set up an array for the RTC info.
// <year yyyy> <month mm Jan=0> <date dd> <day d Sun=0> <hour hh> <minute mm> <second ss>
CurrTimeDate.tm_year = (uint8_t) ( 2016 - 1900 );
CurrTimeDate.tm_mon = (uint8_t) 1; // January is month 0, February is month 1, etc
CurrTimeDate.tm_mday = (uint8_t) 18;
CurrTimeDate.tm_hour = (uint8_t) 17;
CurrTimeDate.tm_min = (uint8_t) 16;
CurrTimeDate.tm_sec = (uint8_t) 0;
set_system_time( mktime( (tm*)&CurrTimeDate ) );
}
// Semaphores are useful to stop a task proceeding, where it should be stopped because it is using a resource, such as the Serial port.
// But they should only be used whilst the scheduler is running.
if ( xSerialSemaphore == NULL ) // Check to see if the Serial Semaphore has not been created.
{
xSerialSemaphore = xSemaphoreCreateMutex(); // mutex semaphore for Serial Port
if ( ( xSerialSemaphore ) != NULL )
xSemaphoreGive( ( xSerialSemaphore ) ); // make the Serial Port available
}
SPI.begin(); // warm up the SPI interface, so it can be used for the SPI RAM testing.
Serial.print(F("SPI SRAM Memory Testing: "));
if (testSPIEEPROM(RAM0_ADDR + 17, CMD_BUFFER_SIZE))
Serial.println(F("*** FAILED ***"));
else
Serial.println(F("PASSED"));
Serial.print(F("SPI EEPROM Memory Testing: "));
if (testSPIEEPROM(RAM1_ADDR + 17, CMD_BUFFER_SIZE))
Serial.println(F("*** FAILED ***\n"));
else
Serial.println(F("PASSED\n"));
// we'll use the SD Card initialization code from the utility libraries
// since we're just testing if the card is working!
Serial.print(F("\nInitializing SD card... "));
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println(F("initialization failed."));
Serial.println(F("Is a card inserted? You must insert a formatted SD Card to proceed."));
} else {
Serial.println(F("wiring is correct and a SD card is present."));
}
// print the type of card
Serial.print(F("\nCard type: "));
switch (card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println(F("SD1"));
break;
case SD_CARD_TYPE_SD2:
Serial.println(F("SD2"));
break;
case SD_CARD_TYPE_SDHC:
Serial.println(F("SDHC"));
break;
default:
Serial.println(F("Unknown SD Card Type"));
break;
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println(F("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card"));
} else {
// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print(F("\nVolume type is FAT"));
Serial.println(volume.fatType(), DEC);
Serial.println();
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
volumesize *= 512; // SD card blocks are always 512 bytes
Serial.print(F("Volume size (bytes): "));
Serial.println(volumesize);
Serial.print(F("Volume size (Kbytes): "));
volumesize /= 1024;
Serial.println(volumesize);
Serial.print(F("Volume size (Mbytes): "));
volumesize /= 1024;
Serial.println(volumesize);
Serial.println(F("\nFiles found on the card (name, date and size in bytes): "));
root.openRoot(volume);
// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}
// Now set up two tasks to help us with testing.
xTaskCreate(
TaskReport
, "RedLED" // report reguarly on the status of its stack and the tick values.
, 256 // Stack size
, NULL
, 2 // priority
, NULL ); // */
xTaskCreate(
TaskAnalogue
, "Analogue"
, 256 // This stack size can be checked & adjusted by reading Highwater
, NULL
, 1 // priority
, NULL ); // */
// Start the task scheduler, which takes over control of scheduling individual tasks.
// The scheduler is started in initVariant() found in variantHooks.c
}
/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/
static void TaskAnalogue(void *pvParameters) // Prepare the DAC
{
(void) pvParameters;
TickType_t xLastWakeTime;
/* The xLastWakeTime variable needs to be initialised with the current tick
count. Note that this is the only time we access this variable. From this
point on xLastWakeTime is managed automatically by the xTaskDelayUntil()
API function. */
xLastWakeTime = xTaskGetTickCount();
// Create the SPI SRAM ring-buffer used by audio delay loop.
SPIRAM_ringBuffer_InitBuffer( &SRAM_delayBuffer, (uint_farptr_t)(RAM0_ADDR), sizeof(uint8_t) * DELAY);
// See if we can obtain the Serial Semaphore.
// If the semaphore is not available, wait 5 ticks to see if it becomes free.
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
// We were able to obtain the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
Serial.print(F("DAC_Codec_init "));
// initialise the USART 1 MSPIM bus specifically for DAC use, with the post-latch configuration.
// pre-latch for audio or AC signals (FALSE), or post-latch for single value setting or DC values (TRUE).
DAC_init(FALSE);
Serial.print(F("will "));
// Initialise the sample interrupt timer.
// set up the sampling Timer3 to 48000Hz (or lower), runs at audio sampling rate in Hz.
DAC_Timer3_init(SAMPLE_RATE);
Serial.print(F("very "));
// Initialise the filter to be a Low Pass Filter.
tx_filter.cutoff = 0xc000; // set filter to 3/8 of sample frequency.
setIIRFilterLPF( &tx_filter ); // initialise transmit sample filter
Serial.print(F("soon "));
// set up ADC sampling on the ADC7 (Microphone).
AudioCodec_ADC_init();
Serial.print (F("be "));
// Set the call back function to do the audio processing.
// Done this way so that we can change the audio handling depending on what we want to achieve.
DAC_setHandler(audioCodec_dsp, &ch_A_out, &ch_B_out);
Serial.println(F("done."));
xSemaphoreGive( xSerialSemaphore ); // Now free the Serial Port for others.
}
// vTaskSuspend(NULL); // Well, we're pretty much done here. Let's suspend the Task.
// vTaskEndScheduler(); // Or just kill the FreeRTOS scheduler. Rely on Timer3 Interrupt for regular output.
for (;;)
{
// See if we can obtain the Serial Semaphore.
// If the semaphore is not available, wait 5 ticks to see if it becomes free.
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
// We were able to obtain the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
Serial.print(F("Audio Stack HighWater @ "));
Serial.println(uxTaskGetStackHighWaterMark(NULL));
xSemaphoreGive( xSerialSemaphore ); // Now free the Serial Port for others.
}
xTaskDelayUntil( &xLastWakeTime, ( 8192 / portTICK_PERIOD_MS ) );
}
}
static void TaskReport(void *pvParameters) // report on the status of the device
{
(void) pvParameters;;
TickType_t xLastWakeTime;
/* The xLastWakeTime variable needs to be initialised with the current tick
count. Note that this is the only time we access this variable. From this
point on xLastWakeTime is managed automatically by the xTaskDelayUntil()
API function. */
xLastWakeTime = xTaskGetTickCount();
time_t currentTick; // set up a location for the current time stamp
for (;;)
{
// See if we can obtain the Serial Semaphore.
// If the semaphore is not available, wait 5 ticks to see if it becomes free.
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
// We were able to obtain the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
Serial.print(F("Report Stack HighWater @ "));
Serial.print(uxTaskGetStackHighWaterMark(NULL));
Serial.print(F(" Current Time: "));
time((time_t *)&currentTick);
Serial.println(ctime( (time_t *)&currentTick));
xSemaphoreGive( xSerialSemaphore ); // Now free the Serial Port for others.
}
xTaskDelayUntil( &xLastWakeTime, ( 2048 / portTICK_PERIOD_MS ) );
}
}
/*--------------------------------------------------*/
/*-------------------- Functions -------------------*/
/*--------------------------------------------------*/
static int8_t testSPIEEPROM( uint_farptr_t p1, uint16_t p2 )
{
int8_t ReturnCode;
if (Buff == NULL) // if there is no Buff buffer allocated (pointer is NULL), then allocate buffer.
if ( !(Buff = (uint8_t *) pvPortMalloc( sizeof(uint8_t) * CMD_BUFFER_SIZE )))
{
Serial.println(F("pvPortMalloc for *Buff fail..!"));
return SPIRAM_ERROR;
}
if (p2 >= CMD_BUFFER_SIZE) p2 = CMD_BUFFER_SIZE;
srand( p1 % 42 ); // create a random seed, based on 42.
for ( uint16_t i = 0; i < p2; ++i)
{
Buff[i] = (uint8_t) rand(); // fill the Buff with some pseudo random numbers.
}
Serial.print(F("Testing at 0x"));
Serial.print( (uint32_t)p1, HEX);
Serial.print(F(" for "));
Serial.print( p2, DEC);
Serial.println(F(" bytes."));
ReturnCode = SPIRAM_begin();
if (ReturnCode) return ReturnCode; // problem with opening the EEPROM / SRAM
uint_farptr_t FarAddress = p1;
ReturnCode = SPIRAM_write( FarAddress, Buff, (size_t)p2);
if (ReturnCode) return ReturnCode; /* error or disk full */
for (uint16_t i = 0; i < p2; ++i)
{
uint8_t read_result;
ReturnCode = SPIRAM_read( &read_result, (uint_farptr_t)(FarAddress + i), (size_t)1);
if (ReturnCode) return ReturnCode; /* error or disk full */
// Serial.print(F("Written 0x"));
// Serial.print( Buff[i], HEX);
// Serial.print(F(" Read 0x"));
// Serial.println( read_result, HEX);
if ( Buff[i] != read_result)
{
Serial.print(F("Error at Address 0x"));
Serial.print( (uint_farptr_t)(FarAddress + i), HEX);
Serial.print(F(" with 0x"));
Serial.println( read_result, HEX);
return SPIRAM_ERROR;
}
}
return SPIRAM_SUCCESS;
}
void audioCodec_dsp( uint16_t * ch_A, uint16_t * ch_B)
{
int16_t xn;
uint8_t cn;
if ( SPIRAM_ringBuffer_GetCount(&SRAM_delayBuffer) >= DELAY )
{
cn = SPIRAM_ringBuffer_Pop(&SRAM_delayBuffer);
}
else
{
cn = 0x80 ^ 0x55; // put A-Law nulled signal on the output.
}
alaw_expand1(&cn, &xn); // expand the A-Law compression
*ch_A = *ch_B = (uint16_t)(xn + 0x7fff); // put signal out on A & B channel.
AudioCodec_ADC(&mod7_value.u16);
xn = mod7_value.u16 - 0x7fe0; // centre the sample to 0 by subtracting 1/2 10bit range.
IIRFilter( &tx_filter, &xn); // filter sample train
alaw_compress1(&xn, &cn); // compress using A-Law
if ( SPIRAM_ringBuffer_GetCount(&SRAM_delayBuffer) <= DELAY )
{
SPIRAM_ringBuffer_Poke(&SRAM_delayBuffer, cn);
}
}
/*--------------------------------------------------*/
/*---------------------- Loop ----------------------*/
/*--------------------------------------------------*/
void loop() {
// Remember that loop() is simply the freeRTOS idle task.
// It is only something to do, when there's nothing else to do.
// There are several macros provided in the header file to put
// the device into sleep mode.
// SLEEP_MODE_IDLE (0)
// SLEEP_MODE_ADC _BV(SM0)
// SLEEP_MODE_PWR_DOWN _BV(SM1)
// SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
// SLEEP_MODE_STANDBY (_BV(SM1) | _BV(SM2))
// SLEEP_MODE_EXT_STANDBY (_BV(SM0) | _BV(SM1) | _BV(SM2))
set_sleep_mode( SLEEP_MODE_IDLE );
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
sleep_enable();
#if defined(BODS) && defined(BODSE) // Only if there is support to disable the brown-out detection.
sleep_bod_disable();
#endif
}
sleep_cpu(); // good night.
// Ugh. I've been woken up. Better disable sleep mode.
sleep_disable();
}

View file

@ -0,0 +1,134 @@
/*
* Example of a basic FreeRTOS queue
* https://www.freertos.org/Embedded-RTOS-Queues.html
*/
// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>
// Include queue support
#include <queue.h>
/*
* Declaring a global variable of type QueueHandle_t
*
*/
QueueHandle_t integerQueue;
void setup() {
/**
* Create a queue.
* https://www.freertos.org/a00116.html
*/
integerQueue = xQueueCreate(10, // Queue length
sizeof(int) // Queue item size
);
if (integerQueue != NULL) {
// Create task that consumes the queue if it was created.
xTaskCreate(TaskSerial, // Task function
"Serial", // A name just for humans
128, // This stack size can be checked & adjusted by reading the Stack Highwater
NULL,
2, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
NULL);
// Create task that publish data in the queue if it was created.
xTaskCreate(TaskAnalogRead, // Task function
"AnalogRead", // Task name
128, // Stack size
NULL,
1, // Priority
NULL);
}
xTaskCreate(TaskBlink, // Task function
"Blink", // Task name
128, // Stack size
NULL,
0, // Priority
NULL );
}
void loop() {}
/**
* Analog read task
* Reads an analog input on pin 0 and send the readed value through the queue.
* See Blink_AnalogRead example.
*/
void TaskAnalogRead(void *pvParameters)
{
(void) pvParameters;
for (;;)
{
// Read the input on analog pin 0:
int sensorValue = analogRead(A0);
/**
* Post an item on a queue.
* https://www.freertos.org/a00117.html
*/
xQueueSend(integerQueue, &sensorValue, portMAX_DELAY);
// One tick delay (15ms) in between reads for stability
vTaskDelay(1);
}
}
/**
* Serial task.
* Prints the received items from the queue to the serial monitor.
*/
void TaskSerial(void * pvParameters) {
(void) pvParameters;
// Init Arduino serial
Serial.begin(9600);
// Wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
while (!Serial) {
vTaskDelay(1);
}
int valueFromQueue = 0;
for (;;)
{
/**
* Read an item from a queue.
* https://www.freertos.org/a00118.html
*/
if (xQueueReceive(integerQueue, &valueFromQueue, portMAX_DELAY) == pdPASS) {
Serial.println(valueFromQueue);
}
}
}
/*
* Blink task.
* See Blink_AnalogRead example.
*/
void TaskBlink(void *pvParameters)
{
(void) pvParameters;
pinMode(LED_BUILTIN, OUTPUT);
for (;;)
{
digitalWrite(LED_BUILTIN, HIGH);
vTaskDelay( 250 / portTICK_PERIOD_MS );
digitalWrite(LED_BUILTIN, LOW);
vTaskDelay( 250 / portTICK_PERIOD_MS );
}
}

View file

@ -0,0 +1,78 @@
/*
* Example of a Arduino interruption and RTOS Binary Semaphore
* https://www.freertos.org/Embedded-RTOS-Binary-Semaphores.html
*/
// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>
// Include semaphore supoport
#include <semphr.h>
/*
* Declaring a global variable of type SemaphoreHandle_t
*
*/
SemaphoreHandle_t interruptSemaphore;
void setup() {
// Configure pin 2 as an input and enable the internal pull-up resistor
pinMode(2, INPUT_PULLUP);
// Create task for Arduino led
xTaskCreate(TaskLed, // Task function
"Led", // Task name
128, // Stack size
NULL,
0, // Priority
NULL );
/**
* Create a binary semaphore.
* https://www.freertos.org/xSemaphoreCreateBinary.html
*/
interruptSemaphore = xSemaphoreCreateBinary();
if (interruptSemaphore != NULL) {
// Attach interrupt for Arduino digital pin
attachInterrupt(digitalPinToInterrupt(2), interruptHandler, LOW);
}
}
void loop() {}
void interruptHandler() {
/**
* Give semaphore in the interrupt handler
* https://www.freertos.org/a00124.html
*/
xSemaphoreGiveFromISR(interruptSemaphore, NULL);
}
/*
* Led task.
*/
void TaskLed(void *pvParameters)
{
(void) pvParameters;
pinMode(LED_BUILTIN, OUTPUT);
for (;;) {
/**
* Take the semaphore.
* https://www.freertos.org/a00122.html
*/
if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdPASS) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
vTaskDelay(10);
}
}

View file

@ -0,0 +1,81 @@
/*
Example of a FreeRTOS mutex
https://www.freertos.org/Real-time-embedded-RTOS-mutexes.html
*/
// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>
// Include mutex support
#include <semphr.h>
/*
Declaring a global variable of type SemaphoreHandle_t
*/
SemaphoreHandle_t mutex;
int globalCount = 0;
void setup() {
Serial.begin(9600);
/**
Create a mutex.
https://www.freertos.org/CreateMutex.html
*/
mutex = xSemaphoreCreateMutex();
if (mutex != NULL) {
Serial.println("Mutex created");
}
/**
Create tasks
*/
xTaskCreate(TaskMutex, // Task function
"Task1", // Task name for humans
128,
1000, // Task parameter
1, // Task priority
NULL);
xTaskCreate(TaskMutex, "Task2", 128, 1000, 1, NULL);
}
void loop() {}
void TaskMutex(void *pvParameters)
{
TickType_t delayTime = *((TickType_t*)pvParameters); // Use task parameters to define delay
for (;;)
{
/**
Take mutex
https://www.freertos.org/a00122.html
*/
if (xSemaphoreTake(mutex, 10) == pdTRUE)
{
Serial.print(pcTaskGetName(NULL)); // Get task name
Serial.print(", Count read value: ");
Serial.print(globalCount);
globalCount++;
Serial.print(", Updated value: ");
Serial.print(globalCount);
Serial.println();
/**
Give mutex
https://www.freertos.org/a00123.html
*/
xSemaphoreGive(mutex);
}
vTaskDelay(delayTime / portTICK_PERIOD_MS);
}
}

View file

@ -0,0 +1,61 @@
/**
Example of a Arduino interruption and RTOS Task Notification.
https://www.freertos.org/RTOS_Task_Notification_As_Binary_Semaphore.html
*/
// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>
/**
Declaring a global TaskHandle for the led task.
*/
TaskHandle_t taskNotificationHandler;
void setup() {
// Configure pin 2 as an input and enable the internal pull-up resistor.
pinMode(2, INPUT_PULLUP);
// Create task for FreeRTOS notification
xTaskCreate(TaskNotification, // Task function
"Notification", // Task name
128, // Stack size
NULL,
3, // Priority
&taskNotificationHandler ); // TaskHandle
}
void loop() {
}
/*
Notification task.
*/
void TaskNotification(void *pvParameters)
{
(void) pvParameters;
int digitalPin = 2;
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(digitalPin), digitalPinInterruptHandler, LOW);
for (;;) {
if (ulTaskNotifyTake(pdTRUE, portMAX_DELAY)) {
Serial.println("Notification received");
}
}
}
void digitalPinInterruptHandler() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(taskNotificationHandler, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken) {
taskYIELD();
}
}

View file

@ -0,0 +1,150 @@
/*
* Example of a basic FreeRTOS queue
* https://www.freertos.org/Embedded-RTOS-Queues.html
*/
// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>
// Include queue support
#include <queue.h>
// Define a Structure Array
struct Arduino{
int pin[2];
int ReadValue[2];
};
//Function Declaration
void Blink(void *pvParameters);
void POT(void *pvParameters);
void TaskSerial(void *pvParameters);
/*
* Declaring a global variable of type QueueHandle_t
*
*/
QueueHandle_t structArrayQueue;
void setup() {
/**
* Create a queue.
* https://www.freertos.org/a00116.html
*/
structArrayQueue=xQueueCreate(10, //Queue length
sizeof(struct Arduino)); //Queue item size
if(structArrayQueue!=NULL){
xTaskCreate(TaskBlink, // Task function
"Blink",// Task name
128,// Stack size
NULL,
0,// Priority
NULL);
// Create other task that publish data in the queue if it was created.
xTaskCreate(POT,// Task function
"AnalogRead",// Task name
128, // Stack size
NULL,
2,// Priority
NULL);
// Create task that consumes the queue if it was created.
xTaskCreate(TaskSerial,// Task function
"PrintSerial",// A name just for humans
128,// This stack size can be checked & adjusted by reading the Stack Highwater
NULL,
1, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
NULL);
}
}
void loop() {}
/*
* Blink task.
* See Blink_AnalogRead example.
*/
void TaskBlink(void *pvParameters){
(void) pvParameters;
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
for(;;)
{
digitalWrite(13,HIGH);
vTaskDelay(250/portTICK_PERIOD_MS);
digitalWrite(13,LOW);
vTaskDelay(250/portTICK_PERIOD_MS);
}
}
/**
* Analog read task for Pin A0 and A1
* Reads an analog input on pin 0 and pin 1
* Send the readed value through the queue.
* See Blink_AnalogRead example.
*/
void POT(void *pvParameters){
(void) pvParameters;
pinMode(A0,INPUT);
pinMode(A1,INPUT);
for (;;){
// Read the input on analog pin 0:
struct Arduino currentVariable;
currentVariable.pin[0]=0;
currentVariable.pin[1]=1;
currentVariable.ReadValue[0]=analogRead(A0);
currentVariable.ReadValue[1]=analogRead(A1);
/**
* Post an item on a queue.
* https://www.freertos.org/a00117.html
*/
xQueueSend(structArrayQueue,&currentVariable,portMAX_DELAY);
// One tick delay (15ms) in between reads for stability
vTaskDelay(1);
}
}
/**
* Serial task.
* Prints the received items from the queue to the serial monitor.
*/
void TaskSerial(void *pvParameters){
(void) pvParameters;
// Init Arduino serial
Serial.begin(9600);
// Wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
while (!Serial) {
vTaskDelay(1);
}
for (;;){
struct Arduino currentVariable;
/**
* Read an item from a queue.
* https://www.freertos.org/a00118.html
*/
if(xQueueReceive(structArrayQueue,&currentVariable,portMAX_DELAY) == pdPASS ){
for(int i=0;i<2;i++){
Serial.print("PIN:");
Serial.println(currentVariable.pin[i]);
Serial.print("value:");
Serial.println(currentVariable.ReadValue[i]);
}
}
vTaskDelay(500/portTICK_PERIOD_MS);
}
}

View file

@ -0,0 +1,181 @@
/*
* Example of a basic FreeRTOS queue
* https://www.freertos.org/Embedded-RTOS-Queues.html
*/
// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>
// Include queue support
#include <queue.h>
// Define a struct
struct pinRead {
int pin;
int value;
};
/*
* Declaring a global variable of type QueueHandle_t
*
*/
QueueHandle_t structQueue;
void setup() {
/**
* Create a queue.
* https://www.freertos.org/a00116.html
*/
structQueue = xQueueCreate(10, // Queue length
sizeof(struct pinRead) // Queue item size
);
if (structQueue != NULL) {
// Create task that consumes the queue if it was created.
xTaskCreate(TaskSerial, // Task function
"Serial", // A name just for humans
128, // This stack size can be checked & adjusted by reading the Stack Highwater
NULL,
2, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
NULL);
// Create task that publish data in the queue if it was created.
xTaskCreate(TaskAnalogReadPin0, // Task function
"AnalogReadPin0", // Task name
128, // Stack size
NULL,
1, // Priority
NULL);
// Create other task that publish data in the queue if it was created.
xTaskCreate(TaskAnalogReadPin1, // Task function
"AnalogReadPin1", // Task name
128, // Stack size
NULL,
1, // Priority
NULL);
}
xTaskCreate(TaskBlink, // Task function
"Blink", // Task name
128, // Stack size
NULL,
0, // Priority
NULL );
}
void loop() {}
/**
* Analog read task for Pin A0
* Reads an analog input on pin 0 and send the readed value through the queue.
* See Blink_AnalogRead example.
*/
void TaskAnalogReadPin0(void *pvParameters)
{
(void) pvParameters;
for (;;)
{
// Read the input on analog pin 0:
struct pinRead currentPinRead;
currentPinRead.pin = 0;
currentPinRead.value = analogRead(A0);
/**
* Post an item on a queue.
* https://www.freertos.org/a00117.html
*/
xQueueSend(structQueue, &currentPinRead, portMAX_DELAY);
// One tick delay (15ms) in between reads for stability
vTaskDelay(1);
}
}
/**
* Analog read task for Pin A1
* Reads an analog input on pin 1 and send the readed value through the queue.
* See Blink_AnalogRead example.
*/
void TaskAnalogReadPin1(void *pvParameters)
{
(void) pvParameters;
for (;;)
{
// Read the input on analog pin 1:
struct pinRead currentPinRead;
currentPinRead.pin = 1;
currentPinRead.value = analogRead(A1);
/**
* Post an item on a queue.
* https://www.freertos.org/a00117.html
*/
xQueueSend(structQueue, &currentPinRead, portMAX_DELAY);
// One tick delay (15ms) in between reads for stability
vTaskDelay(1);
}
}
/**
* Serial task.
* Prints the received items from the queue to the serial monitor.
*/
void TaskSerial(void * pvParameters) {
(void) pvParameters;
// Init Arduino serial
Serial.begin(9600);
// Wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
while (!Serial) {
vTaskDelay(1);
}
for (;;)
{
struct pinRead currentPinRead;
/**
* Read an item from a queue.
* https://www.freertos.org/a00118.html
*/
if (xQueueReceive(structQueue, &currentPinRead, portMAX_DELAY) == pdPASS) {
Serial.print("Pin: ");
Serial.print(currentPinRead.pin);
Serial.print(" Value: ");
Serial.println(currentPinRead.value);
}
}
}
/*
* Blink task.
* See Blink_AnalogRead example.
*/
void TaskBlink(void *pvParameters)
{
(void) pvParameters;
pinMode(LED_BUILTIN, OUTPUT);
for (;;)
{
digitalWrite(LED_BUILTIN, HIGH);
vTaskDelay( 250 / portTICK_PERIOD_MS );
digitalWrite(LED_BUILTIN, LOW);
vTaskDelay( 250 / portTICK_PERIOD_MS );
}
}

View file

@ -0,0 +1,85 @@
#include <Arduino_FreeRTOS.h>
//define task handles
TaskHandle_t TaskBlink_Handler;
TaskHandle_t TaskSerial_Handler;
// define two tasks for Blink & Serial
void TaskBlink( void *pvParameters );
void TaskSerial(void* pvParameters);
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
}
// Now set up two tasks to run independently.
xTaskCreate(
TaskBlink
, "Blink" // A name just for humans
, 128 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL //Parameters passed to the task function
, 2 // Priority, with 2 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, &TaskBlink_Handler );//Task handle
xTaskCreate(
TaskSerial
, "Serial"
, 128 // Stack size
, NULL //Parameters passed to the task function
, 1 // Priority
, &TaskSerial_Handler ); //Task handle
}
void loop()
{
// Empty. Things are done in Tasks.
}
/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/
void TaskSerial(void* pvParameters){
/*
Serial
Send "s" or "r" through the serial port to control the suspend and resume of the LED light task.
This example code is in the public domain.
*/
(void) pvParameters;
for (;;) // A Task shall never return or exit.
{
while(Serial.available()>0){
switch(Serial.read()){
case 's':
vTaskSuspend(TaskBlink_Handler);
Serial.println("Suspend!");
break;
case 'r':
vTaskResume(TaskBlink_Handler);
Serial.println("Resume!");
break;
}
vTaskDelay(1);
}
}
}
void TaskBlink(void *pvParameters) // This is a task.
{
(void) pvParameters;
pinMode(LED_BUILTIN, OUTPUT);
for (;;) // A Task shall never return or exit.
{
//Serial.println(11);
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
}
}

View file

@ -0,0 +1,148 @@
/*
* Example of FreeRTOS task utilities
* https://www.freertos.org/a00021.html
*/
// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>
/**
* Task handlers
* https://www.freertos.org/a00019.html#xTaskHandle
*/
TaskHandle_t taskBlinkHandle;
TaskHandle_t taskDeletedHandle;
TaskHandle_t taskBlockedHandle;
void setup() {
/**
* Task creation
*/
xTaskCreate(TaskBlink, // Task function
"Blink", // Task name
128, // Stack size
NULL,
0, // Priority
&taskBlinkHandle); // Task handler
xTaskCreate(TaskSerial,
"Serial",
128,
NULL,
2,
NULL);
xTaskCreate(TaskDeleted,
"Deleted",
64,
NULL,
1,
&taskDeletedHandle);
xTaskCreate(TaskBlocked,
"Blocked",
64,
NULL,
1,
&taskBlockedHandle);
}
void loop() {}
/**
* Example of utilities usage
*/
void TaskSerial(void *pvParameters)
{
(void) pvParameters;
Serial.begin(9600);
for (;;)
{
Serial.println("======== Tasks status ========");
Serial.print("Tick count: ");
Serial.print(xTaskGetTickCount());
Serial.print(", Task count: ");
Serial.print(uxTaskGetNumberOfTasks());
Serial.println();
Serial.println();
// Serial task status
Serial.print("- TASK ");
Serial.print(pcTaskGetName(NULL)); // Get task name without handler https://www.freertos.org/a00021.html#pcTaskGetName
Serial.print(", High Watermark: ");
Serial.print(uxTaskGetStackHighWaterMark(NULL)); // https://www.freertos.org/uxTaskGetStackHighWaterMark.html
TaskHandle_t taskSerialHandle = xTaskGetCurrentTaskHandle(); // Get current task handle. https://www.freertos.org/a00021.html#xTaskGetCurrentTaskHandle
Serial.println();
Serial.print("- TASK ");
Serial.print(pcTaskGetName(taskBlinkHandle)); // Get task name with handler
Serial.print(", High Watermark: ");
Serial.print(uxTaskGetStackHighWaterMark(taskBlinkHandle));
Serial.println();
Serial.print("- TASK ");
Serial.print(pcTaskGetName(taskDeletedHandle));
Serial.print(", High Watermark: ");
Serial.print(uxTaskGetStackHighWaterMark(taskDeletedHandle));
Serial.println();
Serial.print("- TASK ");
Serial.print(pcTaskGetName(taskBlockedHandle));
Serial.print(", High Watermark: ");
Serial.print(uxTaskGetStackHighWaterMark(taskBlockedHandle));
Serial.println();
Serial.println();
vTaskDelay( 5000 / portTICK_PERIOD_MS );
}
}
/**
* Blocked tasks when run
*/
void TaskBlocked(void *pvParameters) {
(void) pvParameters;
for (;;)
{
vTaskDelay( 900000 / portTICK_PERIOD_MS );
}
}
/**
* Deleted tasks when run
*/
void TaskDeleted(void *pvParameters) {
(void) pvParameters;
vTaskDelete(NULL);
}
/*
* Blink task.
* See Blink_AnalogRead example.
*/
void TaskBlink(void *pvParameters)
{
(void) pvParameters;
pinMode(LED_BUILTIN, OUTPUT);
for (;;)
{
digitalWrite(LED_BUILTIN, HIGH);
vTaskDelay( 250 / portTICK_PERIOD_MS );
digitalWrite(LED_BUILTIN, LOW);
vTaskDelay( 250 / portTICK_PERIOD_MS );
}
}