Skip to content

Commit

Permalink
update to recent from gf_aurora
Browse files Browse the repository at this point in the history
  • Loading branch information
tzhu committed May 19, 2024
1 parent d28f765 commit caeac68
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 78 deletions.
2 changes: 2 additions & 0 deletions os-timer-port.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ void portTimerInit( void (*callback)());

void portTimerStop();

#define portTimerTicksPerUs() 1

long portTimerGetUs();

void portTimerStart(long end_us);
Expand Down
205 changes: 129 additions & 76 deletions os-timer.cpp
Original file line number Diff line number Diff line change
@@ -1,110 +1,163 @@
#include "os-timer.h"
#include <etl/multiset.h>
#include "pt-os.h"
#include "os-timer-port.h"
#include <etl/set.h>

constexpr int kMaxTimerItem = 16;
static void OsTimerIsrHandler_();

typedef struct
class PtTimer
{
OsTimerCallback_t callback;
void *param;
uint64_t period_tick;
uint64_t end_tick;
int id;
bool repeatable;
} OsTimer_t;

volatile int kOsTimerTrigged_ = 0;
int kOsTimerHandled_ = 0;
int kOsTimerIdSeed_ = 0;

struct tick_cmp
{
bool operator()(const OsTimer_t &a, const OsTimer_t &b) const { return a.end_tick < b.end_tick; }
};
etl::set<OsTimer_t, kMaxTimerItem, tick_cmp> gOsTimerObj_;
public:
typedef struct
{
OsTimerCallback_t callback;
void *param;
uint64_t period_us;
uint64_t end_us;
int id;

static void OsTimerIsrHandler_()
{
kOsTimerTrigged_ += 1;
portTimerStop();
}
int repeatable;
} PtTimer_t;
struct tick_cmp
{
bool operator()(const PtTimer_t &a, const PtTimer_t &b) const { return a.end_us < b.end_us; }
};
PtTimer()
{
timerTrigged_ = 0;
timerHandled_ = 0;
timerIdSeed_ = 0;
}
bool NewTimerEventHappened()
{
if (timerTrigged_ <= timerHandled_) return false;
timerHandled_++;
return true;
}

TASK_DECLARE(OsTimerTask_(OsTaskId taskId, void *))
{
TASK_BEGIN(taskId);
while (1)
void Init(uint64_t ticksPerUs)
{
ticksPerUs_ = ticksPerUs;
timerObj_.clear();
}

void Handle()
{
TASK_WAIT_UNTIL(taskId, kOsTimerTrigged_ > kOsTimerHandled_);
kOsTimerHandled_++;
// find the first timer. Which happened most recently.
auto tim = gOsTimerObj_.begin();
OS_ASSERT(tim != gOsTimerObj_.end()); // Shouldn't be empty.
auto tim = timerObj_.begin();
OS_ASSERT(tim != timerObj_.end()); // Shouldn't be empty.

if (tim->callback) tim->callback(tim->id, tim->param);
// update the repeatable timer.
if (tim->repeatable)
{
gOsTimerObj_.insert(
{tim->callback, tim->param, tim->period_tick, tim->end_tick + tim->period_tick, tim->id, true});
timerObj_.insert(
{tim->callback, tim->param, tim->period_us, tim->end_us + tim->period_us, tim->id, 1});
}
// remove the current timer.
gOsTimerObj_.erase(tim);
timerObj_.erase(tim);

// if has one or more timer enable it.
tim = gOsTimerObj_.begin();
if (tim != gOsTimerObj_.end())
portTimerStart(tim->end_tick);
tim = timerObj_.begin();
if (tim != timerObj_.end()) portTimerStart(tim->end_us);
}

int Register(OsTimerCallback_t callback, void *param, uint64_t period_us, bool repeatable, int *id)
{
if (timerObj_.full()) return OS_NO_RESOURCE;
portTimerStop();
timerObj_.insert(
{callback, param, period_us, portTimerGetUs() + period_us, ++timerIdSeed_, repeatable ? 1 : 0});
portTimerStart(timerObj_.begin()->end_us);
if (id) *id = timerIdSeed_;
return TASK_OP_SUCCESS;
}

int Count() { return timerObj_.size(); }

int Kill(int id)
{
for (auto it = timerObj_.begin(); it != timerObj_.end(); it++)
{
if (it->id == id)
{
if (it == timerObj_.begin())
{
// if 1st timer is killed, reload the next one.
portTimerStop();
timerObj_.erase(it);
it = timerObj_.begin();
if (it != timerObj_.end()) portTimerStart(it->end_us);
}
else
timerObj_.erase(it);
return TASK_OP_SUCCESS;
}
}
return INVALID_TASK_ID;
}

int DelayUs(uint64_t delay_us)
{
bool timerTriggered = false;
// HAL_UartPrint("[TIM]: from %llu - %lluUs\n", portTimerGetUs(), delay_us);
int rc = Register(timerDelayCallback_, &timerTriggered, delay_us, false, 0);
if (rc != TASK_OP_SUCCESS) return rc;
while (timerTriggered == false) TaskYield();
return TASK_OP_SUCCESS;
}

void EventCallback()
{
timerTrigged_ += 1;
portTimerStop();
}

protected:
static void timerDelayCallback_(int id, void *param)
{
bool *triggerred = (bool *)param;
// HAL_UartPrint("[TIM]: to %llu\n", portTimerGetUs());
*triggerred = true;
}
volatile int timerTrigged_;
int timerHandled_;
int timerIdSeed_;
uint64_t ticksPerUs_;
etl::multiset<PtTimer_t, osMaxTimers, tick_cmp> timerObj_;
};

