Skip to content

Commit

Permalink
os-timer OOP, update bash_build.sh
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhuLingQing committed Mar 17, 2024
1 parent b370037 commit 0f21a8c
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 89 deletions.
38 changes: 22 additions & 16 deletions bash_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,38 @@ set -o pipefail
lib_name=pt_os
build_dir=build

#test g++ and git has been installed
g++ --version
echo "----Check g++ has been installed"
git --version

#remove the build dir and make it.
echo "----remove the build dir and make it."
if [ -d ${build_dir} ];then
rm -rf ${build_dir}/*
else
mkdir ${build_dir}
fi
pushd ${build_dir}

#clone the dependency repo
git clone https://github.com/ZhuLingQing/protothreads.git
git clone https://github.com/ETLCPP/etl.git
pushd etl
git checkout 20.38.10
popd
#build the os static library
g++ -g -o ${pt-os}.o -c ../pt-os.cpp -I./protothreads -I./etl
g++ -g -o ${os-timer}.o -c ../os-timer.cpp -I./protothreads -I./etl
g++ -g -o ${os-timer-port}.o -c ../os-timer-port.cpp -I./protothreads -I./etl
ar -rv lib${lib_name}.a ${pt-os}.o ${os-timer}.o ${os-timer-port}.o
#build the test
echo "----clone the dependency repo"
if [ ! -d "protothreads" ];then
git clone https://github.com/ZhuLingQing/protothreads.git
fi

if [ ! -d "etl" ];then
git clone https://github.com/ETLCPP/etl.git
pushd etl
git checkout 20.38.10
popd
fi

echo "----build the os static library"
g++ -g -o ${pt-os}.o -c ../pt-os.cpp -I./protothreads -I./etl/include
g++ -g -o ${os-timer}.o -c ../os-timer.cpp -I./protothreads -I./etl/include
ar -rv lib${lib_name}.a ${pt-os}.o ${os-timer}.o

echo "----build the test"
g++ -g -o test_pt_os ../tests/*.cpp -I./protothreads -I.. -I../tests -L. -l${lib_name}
#run the test

echo "----run the test"
./test_pt_os
rc=$?
if [ ${rc} -eq 0 ];then
Expand Down
193 changes: 123 additions & 70 deletions os-timer.cpp
Original file line number Diff line number Diff line change
@@ -1,110 +1,163 @@
#include "os-timer.h"
#include "pt-os.h"
#include "os-timer-port.h"
#include <etl/set.h>
#include <etl/multiset.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;
bool 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;
}

static void OsTimerIsrHandler_()
{
kOsTimerTrigged_ += 1;
portTimerStop();
}
void Init()
{
timerObj_.clear();
}

TASK_DECLARE(OsTimerTask_(OsTaskId taskId, void *))
{
TASK_BEGIN(taskId);
while (1)
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, true});
}
// 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 NO_RESOURCE;
portTimerStop();
timerObj_.insert({callback, param, period_us,
portTimerGetUs() + period_us, ++timerIdSeed_, repeatable});
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)
{
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;
}

inline void try_insert(OsTimerCallback_t callback, void *param, uint64_t period_us, uint64_t end_us, bool repeatable)
{

}
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_;
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();
kTimer_.Init();
portTimerInit(OsTimerIsrHandler_);
portTimerStop();
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 OsTimerCount() { return kTimer_.Count(); }

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;
}

static void timerDelayCallback_(int id, void *param)
{
bool *triggerred = (bool *)param;
// HAL_UartPrint("[TIM]: to %llu\n", portTimerGetUs());
*triggerred = true;
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;
return kTimer_.DelayUs(delay_us);
}
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 maximum timer support
#define osMaxTimers (64)

#include <cassert>
#define OS_ASSERT assert

Expand Down
6 changes: 3 additions & 3 deletions tests/timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ constexpr int kMaxTestNum_ = 10;
volatile int kSignalTriggered_ = 0;
uint64_t kStartUs_;
static long testTimerParam[kMaxTestNum_];
constexpr long testTimerGolden[kMaxTestNum_] = {11, 33, 50, 51, 33, 33, 99, 33, 33, 33};
constexpr long testTimerGolden[kMaxTestNum_] = {11, 33, 50, 51, 33, 99, 33, 33, 33, 33};
static uint64_t testUsCounter[kMaxTestNum_];
constexpr uint64_t testUsGolden[kMaxTestNum_] = {100, 300, 500, 500, 600, 900, 1000, 1200, 1500, 1800};
constexpr uint64_t testUsGolden[kMaxTestNum_] = {100, 300, 500, 500, 600, 900, 900, 1200, 1500, 1800};

void testTimerCallback_(int id, void *param)
{
Expand Down Expand Up @@ -84,7 +84,7 @@ int TestTimer()

OsTimerRegister(testTimerCallback_, (void *)(11), 100 * testTimerGain_, false, nullptr);
OsTimerRegister(testTimerCallback_, (void *)(50), 500 * testTimerGain_, false, nullptr);
OsTimerRegister(testTimerCallback_, (void *)(99), 1000 * testTimerGain_, false, nullptr);
OsTimerRegister(testTimerCallback_, (void *)(99), 900 * testTimerGain_, false, nullptr);
OsTimerRegister(testTimerCallback_, (void *)(33), 300 * testTimerGain_, true, &repeat_timer_id);
OsTimerRegister(testTimerCallback_, (void *)(51), 500 * testTimerGain_, false, nullptr);

Expand Down

0 comments on commit 0f21a8c

Please sign in to comment.