Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b69abb1
Add untested EventScheduler class
ShaneTWilliams Nov 10, 2019
fb6a923
Add untested Event class
ShaneTWilliams Nov 10, 2019
3f515a7
Fix small i2c interface error for compiling purposes
ShaneTWilliams Nov 10, 2019
b65b01e
Remove local variable `event` and operate on member array of events
ShaneTWilliams Nov 10, 2019
9ac9542
Add setter for m_num_calls_left
ShaneTWilliams Nov 10, 2019
8b5233b
Change EventScheduler::callFunctionAfter behaviour to be callFunction…
ShaneTWilliams Nov 10, 2019
6448937
Remove example test
ShaneTWilliams Nov 10, 2019
973919c
Add more descriptive comments to EventScheduler class
ShaneTWilliams Nov 10, 2019
22cd84a
Add more descriptive comments to Event class
ShaneTWilliams Nov 10, 2019
db41025
Update platformio.ini to include event scheduler
ShaneTWilliams Nov 10, 2019
4158cad
Change order of callFunctionEvery args
ShaneTWilliams Nov 10, 2019
ce5c537
Add comments and whitespace fixes
ShaneTWilliams Nov 10, 2019
83ccf5c
Add testing main for EventScheduler class
ShaneTWilliams Nov 10, 2019
0cc3318
Remove Testing as default env before PR
ShaneTWilliams Nov 10, 2019
5d4195c
Add newlines to end of files
ShaneTWilliams Nov 16, 2019
a350ef7
Move implementation of `Event` methods to header
ShaneTWilliams Nov 16, 2019
6ab8189
Rename `Event` method `callCallback` to `callback` :(
ShaneTWilliams Nov 16, 2019
74b5964
Change `Event` class to a struct and change m_events from an array to…
ShaneTWilliams Nov 22, 2019
155521e
Change eventId_t from int8_t to int16_t in case if more than 127 even…
ShaneTWilliams Nov 22, 2019
1f59a72
Add getter for m_MAX_NUM_EVENTS
ShaneTWilliams Nov 22, 2019
5b9b4c6
Add unit tests suggested in PR
ShaneTWilliams Nov 22, 2019
426c7d1
Add new comments to EventScheduler class
ShaneTWilliams Nov 22, 2019
ea74d95
Add better comments to `findFreeEventId`
ShaneTWilliams Nov 22, 2019
cf8ad37
Move EventScheduler from Node/Common to OnPod/Common
ShaneTWilliams Nov 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions OnPod/Node/Common/EventScheduler/include/event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef NODE_EVENT_H
#define NODE_EVENT_H

#include <stdint.h>

typedef uint32_t timeMs_t; // Time in ms

enum class EventType
{
UNASSIGNED,
FINITE, // Repeat X number of times
FOREVER, // Repeat forever
};

enum class EventState
{
STARTED,
STOPPED,
};

class Event
{
private:
EventType m_type = EventType::UNASSIGNED;
EventState m_state = EventState::STOPPED;
void (*m_callback)(void) = nullptr;
timeMs_t m_delay_ms = 0;
timeMs_t m_last_time_called_ms = 0;
uint32_t m_num_calls_left = 0;

public:
// Getters
EventType getType(void);
EventState getState(void);
timeMs_t getDelayMs(void);
timeMs_t getLastTimeCalledMs(void);
uint32_t getNumCallsLeft(void);

// Setters
void setType(EventType type);
void setState(EventState state);
void setDelayMs(timeMs_t delay_ms);
void setLastTimeCalledMs(timeMs_t time_ms);
void setCallback(void (*callback)(void));
void setNumCallsLeft(uint32_t num_calls);

// Take away one from the event's `m_num_calls_left`
void decrementNumCallsLeft(void);
void callCallback(void);
// Reset event attributes to prepare for reassignment
void cleanup(void);
};

#endif
46 changes: 46 additions & 0 deletions OnPod/Node/Common/EventScheduler/include/event_scheduler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef NODE_EVENT_SCHEDULER_H
#define NODE_EVENT_SCHEDULER_H

#include <stdint.h>
#include "event.h"

typedef int8_t eventId_t; // Should range from 0-127. -1 indicates error in finding free ID
typedef uint32_t timeMs_t; // Time in ms

class EventScheduler
{
private:
// Number of events that can be active at once
static const uint8_t m_MAX_NUM_EVENTS = 50;
// Array of Event objects
Event m_events[m_MAX_NUM_EVENTS];

// Returns an unassigned Event object in array, or -1 if none are free
eventId_t findFreeEvent(void);

public:
// Check if any callbacks must be called and execute them.
// If the repeat limit is reached, reset the event object.
void updateEvents(timeMs_t current_time);

// Resumes the event's calls
void startEvent(eventId_t event_id);
// Pauses all the event's calls.
// If the event has a certain number of repeats, they will be preserved after starting again.
void stopEvent(eventId_t event_id);

// Call `callback` every `delay_ms` milliseconds, `repeat_count` times.
// Returns index of event in `m_event_list` or -1 if `m_event_list` is full.
eventId_t callFunctionEvery(timeMs_t delay_ms, void (*callback)(void),
timeMs_t current_time, uint32_t repeat_count);
// Call `callback` every `delay_ms` milliseconds, forever.
// Returns index of event in `m_event_list` or -1 if `m_event_list` is full.
eventId_t callFunctionEvery(timeMs_t delay_ms, void (*callback)(void),
timeMs_t current_time);
// Call `callback` after `delay_ms` milliseconds.
// Returns index of event in `m_event_list` or -1 if `m_event_list` is full.
eventId_t callFunctionAfter(timeMs_t delay_ms, void (*callback)(void),
timeMs_t current_time);
};

#endif
78 changes: 78 additions & 0 deletions OnPod/Node/Common/EventScheduler/src/event.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "event.h"

EventType Event::getType(void)
{
return m_type;
}

EventState Event::getState(void)
{
return m_state;
}

uint32_t Event::getDelayMs(void)
{
return m_delay_ms;
}

uint32_t Event::getLastTimeCalledMs(void)
{
return m_last_time_called_ms;
}

uint32_t Event::getNumCallsLeft(void)
{
return m_num_calls_left;
}


void Event::setType(EventType type)
{
m_type = type;
}

void Event::setState(EventState state)
{
m_state = state;
}

void Event::setDelayMs(timeMs_t delay_ms)
{
m_delay_ms = delay_ms;
}

void Event::setLastTimeCalledMs(timeMs_t time_ms)
{
m_last_time_called_ms = time_ms;
}

void Event::setCallback(void (*callback)(void))
{
m_callback = callback;
}

void Event::setNumCallsLeft(uint32_t num_calls)
{
m_num_calls_left = num_calls;
}


void Event::decrementNumCallsLeft(void)
{
m_num_calls_left--;
}

void Event::callCallback(void)
{
m_callback();
}

void Event::cleanup(void)
{
m_type = EventType::UNASSIGNED;
m_state = EventState::STOPPED;
m_callback = nullptr;
m_delay_ms = 0;
m_last_time_called_ms = 0;
m_num_calls_left = 0;
}
85 changes: 85 additions & 0 deletions OnPod/Node/Common/EventScheduler/src/event_scheduler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "event_scheduler.h"

void EventScheduler::updateEvents(timeMs_t current_time)
{
// Iterate through m_events array
for (eventId_t id = 0; id < m_MAX_NUM_EVENTS; id++)
{
// Ignore stopped or unused event objects
if (m_events[id].getType() == EventType::UNASSIGNED ||
m_events[id].getState() == EventState::STOPPED)
{
continue;
}
// If the event's delay has passed
if ((current_time - m_events[id].getLastTimeCalledMs() >= m_events[id].getDelayMs()))
{
m_events[id].callCallback();
m_events[id].setLastTimeCalledMs(current_time);
// If the event only runs a certain number of times
if (m_events[id].getType() == EventType::FINITE)
{
m_events[id].decrementNumCallsLeft();
// Unassign/reset event objects that are finished
if (m_events[id].getNumCallsLeft() == 0)
{
m_events[id].cleanup();
}
}
}
}
}

eventId_t EventScheduler::findFreeEvent(void)
{
for (eventId_t id = 0; id < m_MAX_NUM_EVENTS; id++)
{
if (m_events[id].getType() == EventType::UNASSIGNED)
{
return id;
}
}
return -1;
}

void EventScheduler::startEvent(eventId_t event_id)
{
m_events[event_id].setState(EventState::STARTED);
}

void EventScheduler::stopEvent(eventId_t event_id)
{
m_events[event_id].setState(EventState::STOPPED);
}

eventId_t EventScheduler::callFunctionEvery(timeMs_t delay_ms, void (*callback)(void),
timeMs_t current_time, uint32_t repeat_count)
{
eventId_t id = findFreeEvent();
m_events[id].setType(EventType::FINITE);
m_events[id].setState(EventState::STARTED);
m_events[id].setDelayMs(delay_ms);
m_events[id].setLastTimeCalledMs(current_time);
m_events[id].setCallback(callback);
m_events[id].setNumCallsLeft(repeat_count);
return id;
}

eventId_t EventScheduler::callFunctionEvery(timeMs_t delay_ms, void (*callback)(void),
timeMs_t current_time)
{
eventId_t id = findFreeEvent();
m_events[id].setType(EventType::FOREVER);
m_events[id].setState(EventState::STARTED);
m_events[id].setDelayMs(delay_ms);
m_events[id].setLastTimeCalledMs(current_time);
m_events[id].setCallback(callback);
m_events[id].setNumCallsLeft(0);
return id;
}

eventId_t EventScheduler::callFunctionAfter(timeMs_t delay_ms, void (*callback)(void),
timeMs_t current_time)
{
return callFunctionEvery(delay_ms, callback, current_time, 1);
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class I2CInterface
HAL_StatusTypeDef memRead(uint16_t devAddress, uint16_t memAddress,
uint16_t memAddressSize, uint32_t timeout);

HAL_StatusTypeDef isDeviceReady(uint16_t devAddress, uint32_t trials = 100, uint32_t timeout);
HAL_StatusTypeDef isDeviceReady(uint16_t devAddress, uint32_t trials, uint32_t timeout);

/*
Config methods for digital and analog noise filters
Expand Down
Loading