Skip to content

Commit

Permalink
porting linux
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhuLingQing committed Mar 16, 2024
1 parent f0e42a7 commit 79d59a5
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 54 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
build/
.vscode/
*.bak
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ include_directories(${PROJECT_SOURCE_DIR})

target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

target_link_libraries(${LIB_NAME} protothreads)
target_link_libraries(${LIB_NAME} protothreads etl)

set( OS_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE )

Expand Down
10 changes: 8 additions & 2 deletions bash_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@ 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 ${lib_name}.o -c ../pt-os.cpp -I./protothreads
ar -rv lib${lib_name}.a ${lib_name}.o
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
g++ -g -o test_pt_os ../tests/*.cpp -I./protothreads -I.. -I../tests -L. -l${lib_name}
#run the test
Expand Down
67 changes: 67 additions & 0 deletions os-timer-port.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "os-timer-port.h"
#include "os-timer.h"
#include "pt-os.h"
#include <stdio.h>

#if __linux__

#include <signal.h>
#include <time.h>
#include <sys/time.h>

static void (*TimerCallback_)();
static long TimerBaseUs_ = 0;

static void TimerRoutine(int signo)
{
struct itimerval value, ovalue;
switch (signo){
case SIGALRM:
portTimerStop();
TimerCallback_();
break;
}
}

void portTimerInit( void (*callback)())
{
struct timeval tv;
gettimeofday(&tv,NULL);
TimerBaseUs_ = tv.tv_sec*1000000 + tv.tv_usec;
TimerCallback_ = callback;
signal(SIGALRM, TimerRoutine);
}

void portTimerStop()
{
struct itimerval value, ovalue;
value.it_value.tv_sec = 0;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 0;
value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &value, &ovalue);
}

long portTimerGetUs()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return (tv.tv_sec*1000000 + tv.tv_usec - TimerBaseUs_);
}

void portTimerStart(long end_us)
{
struct itimerval value, ovalue;
long offset = end_us - portTimerGetUs();
if (offset > 5)
{
value.it_value.tv_sec = offset/1000000;
value.it_value.tv_usec = offset%1000000;
value.it_interval.tv_sec = value.it_value.tv_sec;
value.it_interval.tv_usec = value.it_value.tv_usec;
setitimer(ITIMER_REAL, &value, &ovalue);
}
else TimerCallback_();
}

#endif
18 changes: 15 additions & 3 deletions os-timer-port.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
#ifndef _OS_TIMER_PORT_H_
#define _OS_TIMER_PORT_H_

#if __linux__

void portTimerInit( void (*callback)());

void portTimerStop();

long portTimerGetUs();

void portTimerStart(long end_us);

#elif __riscv__

#include "hal/timer/mtime.h"
#include "hal/timer/riscv_mtime_csr.h"

Expand All @@ -15,10 +27,10 @@

#define portTimerTicksPerUs() ((MtimeGetPeriod() + 1) * 1000)

#define portTimerGetTick() __mtime_get_count()

#define portTimerComputeEndTick(tick) (portTimerGetTick() + (tick))
#define portTimerGetUs() __mtime_get_count()

#define portTimerStart(end) __mtime_set_compare(end)

#endif

#endif
23 changes: 10 additions & 13 deletions os-timer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "os_timer.h"
#include "os-timer.h"
#include "pt-os.h"
#include "os_timer_port.h"
#include "os-timer-port.h"
#include <etl/set.h>

constexpr int kMaxTimerItem = 16;
Expand All @@ -18,7 +18,6 @@ typedef struct
volatile int kOsTimerTrigged_ = 0;
int kOsTimerHandled_ = 0;
int kOsTimerIdSeed_ = 0;
uint64_t kOsTimerTicksPerUs_ = 0;

struct tick_cmp
{
Expand Down Expand Up @@ -52,11 +51,9 @@ TASK_DECLARE(OsTimerTask_(OsTaskId taskId, void *))
// remove the current timer.
gOsTimerObj_.erase(tim);
// if has one or more timer enable it.
if (gOsTimerObj_.size())
{
tim = gOsTimerObj_.begin();
tim = gOsTimerObj_.begin();
if (tim != gOsTimerObj_.end())
portTimerStart(tim->end_tick);
}
}
TASK_END(taskId);
}
Expand All @@ -65,16 +62,15 @@ void OsTimerInit()
{
portTimerInit(OsTimerIsrHandler_);
portTimerStop();
kOsTimerTicksPerUs_ = portTimerTicksPerUs();
RegisterTask("thrTmr", OsTimerTask_, nullptr);
}

int OsTimerRegister(OsTimerCallback_t callback, void *param, uint64_t period_us, bool repeatable, int *id)
{
if (gOsTimerObj_.full()) return kLtMallocFail;
if (gOsTimerObj_.full()) return NO_RESOURCE;
portTimerStop();
gOsTimerObj_.insert({callback, param, period_us * kOsTimerTicksPerUs_,
portTimerComputeEndTick(period_us * kOsTimerTicksPerUs_), ++kOsTimerIdSeed_, repeatable});
gOsTimerObj_.insert({callback, param, period_us,
portTimerGetUs() + period_us, ++kOsTimerIdSeed_, repeatable});
portTimerStart(gOsTimerObj_.begin()->end_tick);
if (id) *id = kOsTimerIdSeed_;
return TASK_OP_SUCCESS;
Expand All @@ -92,19 +88,20 @@ int OsTimerKill(int id)
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", portTimerGetTick());
// HAL_UartPrint("[TIM]: to %llu\n", portTimerGetUs());
*triggerred = true;
}

int OsTimerDelayUs(uint64_t delay_us)
{
bool timerTriggered = false;
// HAL_UartPrint("[TIM]: from %llu - %lluUs\n", portTimerGetTick(), delay_us);
// 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();
Expand Down
3 changes: 3 additions & 0 deletions os-timer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef _OS_TIMER_H_
#define _OS_TIMER_H_

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C"
{
Expand Down
1 change: 1 addition & 0 deletions pt-os.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern "C"
#define TASK_OP_SUCCESS (0)
#define INVALID_TASK_ID (-1)
#define INVALID_TASK_STATUS (-2)
#define NO_RESOURCE (-3)

typedef enum
{
Expand Down
2 changes: 2 additions & 0 deletions pt-osConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
#include <cassert>
#define OS_ASSERT assert

#define OS_PRINT printf

#endif
74 changes: 39 additions & 35 deletions tests/timer.cpp
Original file line number Diff line number Diff line change
@@ -1,58 +1,59 @@
#include <os.h>
#include "os_test.h"
#include <os-timer-port.h>

constexpr long testTimerGain_ = 10000;
constexpr int kMaxTestNum_ = 10;
volatile int testCount = 0;
uint64_t tickStart;
volatile int kSignalTriggered_ = 0;
uint64_t kStartUs_;
static long testTimerParam[kMaxTestNum_];
constexpr long testTimerGolden[kMaxTestNum_] = {11, 33, 50, 51, 33, 99, 33, 33, 33, 33};
static uint64_t testTickCounter[kMaxTestNum_];
constexpr uint64_t testTickGolden[kMaxTestNum_] = {100, 300, 500, 500, 600, 900, 900, 1200, 1500, 1800};
static uint64_t testUsCounter[kMaxTestNum_];
constexpr uint64_t testUsGolden[kMaxTestNum_] = {100, 300, 500, 500, 600, 900, 900, 1200, 1500, 1800};

void testTimerCallback_(int id, void *param)
{
testTickCounter[testCount] = portTimerGetTick() / 1000 - tickStart;
testTimerParam[testCount] = (long)param;
OS_TRACE("Timer%d: %lld happened at %llu\n", id, testTimerParam[testCount], testTickCounter[testCount]);
testCount++;
testUsCounter[kSignalTriggered_] = portTimerGetUs();
testTimerParam[kSignalTriggered_] = (long)param;
OS_TRACE("Timer%d: %lld happened at %llu\n", id, testTimerParam[kSignalTriggered_], testUsCounter[kSignalTriggered_]/1000);
kSignalTriggered_++;
}

constexpr long kTimerTaskSeconds_ = 3;
long tCount1Ms = 0;
long tCount100Us = 0;
long tCount1s = 0;
long tCount100Ms = 0;
long tCountIdle = 0;

static void timerDelayCallback_(int id, void *param)
{
bool *triggerred = (bool *)param;
// OS_TRACE("[TIM]: to %llu\n", portTimerGetTick());
// OS_TRACE("[TIM]: to %llu\n", portTimerGetUs());
*triggerred = true;
}

PT_THREAD(testTimerThread1Ms_(OsTaskId taskId, void *param))
PT_THREAD(testTimerThread1s_(OsTaskId taskId, void *param))
{
static bool timerTriggered;
TASK_BEGIN(taskId);
while (1)
{
OsTimerDelayUs(1000);
OsTimerDelayUs(1000 * 1000);
TASK_YIELD(taskId); // force Yield
tCount1Ms++;
// OS_TRACE("1Ms hit %ld, idleYield %ld\n", tCount1Ms, tCountIdle);
tCount1s++;
// OS_TRACE("1s hit %ld, idleYield %ld\n", tCount1s, tCountIdle);
}
TASK_END(taskId);
}

PT_THREAD(testTimerThread100Us_(OsTaskId taskId, void *param))
PT_THREAD(testTimerThread100Ms_(OsTaskId taskId, void *param))
{
static bool timerTriggered;
TASK_BEGIN(taskId);
while (1)
{
OsTimerDelayUs(100);
OsTimerDelayUs(100 * 1000);
TASK_YIELD(taskId); // force Yield
tCount100Us++;
// OS_TRACE("100Us hit %ld, idleYield %ld\n", tCount100Us, tCountIdle);
tCount100Ms++;
// OS_TRACE("100Ms hit %ld, idleYield %ld\n", tCount100Ms, tCountIdle);
}
TASK_END(taskId);
}
Expand All @@ -71,24 +72,27 @@ PT_THREAD(testIdleThread_(OsTaskId taskId, void *param))
int TestTimer()
{
int repeat_timer_id;
OS_TRACE("======== %s ========\n", __FUNCTION__);
OsInit();
OsTimerInit();
kStartUs_ = portTimerGetUs();
OS_TRACE("Timer Init\n", __FUNCTION__);

tickStart = portTimerGetTick() / 1000;
LT_ASSERT(kLtSc == OsTimerRegister(testTimerCallback_, (void *)(11), 100, false, nullptr));
LT_ASSERT(kLtSc == OsTimerRegister(testTimerCallback_, (void *)(50), 500, false, nullptr));
LT_ASSERT(kLtSc == OsTimerRegister(testTimerCallback_, (void *)(99), 900, false, nullptr));
LT_ASSERT(kLtSc == OsTimerRegister(testTimerCallback_, (void *)(33), 300, true, &repeat_timer_id));
LT_ASSERT(kLtSc == OsTimerRegister(testTimerCallback_, (void *)(51), 500, false, nullptr));
OsTimerRegister(testTimerCallback_, (void *)(11), 100 * testTimerGain_, false, nullptr);
OsTimerRegister(testTimerCallback_, (void *)(50), 500 * 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);

while (testCount < kMaxTestNum_) TaskYield();
OS_TRACE("Timer Yield\n", __FUNCTION__);
while (kSignalTriggered_ < kMaxTestNum_) TaskYield();
for (int i = 0; i < kMaxTestNum_; i++)
{
if (testTimerParam[i] != testTimerGolden[i] || testTickCounter[i] / 10 != testTickGolden[i] / 10)
if (testTimerParam[i] != testTimerGolden[i] || testUsCounter[i] / 1000 != testUsGolden[i] * testTimerGain_ / 1000)
{
OS_TRACE("Test%d Failed\n", i);
OS_TRACE("Timer [%lld : %lld]. Tick [%llu : %llu]\n", testTimerParam[i], testTimerGolden[i],
testTickCounter[i], testTickGolden[i]);
testUsCounter[i], testUsGolden[i] * testTimerGain_);
return 1;
}
}
Expand All @@ -97,25 +101,25 @@ int TestTimer()
OS_TRACE("Timer count error 1 - %d\n", OsTimerCount());
return 2;
}
LT_ASSERT(OsTimerKill(repeat_timer_id) == kLtSc);
OsTimerKill(repeat_timer_id);
if (OsTimerCount() != 0)
{
OS_TRACE("Timer count error 0 - %d\n", OsTimerCount());
return 3;
}

OS_TRACE("Test Timer in task\n");
RegisterTask("thr1Ms", &testTimerThread1Ms_, nullptr);
RegisterTask("thr100Us", &testTimerThread100Us_, nullptr);
RegisterTask("thr1s", &testTimerThread1s_, nullptr);
RegisterTask("thr100Ms", &testTimerThread100Ms_, nullptr);
RegisterTask("thrIdle", &testIdleThread_, nullptr);
OS_TRACE("Test Timer start\n");
while (tCount1Ms < kTimerTaskSeconds_)
while (tCount1s < kTimerTaskSeconds_)
{
TaskYield();
}
if ((tCount1Ms * 10 - tCount100Us) <= 2)
if ((tCount1s * 10 - tCount100Ms) <= 2)
{
OS_TRACE("Timer task error %ld - %ld\n", tCount1Ms, tCount100Us);
OS_TRACE("Timer task error %ld - %ld\n", tCount1s, tCount100Ms);
return 4;
}
OS_TRACE("Idle task yield %ld\n", tCountIdle);
Expand Down

0 comments on commit 79d59a5

Please sign in to comment.