Example software for a Cyclic Executive
Dependencies: MCP23017 SDFileSystem WattBob_TextLCD mbed
main.cpp
- Committer:
- sk398
- Date:
- 2016-03-02
- Revision:
- 10:c0531edf4850
- Parent:
- 9:46408a8dea0c
File content as of revision 10:c0531edf4850:
/* #####################################################################
main.cpp
---------
Embedded Software - Assignment 2
--------------------------------
Written by: Steven Kay
Date: February 2016
Function: This is the main runner containing the Cyclic executive
There are 7 defined tasks and several Auxillary components
which are logically ran periodically at their required time
by a Cyclic Executive sequencer.
Ticks, or slots, to this Cyclic Executive are provided by
a ticker ever 25ms, and then using logical expressions, the
correct task is initiated and allocated the required time.
##################################################################### */
#include "mbed.h"
#include "Tasks.h"
// ============================================================================
// Task Declerations
// ============================================================================
Task1 task1(p11); // Square wave Measurement
Task2 task2_switch1(p12); // Read digital Input
Task3 task3(p13); // Watchdog Pulse
Task4 task4(p15,p16); // Read analog Inputs
Task5 task5(p9,p10,0x40); // Output to LCD Display
Task6 task6; // Logical checks
Task7 task7(p5,p6,p7,p8,"SD","/SD/A2"); // SD Card Write
// ============================================================================
// Cyclic Executive Objects and Declerations
// ============================================================================
DigitalOut ErrorLED(LED1); // Error Indicating LED
DigitalOut LenPin(p25); // Pulse Pin
DigitalIn SDRemoval(p18); // Switch state to indicate remove SD
Ticker CyclicTicker; // Ticker object to cycle tasks
Timer stampTime; // Timer to stamp the time between logs
// NOTE THE FOLLOWING ARE NOT ESSENTIAL TO THE OPERATION OF THIS CYCLIC EXECUTIVE
Timer task1t; // Timer to calculate task1 timing
Timer task2t; // Timer to calculate task2 timing
Timer task3t; // Timer to calculate task3 timing
Timer task4t; // Timer to calculate task4 timing
Timer task5t; // Timer to calculate task5 timing
Timer task6t; // Timer to calculate task6 timing
// ============================================================================
// Global Data Parameters used in Cyclic Executive
// ============================================================================
// Counter to record the number of ticks went through by the Cyclic Executive
int cyclicTicks = 1;
// Flag variable to switch priority between Tasks 2 and 3
int taskNum = 2;
// Global parameter storing the most up to date value of the return from Task 1
volatile int task1Frequency;
// Global parameter storing the most up to date value of the return from Task 2
volatile int task2SwitchState;
// Global parameter storing the most up to date value of the return from Task 4
volatile float task4AnalogChannels[2];
// Global parameter storing the most up to date value of the return from Task 6
volatile int task6ErrorState;
// Char array to store the concatenated string for output onto the SD Card
char logData[50];
// ============================================================================
// Cyclic Executive Function Prototypes
// ============================================================================
void CyclicExec();
// ============================================================================
// Main Execution Program
// ============================================================================
int main() {
// Attempt to open SD file
// If open failed, do not run Cyclic Exec
if(!task7.openFile("/SD/A2/test.csv","a"))
{
// Start Cyclic Executive
CyclicTicker.attach(&CyclicExec,0.025); // 25ms pulses
// Keep program running until RESET
while(1)
{
}
}
// If FIle is not opened, prompt user and show Error on LED
else
{
// Prompt user about error
printf("File not opened\r\nNot executing Cyclic Executive");
// Execute error code on LED
while(1)
{
ErrorLED = 1;
wait(1);
ErrorLED = 0;
wait(1);
}
}
}
#define TASK1_TICKS 40
#define TASK2_TICKS 12
#define TASK3_TICKS 12
#define TASK4_TICKS 16
#define TASK5_TICKS 80
#define TASK6_TICKS 32
#define TASK7_TICKS 200
void CyclicExec()
{
// When called, increment cyclicTicks
cyclicTicks++;
// Run every 1 second (should be 40 ticks, but tuned to 38 through testing)
if(cyclicTicks % 38 == 0)
{
// ---------- Can be removed ---------
task1t.stop();
printf("T1 %d\r\n",task1t.read_ms());
// -----------------------------------
// Run Task1
LenPin = 1;
task1Frequency = task1.ReadFrequency();
LenPin = 0;
// ---------- Can be removed ---------
task1t.reset();
task1t.start();
// -----------------------------------
}
// Run every 300ms (should be 12 ticks, but logic dictates double the frequency)
if(cyclicTicks % 6 == 0)
{
// If flag taskNum is assigned to run Task2
if(taskNum == 2)
{
// ---------- Can be removed ---------
task2t.stop();
printf("T2 %d\r\n",task2t.read_ms());
// -----------------------------------
// Run Task 2
task2SwitchState = task2_switch1.digitalInState();
// Set flag to run Task 3 on next iteration
taskNum = 3;
// ---------- Can be removed ---------
task2t.reset();
task2t.start();
// -----------------------------------
}
// If flag taskNum is assigned to run Task3
else if(taskNum == 3)
{
// ---------- Can be removed ---------
task3t.stop();
printf("T3 %d\r\n",task3t.read_ms());
// -----------------------------------
// Run Task3
task3.OutputWatchdogPulse();
// Set flag to run Task2 on next iteration
taskNum = 2;
// ---------- Can be removed ---------
task3t.reset();
task3t.start();
// -----------------------------------
}
}
// Run every 400ms (16 ticks)
if(cyclicTicks % 16 == 0)
{
// ---------- Can be removed ---------
task4t.stop();
printf("T4 %d\r\n",task4t.read_ms());
// -----------------------------------
// Run Task4
float *analogReading = task4.returnAnalogReadings();
task4AnalogChannels[0] = *(analogReading);
task4AnalogChannels[1]= *(analogReading+1);
// ---------- Can be removed ---------
task4t.reset();
task4t.start();
// -----------------------------------
}
// Run every 2 seconds (should be 80 ticks, but tuned to 84 through testing)
if(cyclicTicks % 84 == 0)
{
// ---------- Can be removed ---------
task5t.stop();
printf("T5 %1.2f\r\n",task5t.read());
// -----------------------------------
// Run Task5
task5.updateDisplay( task1Frequency,
task2SwitchState,
task6ErrorState,
task4AnalogChannels[0],
task4AnalogChannels[1] );
// ---------- Can be removed ---------
task5t.reset();
task5t.start();
// -----------------------------------
}
// Run every 800ms (32 ticks)
if(cyclicTicks % 32 == 0)
{
// ---------- Can be removed ---------
task6t.stop();
printf("T6 %d\r\n",task6t.read_ms());
// -----------------------------------
// Run Task6
task6ErrorState = task6.updateErrorCode( task2SwitchState,
task4AnalogChannels[0],
task4AnalogChannels[1] );
// ---------- Can be removed ---------
task6t.reset();
task6t.start();
// -----------------------------------
}
// Run every 5 seconds (200 ticks)
if(cyclicTicks % 200 == 0)
{
// ---------- Can be removed ---------
printf("T7\r\n");
// -----------------------------------
// Run Task7
stampTime.stop();
int a = sprintf( logData,"Time=%1.2f,Freq=%d,SW1=%d,A1=%1.3f,A2=%1.3f\n",
stampTime.read(),
task1Frequency,
task2SwitchState,
task4AnalogChannels[0],
task4AnalogChannels[1] );
task7.writeData(logData);
// ---------- Can be removed ---------
stampTime.reset();
stampTime.start();
// -----------------------------------
}
// If SDRemoval Input is high, close FILE and detach the Ticker
if(SDRemoval == HIGH)
{
printf("SD Removed");
task7.closeFile();
CyclicTicker.detach();
}
}