-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
tzhu
committed
Mar 14, 2024
0 parents
commit 72a5691
Showing
14 changed files
with
812 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
./build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
cmake_minimum_required(VERSION 3.26) | ||
|
||
add_subdirectory("protothreads") | ||
|
||
# cd ./build && make test | ||
enable_testing() | ||
|
||
set( LIB_NAME pt_os_lib ) | ||
|
||
file( GLOB SRCS | ||
"*.cpp") | ||
|
||
add_library(${LIB_NAME} STATIC ${SRCS}) | ||
|
||
include_directories(${PROJECT_SOURCE_DIR}) | ||
|
||
target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) | ||
|
||
target_link_libraries(${LIB_NAME} protothreads) | ||
|
||
set( OS_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE ) | ||
|
||
add_subdirectory( "./tests" ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
include(FetchContent) | ||
|
||
fetchcontent_declare( | ||
pt | ||
GIT_REPOSITORY https://github.com/ZhuLingQing/protothreads.git | ||
GIT_TAG main | ||
) | ||
|
||
FetchContent_MakeAvailable(pt) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
#include "pt-os.h" | ||
#include <string.h> | ||
|
||
static inline size_t min_(size_t a, size_t b) { return a < b ? a : b; } | ||
|
||
#define OsTaskId2Idx(id) (int)(id - kPt_) | ||
|
||
class TaskControlBlock | ||
{ | ||
public: | ||
TaskControlBlock() { Reset(); } | ||
|
||
void Reset() | ||
{ | ||
#if defined(osMaxNameLen) && osMaxNameLen > 0 | ||
memset(kName_, 0, sizeof(kName_)); | ||
#endif | ||
kTask_ = nullptr; | ||
kPtStatus_ = OsTaskNotExist; | ||
} | ||
|
||
void Register(const char *name, TaskFunction task, void *param) | ||
{ | ||
#if defined(osMaxNameLen) && osMaxNameLen > 0 | ||
memcpy(kName_, name, min_(sizeof(kName_) - 1, strlen(name))); | ||
#endif | ||
kTask_ = task; | ||
kParam_ = param; | ||
kEntered_ = false; | ||
kPtStatus_ = OsTaskWaiting; | ||
} | ||
|
||
bool Yield(OsTaskId taskId) | ||
{ | ||
if (kPtStatus_ == OsTaskExit) return false; | ||
if (!kEntered_ && kPtStatus_ != OsTaskSuspend) | ||
{ | ||
kEntered_ = true; | ||
kPtStatus_ = (OsTaskStatus)kTask_(taskId, kParam_); | ||
kEntered_ = false; | ||
} | ||
return (kPtStatus_ == OsTaskExit)?true:false; | ||
} | ||
|
||
OsTaskStatus Status() { return kPtStatus_; } | ||
int Suspend() | ||
{ | ||
if (kPtStatus_ == OsTaskNotExist) return INVALID_TASK_ID; | ||
if (kPtStatus_ == OsTaskExit) return INVALID_TASK_STATUS; | ||
kPtStatus_ = OsTaskSuspend; | ||
return TASK_OP_SUCCESS; | ||
} | ||
int Resume() | ||
{ | ||
if (kPtStatus_ == OsTaskNotExist) return INVALID_TASK_ID; | ||
if (kPtStatus_ == OsTaskExit) return INVALID_TASK_STATUS; | ||
kPtStatus_ = OsTaskWaiting; | ||
return TASK_OP_SUCCESS; | ||
} | ||
|
||
int Delete() | ||
{ | ||
if (kPtStatus_ == OsTaskNotExist) return INVALID_TASK_ID; | ||
if (kPtStatus_ == OsTaskExit) return INVALID_TASK_STATUS; | ||
kPtStatus_ = OsTaskExit; | ||
return TASK_OP_SUCCESS; | ||
} | ||
|
||
const char *Name() | ||
{ | ||
#if defined(osMaxNameLen) && osMaxNameLen > 0 | ||
return kName_; | ||
#else | ||
return nullptr; | ||
#endif | ||
} | ||
|
||
protected: | ||
TaskFunction kTask_; | ||
#if defined(osMaxNameLen) && osMaxNameLen > 0 | ||
char kName_[osMaxNameLen]; | ||
#endif | ||
void *kParam_; | ||
bool kEntered_; | ||
OsTaskStatus kPtStatus_; | ||
}; | ||
|
||
class PtOs | ||
{ | ||
public: | ||
PtOs() { Reset(); } | ||
|
||
OsTaskId RegisterTask(const char *name, TaskFunction task, void *param) | ||
{ | ||
if (kIdx_ >= osMaxThreads) return OsInvlidTaskId; | ||
kTaskCb_[kIdx_].Register(name, task, param); | ||
kIdx_++; | ||
kNumLiveTasks_++; | ||
PT_INIT(&kPt_[kIdx_ - 1]); | ||
return &kPt_[kIdx_ - 1]; | ||
} | ||
|
||
void Yield() | ||
{ | ||
for (int i = 0; i < kIdx_; i++) | ||
{ | ||
if (true == kTaskCb_[i].Yield(kPt_ + i)) kNumLiveTasks_--; | ||
} | ||
} | ||
|
||
const char *Name(OsTaskId taskId) | ||
{ | ||
OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); | ||
return kTaskCb_[OsTaskId2Idx(taskId)].Name(); | ||
} | ||
|
||
int Delete(OsTaskId taskId) | ||
{ | ||
OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); | ||
auto rc = kTaskCb_[OsTaskId2Idx(taskId)].Delete(); | ||
if (rc == TASK_OP_SUCCESS) kNumLiveTasks_--; | ||
return rc; | ||
} | ||
|
||
int Suspend(OsTaskId taskId) | ||
{ | ||
OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); | ||
return kTaskCb_[OsTaskId2Idx(taskId)].Suspend(); | ||
} | ||
|
||
int Resume(OsTaskId taskId) | ||
{ | ||
OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); | ||
return kTaskCb_[OsTaskId2Idx(taskId)].Resume(); | ||
} | ||
|
||
OsTaskStatus Status(OsTaskId taskId) | ||
{ | ||
OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); | ||
return kTaskCb_[OsTaskId2Idx(taskId)].Status(); | ||
} | ||
|
||
int NumLiveTasks() { return kNumLiveTasks_; } | ||
|
||
void Reset() | ||
{ | ||
for (int i = 0; i < osMaxThreads; i++) | ||
kTaskCb_[i].Reset(); | ||
kIdx_ = 0; | ||
kNumLiveTasks_ = 0; | ||
} | ||
|
||
protected: | ||
TaskControlBlock kTaskCb_[osMaxThreads]; | ||
struct pt kPt_[osMaxThreads]; | ||
int kIdx_; | ||
int kNumLiveTasks_; | ||
}; | ||
|
||
static PtOs sOsControlBlock_; | ||
|
||
OsTaskId RegisterTask(const char *name, TaskFunction task, void *param) { return sOsControlBlock_.RegisterTask(name, task, param); } | ||
|
||
// Cause Registered Service get scheduled | ||
void TaskYield(void) | ||
{ | ||
sOsControlBlock_.Yield(); | ||
} | ||
|
||
const char *TaskName(OsTaskId taskId) | ||
{ | ||
return sOsControlBlock_.Name(taskId); | ||
} | ||
|
||
int TaskDelete(OsTaskId taskId) | ||
{ | ||
return sOsControlBlock_.Delete(taskId); | ||
} | ||
|
||
int TaskSuspend(OsTaskId taskId) | ||
{ | ||
return sOsControlBlock_.Suspend(taskId); | ||
} | ||
|
||
int TaskResume(OsTaskId taskId) | ||
{ | ||
return sOsControlBlock_.Resume(taskId); | ||
} | ||
|
||
OsTaskStatus TaskStatus(OsTaskId taskId) | ||
{ | ||
return sOsControlBlock_.Status(taskId); | ||
} | ||
|
||
void OsInit(void) | ||
{ | ||
//make sure | ||
OS_ASSERT(0 == sOsControlBlock_.NumLiveTasks()); | ||
sOsControlBlock_.Reset(); | ||
} | ||
|
||
void OsStart(void) | ||
{ | ||
while (sOsControlBlock_.NumLiveTasks() > 0) | ||
sOsControlBlock_.Yield(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#ifndef _PT_OS_H_ | ||
#define _PT_OS_H_ | ||
|
||
#include "pt-osConfig.h" | ||
#include <pt.h> | ||
|
||
#define TASK_BEGIN(id) PT_BEGIN(id) | ||
#define TASK_YIELD(id) PT_YIELD(id) | ||
#define TASK_WAIT_UNTIL(id,cond) PT_WAIT_UNTIL(id, cond) | ||
#define TASK_SUSPEND(id) do { if (taskId == id) PT_EXIT(id); else TaskSuspend(id); } while(0) | ||
#define TASK_DELETE(id) do { if (taskId == id) PT_END(id); else TaskDelete(id); } while(0) | ||
#define TASK_EXIT(id) return PT_ENDED | ||
#define TASK_END(id) PT_END(id) | ||
#define TASK_DECLARE(thread_declare) PT_THREAD(thread_declare) | ||
|
||
#if __cplusplus | ||
extern "C" | ||
{ | ||
#endif | ||
typedef struct pt * OsTaskId; | ||
#define OsInvlidTaskId ((OsTaskId)INVALID_TASK_ID) | ||
|
||
#define TASK_OP_SUCCESS (0) | ||
#define INVALID_TASK_ID (-1) | ||
#define INVALID_TASK_STATUS (-2) | ||
|
||
typedef enum | ||
{ | ||
OsTaskWaiting = PT_WAITING, | ||
OsTaskYield = PT_YIELDED, | ||
OsTaskSuspend = PT_EXITED, | ||
OsTaskExit = PT_ENDED, | ||
OsTaskNotExist = -1, | ||
}OsTaskStatus; | ||
|
||
typedef char (*TaskFunction)(OsTaskId, void *); | ||
|
||
OsTaskId RegisterTask(const char *name, TaskFunction task, void *param); | ||
|
||
// Cause Registered Service get scheduled | ||
void TaskYield(void); | ||
|
||
const char *TaskName(OsTaskId taskId); | ||
|
||
// Call TASK_DELETE, it will identify this task or not. | ||
int TaskDelete(OsTaskId taskId); | ||
|
||
// Call TASK_SUSPEND, it will identify this task or not. | ||
int TaskSuspend(OsTaskId taskId); | ||
|
||
int TaskResume(OsTaskId taskId); | ||
|
||
OsTaskStatus TaskStatus(OsTaskId taskId); | ||
|
||
void OsInit(void); | ||
|
||
void OsStart(void); | ||
|
||
#if __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef _OS_CONFIG_H_ | ||
#define _OS_CONFIG_H_ | ||
|
||
|
||
#define osMaxNameLen (16) | ||
#define osMaxThreads (64) | ||
|
||
#include <cassert> | ||
#define OS_ASSERT assert | ||
|
||
#endif |
Oops, something went wrong.