Skip to content

Commit

Permalink
1st release version
Browse files Browse the repository at this point in the history
  • Loading branch information
tzhu committed Mar 14, 2024
0 parents commit 72a5691
Show file tree
Hide file tree
Showing 14 changed files with 812 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./build
23 changes: 23 additions & 0 deletions CMakeLists.txt
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" )
9 changes: 9 additions & 0 deletions protothreads/CMakeLists.txt
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)
206 changes: 206 additions & 0 deletions pt-os.cpp
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();
}
63 changes: 63 additions & 0 deletions pt-os.h
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
11 changes: 11 additions & 0 deletions pt-osConfig.h
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
Loading

0 comments on commit 72a5691

Please sign in to comment.