From 298fe50521746ede2faa6b9c95c04ed6656dc77e Mon Sep 17 00:00:00 2001 From: tzhu Date: Sat, 16 Mar 2024 12:33:10 +0800 Subject: [PATCH 1/6] add timer with etl --- os-timer-port.h | 24 ++++++++++ os-timer.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++ os-timer.h | 47 ++++++++++++++++++ pt-os.h | 1 + tests/main.cpp | 3 ++ tests/timer.cpp | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 311 insertions(+) create mode 100644 os-timer-port.h create mode 100644 os-timer.cpp create mode 100644 os-timer.h create mode 100644 tests/timer.cpp diff --git a/os-timer-port.h b/os-timer-port.h new file mode 100644 index 0000000..47a0130 --- /dev/null +++ b/os-timer-port.h @@ -0,0 +1,24 @@ +#ifndef _OS_TIMER_PORT_H_ +#define _OS_TIMER_PORT_H_ + +#include "hal/timer/mtime.h" +#include "hal/timer/riscv_mtime_csr.h" + +#define portTimerInit(cb) \ + do \ + { \ + MtimeSetPeriod(0); \ + MtimeRegister(cb); \ + } while (0) + +#define portTimerStop() __mtime_set_compare(~0ULL) + +#define portTimerTicksPerUs() ((MtimeGetPeriod() + 1) * 1000) + +#define portTimerGetTick() __mtime_get_count() + +#define portTimerComputeEndTick(tick) (portTimerGetTick() + (tick)) + +#define portTimerStart(end) __mtime_set_compare(end) + +#endif diff --git a/os-timer.cpp b/os-timer.cpp new file mode 100644 index 0000000..f2205ab --- /dev/null +++ b/os-timer.cpp @@ -0,0 +1,111 @@ +#include "os_timer.h" +#include "pt-os.h" +#include "os_timer_port.h" + +constexpr int kMaxTimerItem = 16; + +typedef struct +{ + 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; +uint64_t kOsTimerTicksPerUs_ = 0; + +struct tick_cmp +{ + bool operator()(const OsTimer_t &a, const OsTimer_t &b) const { return a.end_tick < b.end_tick; } +}; +etl::set gOsTimerObj_; + +static void OsTimerIsrHandler_() +{ + kOsTimerTrigged_ += 1; + portTimerStop(); +} + +TASK_DECLARE(OsTimerTask_(OsTaskId taskId, void *)) +{ + TASK_BEGIN(taskId); + while (1) + { + 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. + 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}); + } + // remove the current timer. + gOsTimerObj_.erase(tim); + // if has one or more timer enable it. + if (gOsTimerObj_.size()) + { + tim = gOsTimerObj_.begin(); + portTimerStart(tim->end_tick); + } + } + TASK_END(taskId); +} + +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; + portTimerStop(); + gOsTimerObj_.insert({callback, param, period_us * kOsTimerTicksPerUs_, + portTimerComputeEndTick(period_us * kOsTimerTicksPerUs_), ++kOsTimerIdSeed_, repeatable}); + portTimerStart(gOsTimerObj_.begin()->end_tick); + if (id) *id = kOsTimerIdSeed_; + return TASK_OP_SUCCESS; +} + +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; + } + } +} + +static void timerDelayCallback_(int id, void *param) +{ + bool *triggerred = (bool *)param; + // HAL_UartPrint("[TIM]: to %llu\n", portTimerGetTick()); + *triggerred = true; +} + +int OsTimerDelayUs(uint64_t delay_us) +{ + bool timerTriggered = false; + // HAL_UartPrint("[TIM]: from %llu - %lluUs\n", portTimerGetTick(), 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; +} diff --git a/os-timer.h b/os-timer.h new file mode 100644 index 0000000..f802592 --- /dev/null +++ b/os-timer.h @@ -0,0 +1,47 @@ +#ifndef _OS_TIMER_H_ +#define _OS_TIMER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + typedef void (*OsTimerCallback_t)(int id, void *param); + /*****************************************************************************\ + * @description : Initialize the OsTimer module. + * @return {*} + \*****************************************************************************/ + void OsTimerInit(); + + /*****************************************************************************\ + * @description : Register a timer + * ------------ + * @callback [I]: timer triggered callback function. + * @param [I]: input parameter for callback function. + * @period_us [I]: micro second delay to trigger the timer. + * @repeatable [I]: true=auto reload period_us. + * @id [O]: output the timer id for Kill. (Will be auto killed after + * triggered, if not repeatable timer) + * @return error or success + \*****************************************************************************/ + int OsTimerRegister(OsTimerCallback_t callback, void *param, uint64_t period_us, bool repeatable, int *id); + + /*****************************************************************************\ + * @description : return number of active timer + * @return number of active timer + \*****************************************************************************/ + int OsTimerCount(); + + /*****************************************************************************\ + * @description : Kill a timer + * @id [I]: timer id, which given by OsTimerRegister(...,&id) + * @return error or success + \*****************************************************************************/ + int OsTimerKill(int id); + + int OsTimerDelayUs(uint64_t delay_us); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pt-os.h b/pt-os.h index 8cef01b..a053e2a 100644 --- a/pt-os.h +++ b/pt-os.h @@ -3,6 +3,7 @@ #include #include "pt-osConfig.h" +#include "os-timer.h" #define TASK_BEGIN(id) PT_BEGIN(id) #define TASK_YIELD(id) PT_YIELD(id) diff --git a/tests/main.cpp b/tests/main.cpp index cf34ca5..b5d23fa 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -18,6 +18,7 @@ int Test2p1c(); int Test1p2c(); int TestResume(); int TestSubfunction(); +int TestTimer(); int main() { @@ -27,5 +28,7 @@ int main() rc += Test2p1c(); rc += TestResume(); rc += TestSubfunction(); + rc += TestTimer(); + return rc; } \ No newline at end of file diff --git a/tests/timer.cpp b/tests/timer.cpp new file mode 100644 index 0000000..3f6e2fd --- /dev/null +++ b/tests/timer.cpp @@ -0,0 +1,125 @@ +#include +#include + +constexpr int kMaxTestNum_ = 10; +volatile int testCount = 0; +uint64_t tickStart; +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}; + +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++; +} + +constexpr long kTimerTaskSeconds_ = 3; +long tCount1Ms = 0; +long tCount100Us = 0; +long tCountIdle = 0; + +static void timerDelayCallback_(int id, void *param) +{ + bool *triggerred = (bool *)param; + // OS_TRACE("[TIM]: to %llu\n", portTimerGetTick()); + *triggerred = true; +} + +PT_THREAD(testTimerThread1Ms_(OsTaskId taskId, void *param)) +{ + static bool timerTriggered; + TASK_BEGIN(taskId); + while (1) + { + OsTimerDelayUs(1000); + TASK_YIELD(taskId); // force Yield + tCount1Ms++; + // OS_TRACE("1Ms hit %ld, idleYield %ld\n", tCount1Ms, tCountIdle); + } + TASK_END(taskId); +} + +PT_THREAD(testTimerThread100Us_(OsTaskId taskId, void *param)) +{ + static bool timerTriggered; + TASK_BEGIN(taskId); + while (1) + { + OsTimerDelayUs(100); + TASK_YIELD(taskId); // force Yield + tCount100Us++; + // OS_TRACE("100Us hit %ld, idleYield %ld\n", tCount100Us, tCountIdle); + } + TASK_END(taskId); +} + +PT_THREAD(testIdleThread_(OsTaskId taskId, void *param)) +{ + TASK_BEGIN(taskId); + while (1) + { + tCountIdle++; + TASK_YIELD(taskId); // force Yield + } + TASK_END(taskId); +} + +int TestTimer() +{ + int repeat_timer_id; + OsInit(); + OsTimerInit(); + + 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)); + + while (testCount < kMaxTestNum_) TaskYield(); + for (int i = 0; i < kMaxTestNum_; i++) + { + if (testTimerParam[i] != testTimerGolden[i] || testTickCounter[i] / 10 != testTickGolden[i] / 10) + { + OS_TRACE("Test%d Failed\n", i); + OS_TRACE("Timer [%lld : %lld]. Tick [%llu : %llu]\n", testTimerParam[i], testTimerGolden[i], + testTickCounter[i], testTickGolden[i]); + return 1; + } + } + if (OsTimerCount() != 1) + { + OS_TRACE("Timer count error 1 - %d\n", OsTimerCount()); + return 2; + } + LT_ASSERT(OsTimerKill(repeat_timer_id) == kLtSc); + 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("thrIdle", &testIdleThread_, nullptr); + OS_TRACE("Test Timer start\n"); + while (tCount1Ms < kTimerTaskSeconds_) + { + TaskYield(); + } + if ((tCount1Ms * 10 - tCount100Us) <= 2) + { + OS_TRACE("Timer task error %ld - %ld\n", tCount1Ms, tCount100Us); + return 4; + } + OS_TRACE("Idle task yield %ld\n", tCountIdle); + + OS_TRACE("Test Passed\n"); + return 0; +} From f0e42a781865388802cbf8ab5862c0762c40ffb1 Mon Sep 17 00:00:00 2001 From: tzhu Date: Sat, 16 Mar 2024 12:41:46 +0800 Subject: [PATCH 2/6] add os-timer with etl --- CMakeLists.txt | 9 +++++++++ etl/CMakeLists.txt | 9 +++++++++ os-timer.cpp | 1 + 3 files changed, 19 insertions(+) create mode 100644 etl/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 03cc6e2..e4c9eb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,19 @@ cmake_minimum_required(VERSION 3.16) add_subdirectory("protothreads") +add_subdirectory("etl") # cd ./build && make test enable_testing() +if (DEBUG) + SET(CMAKE_BUILD_TYPE "Debug") + message(STATUS "Build with debug mode") +else() + SET(CMAKE_BUILD_TYPE "Release") + message(STATUS "Build with release mode as default") +endif() + set( LIB_NAME pt_os_lib ) file( GLOB SRCS diff --git a/etl/CMakeLists.txt b/etl/CMakeLists.txt new file mode 100644 index 0000000..ab0c722 --- /dev/null +++ b/etl/CMakeLists.txt @@ -0,0 +1,9 @@ +include(FetchContent) + +fetchcontent_declare( + etl + GIT_REPOSITORY https://github.com/ETLCPP/etl.git + GIT_TAG 20.38.10 +) + +FetchContent_MakeAvailable(etl) diff --git a/os-timer.cpp b/os-timer.cpp index f2205ab..c098f76 100644 --- a/os-timer.cpp +++ b/os-timer.cpp @@ -1,6 +1,7 @@ #include "os_timer.h" #include "pt-os.h" #include "os_timer_port.h" +#include constexpr int kMaxTimerItem = 16; From 79d59a59934f7e2bb63da5a0283673e5c2c7898c Mon Sep 17 00:00:00 2001 From: ZhuLingQing Date: Sat, 16 Mar 2024 20:36:46 +0800 Subject: [PATCH 3/6] porting linux --- .gitignore | 2 ++ CMakeLists.txt | 2 +- bash_build.sh | 10 +++++-- os-timer-port.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++ os-timer-port.h | 18 ++++++++++-- os-timer.cpp | 23 +++++++-------- os-timer.h | 3 ++ pt-os.h | 1 + pt-osConfig.h | 2 ++ tests/timer.cpp | 74 +++++++++++++++++++++++++---------------------- 10 files changed, 148 insertions(+), 54 deletions(-) create mode 100644 os-timer-port.cpp diff --git a/.gitignore b/.gitignore index 567609b..8341083 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ build/ +.vscode/ +*.bak \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e4c9eb9..4a625b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 ) diff --git a/bash_build.sh b/bash_build.sh index 4429194..bc1141b 100644 --- a/bash_build.sh +++ b/bash_build.sh @@ -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 diff --git a/os-timer-port.cpp b/os-timer-port.cpp new file mode 100644 index 0000000..e5fb408 --- /dev/null +++ b/os-timer-port.cpp @@ -0,0 +1,67 @@ +#include "os-timer-port.h" +#include "os-timer.h" +#include "pt-os.h" +#include + +#if __linux__ + +#include +#include +#include + +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 \ No newline at end of file diff --git a/os-timer-port.h b/os-timer-port.h index 47a0130..c8c54a8 100644 --- a/os-timer-port.h +++ b/os-timer-port.h @@ -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" @@ -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 diff --git a/os-timer.cpp b/os-timer.cpp index c098f76..be712c5 100644 --- a/os-timer.cpp +++ b/os-timer.cpp @@ -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 constexpr int kMaxTimerItem = 16; @@ -18,7 +18,6 @@ typedef struct volatile int kOsTimerTrigged_ = 0; int kOsTimerHandled_ = 0; int kOsTimerIdSeed_ = 0; -uint64_t kOsTimerTicksPerUs_ = 0; struct tick_cmp { @@ -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); } @@ -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; @@ -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(); diff --git a/os-timer.h b/os-timer.h index f802592..9ec6335 100644 --- a/os-timer.h +++ b/os-timer.h @@ -1,6 +1,9 @@ #ifndef _OS_TIMER_H_ #define _OS_TIMER_H_ +#include +#include + #ifdef __cplusplus extern "C" { diff --git a/pt-os.h b/pt-os.h index a053e2a..94eaac7 100644 --- a/pt-os.h +++ b/pt-os.h @@ -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 { diff --git a/pt-osConfig.h b/pt-osConfig.h index d1ef6ca..9ae2126 100644 --- a/pt-osConfig.h +++ b/pt-osConfig.h @@ -11,4 +11,6 @@ #include #define OS_ASSERT assert +#define OS_PRINT printf + #endif diff --git a/tests/timer.cpp b/tests/timer.cpp index 3f6e2fd..7085044 100644 --- a/tests/timer.cpp +++ b/tests/timer.cpp @@ -1,58 +1,59 @@ -#include +#include "os_test.h" #include +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); } @@ -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; } } @@ -97,7 +101,7 @@ 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()); @@ -105,17 +109,17 @@ int TestTimer() } 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); From 8f7729897c1bfce5d202483d262b721ad82d82d2 Mon Sep 17 00:00:00 2001 From: ZhuLingQing Date: Sun, 17 Mar 2024 11:21:55 +0800 Subject: [PATCH 4/6] port os-timer to linux --- os-timer.cpp | 1 + os-timer-port.cpp => tests/os-timer-port.cpp | 15 +++---- tests/timer.cpp | 44 +++++++++++--------- 3 files changed, 31 insertions(+), 29 deletions(-) rename os-timer-port.cpp => tests/os-timer-port.cpp (77%) diff --git a/os-timer.cpp b/os-timer.cpp index be712c5..b0ff83e 100644 --- a/os-timer.cpp +++ b/os-timer.cpp @@ -60,6 +60,7 @@ TASK_DECLARE(OsTimerTask_(OsTaskId taskId, void *)) void OsTimerInit() { + gOsTimerObj_.clear(); portTimerInit(OsTimerIsrHandler_); portTimerStop(); RegisterTask("thrTmr", OsTimerTask_, nullptr); diff --git a/os-timer-port.cpp b/tests/os-timer-port.cpp similarity index 77% rename from os-timer-port.cpp rename to tests/os-timer-port.cpp index e5fb408..2f125d4 100644 --- a/os-timer-port.cpp +++ b/tests/os-timer-port.cpp @@ -53,15 +53,12 @@ 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_(); + if (offset < 10) offset = 100; + 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); } #endif \ No newline at end of file diff --git a/tests/timer.cpp b/tests/timer.cpp index 7085044..adf3588 100644 --- a/tests/timer.cpp +++ b/tests/timer.cpp @@ -1,14 +1,14 @@ #include "os_test.h" #include -constexpr long testTimerGain_ = 10000; +constexpr long testTimerGain_ = 1000; constexpr int kMaxTestNum_ = 10; 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}; +constexpr long testTimerGolden[kMaxTestNum_] = {11, 33, 50, 51, 33, 33, 99, 33, 33, 33}; static uint64_t testUsCounter[kMaxTestNum_]; -constexpr uint64_t testUsGolden[kMaxTestNum_] = {100, 300, 500, 500, 600, 900, 900, 1200, 1500, 1800}; +constexpr uint64_t testUsGolden[kMaxTestNum_] = {100, 300, 500, 500, 600, 900, 1000, 1200, 1500, 1800}; void testTimerCallback_(int id, void *param) { @@ -19,8 +19,8 @@ void testTimerCallback_(int id, void *param) } constexpr long kTimerTaskSeconds_ = 3; -long tCount1s = 0; -long tCount100Ms = 0; +long tCount10t = 0; +long tCount1t = 0; long tCountIdle = 0; static void timerDelayCallback_(int id, void *param) @@ -30,30 +30,30 @@ static void timerDelayCallback_(int id, void *param) *triggerred = true; } -PT_THREAD(testTimerThread1s_(OsTaskId taskId, void *param)) +PT_THREAD(testTimerThread10t_(OsTaskId taskId, void *param)) { static bool timerTriggered; TASK_BEGIN(taskId); while (1) { - OsTimerDelayUs(1000 * 1000); + OsTimerDelayUs(100 * testTimerGain_); TASK_YIELD(taskId); // force Yield - tCount1s++; - // OS_TRACE("1s hit %ld, idleYield %ld\n", tCount1s, tCountIdle); + tCount10t++; + // OS_TRACE("10t hit %ld, idleYield %ld\n", tCount10t, tCountIdle); } TASK_END(taskId); } -PT_THREAD(testTimerThread100Ms_(OsTaskId taskId, void *param)) +PT_THREAD(testTimerThread1t_(OsTaskId taskId, void *param)) { static bool timerTriggered; TASK_BEGIN(taskId); while (1) { - OsTimerDelayUs(100 * 1000); + OsTimerDelayUs(10 * testTimerGain_); TASK_YIELD(taskId); // force Yield - tCount100Ms++; - // OS_TRACE("100Ms hit %ld, idleYield %ld\n", tCount100Ms, tCountIdle); + tCount1t++; + // OS_TRACE("1t hit %ld, idleYield %ld\n", tCount1t, tCountIdle); } TASK_END(taskId); } @@ -75,12 +75,16 @@ int TestTimer() OS_TRACE("======== %s ========\n", __FUNCTION__); OsInit(); OsTimerInit(); + kSignalTriggered_ = 0; + tCount10t = 0; + tCount1t = 0; + tCountIdle = 0; kStartUs_ = portTimerGetUs(); OS_TRACE("Timer Init\n", __FUNCTION__); 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 *)(99), 1000 * testTimerGain_, false, nullptr); OsTimerRegister(testTimerCallback_, (void *)(33), 300 * testTimerGain_, true, &repeat_timer_id); OsTimerRegister(testTimerCallback_, (void *)(51), 500 * testTimerGain_, false, nullptr); @@ -88,7 +92,7 @@ int TestTimer() while (kSignalTriggered_ < kMaxTestNum_) TaskYield(); for (int i = 0; i < kMaxTestNum_; i++) { - if (testTimerParam[i] != testTimerGolden[i] || testUsCounter[i] / 1000 != testUsGolden[i] * testTimerGain_ / 1000) + if (testTimerParam[i] != testTimerGolden[i] || testUsCounter[i] / 200 != testUsGolden[i] * testTimerGain_ / 200) { OS_TRACE("Test%d Failed\n", i); OS_TRACE("Timer [%lld : %lld]. Tick [%llu : %llu]\n", testTimerParam[i], testTimerGolden[i], @@ -109,17 +113,17 @@ int TestTimer() } OS_TRACE("Test Timer in task\n"); - RegisterTask("thr1s", &testTimerThread1s_, nullptr); - RegisterTask("thr100Ms", &testTimerThread100Ms_, nullptr); + RegisterTask("thr10t", &testTimerThread10t_, nullptr); + RegisterTask("thr1t", &testTimerThread1t_, nullptr); RegisterTask("thrIdle", &testIdleThread_, nullptr); OS_TRACE("Test Timer start\n"); - while (tCount1s < kTimerTaskSeconds_) + while (tCount10t < kTimerTaskSeconds_) { TaskYield(); } - if ((tCount1s * 10 - tCount100Ms) <= 2) + if ((tCount10t * 10 - tCount1t) <= 2) { - OS_TRACE("Timer task error %ld - %ld\n", tCount1s, tCount100Ms); + OS_TRACE("Timer task error %ld - %ld\n", tCount10t, tCount1t); return 4; } OS_TRACE("Idle task yield %ld\n", tCountIdle); From 8b02c073ccae0ceb8b1c12a3e65361bab3566151 Mon Sep 17 00:00:00 2001 From: ZhuLingQing Date: Sun, 17 Mar 2024 11:27:32 +0800 Subject: [PATCH 5/6] update c-cpp.yml with cmake --- .github/workflows/c-cpp.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index ca9f893..06621db 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -12,12 +12,21 @@ jobs: - uses: actions/checkout@v1 - name: check the environment run: g++ --version && git --version && bash --version - - name: list the environment - run: ls -la - - name: build with bash - run: bash bash_build.sh - - name: run tests + run: cmake --version + - name: make the project run: | + mkdir build pushd build - ./test_pt_os + cmake .. + make popd + - name: test + run: | + pushd build + make test + popd + - name: test with bash + run: | + ./build/tests/test_pt_os + echo "DONE + " From d28f765884532647c3dca8d7fb52be4a8dd1070c Mon Sep 17 00:00:00 2001 From: ZhuLingQing Date: Sun, 17 Mar 2024 11:30:24 +0800 Subject: [PATCH 6/6] debug c-cppy.yml --- .github/workflows/c-cpp.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 06621db..fc3b347 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -11,8 +11,10 @@ jobs: steps: - uses: actions/checkout@v1 - name: check the environment - run: g++ --version && git --version && bash --version - run: cmake --version + run: | + g++ --version + git --version + cmake --version - name: make the project run: | mkdir build