static PtTimer kTimer_;

static void OsTimerIsrHandler_() { kTimer_.EventCallback(); }

static TASK_DECLARE(OsTimerTask_(OsTaskId taskId, void *))
{
TASK_BEGIN(taskId);
while (1)
{
TASK_WAIT_UNTIL(taskId, kTimer_.NewTimerEventHappened());

kTimer_.Handle();
}
TASK_END(taskId);
}

void OsTimerInit()
{
gOsTimerObj_.clear();
portTimerInit(OsTimerIsrHandler_);
portTimerStop();
kTimer_.Init(portTimerTicksPerUs());
RegisterTask("thrTmr", OsTimerTask_, nullptr);
}

int OsTimerRegister(OsTimerCallback_t callback, void *param, uint64_t period_us, bool repeatable, int *id)
{
if (gOsTimerObj_.full()) return NO_RESOURCE;
portTimerStop();
gOsTimerObj_.insert({callback, param, period_us,
portTimerGetUs() + period_us, ++kOsTimerIdSeed_, repeatable});
portTimerStart(gOsTimerObj_.begin()->end_tick);
if (id) *id = kOsTimerIdSeed_;
return TASK_OP_SUCCESS;
return kTimer_.Register(callback, param, period_us, repeatable, id);
}

int OsTimerCount() { return gOsTimerObj_.size(); }

int OsTimerKill(int id)
{
for (auto it = gOsTimerObj_.begin(); it != gOsTimerObj_.end(); it++)
{
if (it->id == id)
{
gOsTimerObj_.erase(it);
return TASK_OP_SUCCESS;
}
}
return INVALID_TASK_ID;
}
int OsTimerCount() { return kTimer_.Count(); }

static void timerDelayCallback_(int id, void *param)
{
bool *triggerred = (bool *)param;
// HAL_UartPrint("[TIM]: to %llu\n", portTimerGetUs());
*triggerred = true;
}
int OsTimerKill(int id) { return kTimer_.Kill(id); }

int OsTimerDelayUs(uint64_t delay_us)
{
bool timerTriggered = false;
// HAL_UartPrint("[TIM]: from %llu - %lluUs\n", portTimerGetUs(), delay_us);
int rc = OsTimerRegister(timerDelayCallback_, &timerTriggered, delay_us, false, 0);
if (rc != TASK_OP_SUCCESS) return rc;
while (timerTriggered == false) TaskYield();
return TASK_OP_SUCCESS;
}
int OsTimerDelayUs(uint64_t delay_us) { return kTimer_.DelayUs(delay_us); }
5 changes: 5 additions & 0 deletions os-timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ extern "C"
\*****************************************************************************/
int OsTimerKill(int id);

/*****************************************************************************\
* @description : delay micro seconds
* @param [I]: delay_us
* @return error or success
\*****************************************************************************/
int OsTimerDelayUs(uint64_t delay_us);

#ifdef __cplusplus
Expand Down
7 changes: 6 additions & 1 deletion pt-os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,12 @@ int OsInit(void)
return TASK_OP_SUCCESS;
}

static TaskFunction idleTask = nullptr;

void OsStart(void)
{
if (idleTask) RegisterTask("Idle", idleTask, nullptr);
while (sOsControlBlock_.NumOfLivingTasks() > 0) sOsControlBlock_.Schedule();
}
}

void OsAddIdleTask(TaskFunction task) { idleTask = task; }
4 changes: 3 additions & 1 deletion pt-os.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extern "C"
#define TASK_OP_SUCCESS (0)
#define INVALID_TASK_ID (-1)
#define INVALID_TASK_STATUS (-2)
#define NO_RESOURCE (-3)
#define OS_NO_RESOURCE (-3)

typedef enum
{
Expand Down Expand Up @@ -65,6 +65,8 @@ extern "C"
// Start scheduling all the tasks, only return while all tasks are OsTaskExit or OsTaskNotExist.
void OsStart(void);

void OsAddIdleTask(TaskFunction task);

#if __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions pt-osConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
// Number of maximum threads support
#define osMaxThreads (64)

// Number of timer.
#define osMaxTimers (64)

#include <cassert>
#define OS_ASSERT assert

Expand Down

0 comments on commit caeac68

Please sign in to comment.