This commit is contained in:
2026-05-19 11:49:22 +08:00
commit add7af4222
96 changed files with 8635 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
#include "cpu_clz.h"
#include "os_config.h"
#if !defined(OS_CFG_CPU_CLZ_ASM_PRESENT) || (!OS_CFG_CPU_CLZ_ASM_PRESENT)
// 如果配置中没有提供汇编版本的clz函数,则使用C语言实现
static const uint8_t clz_table[256] = {/* 索引 */
8u,7u,6u,6u,5u,5u,5u,5u,4u,4u,4u,4u,4u,4u,4u,4u, /* 0x00 to 0x0F */
3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u,3u, /* 0x10 to 0x1F */
2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u, /* 0x20 to 0x2F */
2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u,2u, /* 0x30 to 0x3F */
1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u, /* 0x40 to 0x4F */
1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u, /* 0x50 to 0x5F */
1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u, /* 0x60 to 0x6F */
1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u,1u, /* 0x70 to 0x7F */
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0x80 to 0x8F */
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0x90 to 0x9F */
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xA0 to 0xAF */
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xB0 to 0xBF */
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xC0 to 0xCF */
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xD0 to 0xDF */
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u, /* 0xE0 to 0xEF */
0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u /* 0xF0 to 0xFF */
};
os_uint_t cpu_clz(os_uint_t value){
os_uint_t result = 0;
uint8_t idx;
// 检查高 16 bits
if(value > 0x0000FFFFu){
// 检查 bits[24:31]
if(value > 0x00FFFFFFu){
idx = (value >> 24u) & 0xFFu; // 获取 bits[24:31] 的值
result = clz_table[idx]; // 查表获取 bits[24:31] 中前导零的数量
}else{
idx = (value >> 16u) & 0xFFu; // 获取 bits[16:23] 的值
result = clz_table[idx] + 8u; // 查表获取 bits[16:23] 中前导零的数量,并加上8,表示 bits[24:31] 中的0
}
}else{
// 检查 bits[0:15]
if(value > 0x000000FFu){
idx = (value >> 8u) & 0xFFu; // 获取 bits[8:15] 的值
result = clz_table[idx] + 16u; // 查表获取 bits[8:15] 中前导零的数量,并加上16,表示 bits[16:31] 中的0
}else{
idx = value & 0xFFu; // 获取 bits[0:7] 的值
result = clz_table[idx] + 24u; // 查表获取 bits[0:7] 中前导零的数量,并加上24,表示 bits[8:31] 中的0
}
}
return result;
}
#endif /* OS_CFG_CLZ_ASM_PRESENT */
+11
View File
@@ -0,0 +1,11 @@
#ifndef INCLUDED_CPU_CLZ_H
#define INCLUDED_CPU_CLZ_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
os_uint_t cpu_clz(os_uint_t value); // 计算一个无符号整数中前导零的数量,即从最高位开始连续的0的个数,直到遇到第一个1为止。返回值范围为0-32,如果输入值为0,则返回32。
#endif /* INCLUDED_CPU_CLZ_H */
+42
View File
@@ -0,0 +1,42 @@
#include "os.h"
#include "os_port.h"
#include "os_rdy_list.h"
#include "os_systick.h"
#include "os_sched.h"
#include "os_yield_list.h"
#include "os_idle.h"
#include "os_timewheel.h"
#include "os_isr.h"
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
void os_init(void){
g_os_systick_ticks = 0;
g_os_port_switch_from_sp = 0;
g_os_port_switch_to_sp = 0;
g_os_port_context_switch_flag = OS_FALSE;
g_os_isr_nesting_cnt = 0;
os_priority_init();
os_rdy_list_init();
os_yield_list_init();
os_timewheel_init();
os_sched_init();
os_port_init();
os_idle_init();
}
void os_startup(void){
os_critical_enter();
os_priority_t priority = os_priority_get_highest();
os_rdy_list_t* p_rdy_list = os_rdy_list_get(priority);
os_list_node_t* p_node = p_rdy_list->head.next;
os_task_t* p_next_task = os_list_member_of(p_node, os_task_t, node);
os_rdy_list_remove((os_task_t*)p_next_task);
os_critical_leave();
os_port_startup();
os_port_context_switch(0, &p_next_task->stack.sp);
}
+71
View File
@@ -0,0 +1,71 @@
#ifndef INCLUDED_OS_H
#define INCLUDED_OS_H
#ifndef INCLUDED_OS_TYPES_H
#include "os_types.h"
#endif /* INCLUDED_OS_TYPES_H */
#ifndef INCLUDED_OS_COMPILER_H
#include "os_compiler.h"
#endif /* INCLUDED_OS_COMPILER_H */
#ifndef INCLUDED_OS_MACROS_H
#include "os_macros.h"
#endif /* INCLUDED_OS_MACROS_H */
#ifndef INCLUDED_OS_SCHED_H
#include <os_sched.h>
#endif /*INCLUDED_OS_SCHED_H*/
#ifndef INCLUDED_OS_TASK_H
#include <os_task.h>
#endif /*INCLUDED_OS_TASK_H*/
#ifndef INCLUDED_OS_PORT_H
#include <os_port.h>
#endif /*INCLUDED_OS_PORT_H*/
#ifndef INCLUDED_OS_CRITICAL_H
#include "os_critical.h"
#endif /* INCLUDED_OS_CRITICAL_H */
#ifndef INCLUDED_OS_SYSTICK_H
#include <os_systick.h>
#endif /*INCLUDED_OS_SYSTICK_H*/
#ifndef INCLUDED_OS_SEM_H
#include <os_sem.h>
#endif /*INCLUDED_OS_SEM_H*/
#ifndef INCLUDED_OS_MUTEX_H
#include <os_mutex.h>
#endif /*INCLUDED_OS_MUTEX_H*/
#ifndef INCLUDED_OS_CONDV_H
#include <os_condv.h>
#endif /*INCLUDED_OS_CONDV_H*/
#ifndef INCLUDED_OS_ISR_H
#include <os_isr.h>
#endif /*INCLUDED_OS_ISR_H*/
#ifndef INCLUDED_OS_COUNTDOWNLATCH_H
#include <os_countdownlatch.h>
#endif /*INCLUDED_OS_COUNTDOWNLATCH_H*/
#ifndef INCLUDED_OS_FAIRLOCK_H
#include <os_fairlock.h>
#endif /*INCLUDED_OS_FAIRLOCK_H*/
/* ==================================================================================================== */
/* Methods */
void os_init(void);
void os_startup(void);
#endif /* INCLUDED_OS_H */
+179
View File
@@ -0,0 +1,179 @@
#include <os_condv.h>
#include "os_critical.h"
#include "os_rdy_list.h"
#include "os_sched.h"
#include "os_timewheel.h"
void os_condv_init(os_condv_t* self){
os_list_init(&self->wait_list);
}
void os_condv_destroy(os_condv_t* self){
OS_ASSERT(os_list_is_empty(&self->wait_list));
}
void os_condv_wait(os_condv_t* self, os_mutex_t* lock){
os_mutex_unlock(lock);
os_critical_enter();
os_task_t* p_thread = os_task_self();
os_list_insert_before(&self->wait_list, &p_thread->node);
p_thread->state = kOsTaskState_Wait;
os_critical_leave();
os_sched();
os_mutex_lock(lock);
}
void os_condv_notify_one(os_condv_t* self){
os_critical_enter();
if(os_list_is_empty(&self->wait_list)){
os_critical_leave();
return;
}
os_list_node_t* p = self->wait_list.next;
os_task_t* thread = os_list_member_of(p, os_task_t, node);
os_list_remove(&thread->node);
os_rdy_list_insert(thread);
os_critical_leave();
os_sched();
}
void os_condv_notify_all(os_condv_t* self){
os_critical_enter();
for(os_list_node_t* p = self->wait_list.next; p!=&self->wait_list; ){
os_task_t* thread = os_list_member_of(p, os_task_t, node);
p = p->next;
os_list_remove(&thread->node);
os_rdy_list_insert(thread);
}
os_critical_leave();
os_sched();
}
static void os_condv_ontimeout(os_timer_t* p_timer){
os_task_t* p_thread = os_list_member_of(p_timer, os_task_t, timer);
os_list_remove(&p_thread->node); // 从 WAIT 列表中移除
p_thread->errors = OS_ERR_TIMEOUT; // 标记超时了
os_rdy_list_insert(p_thread); // 加入就绪表
}
os_err_t os_condv_timed_wait(os_condv_t* self, os_mutex_t* lock, os_tick_t ticks){
os_err_t err = OS_ERR_OK;
os_mutex_unlock(lock);
{
os_critical_enter();
os_task_t* p_thread = os_task_self();
os_list_insert_before(&self->wait_list, &p_thread->node);
p_thread->state = kOsTaskState_Wait;
if(ticks==0){
// TIMEOUT
p_thread->errors = OS_ERR_TIMEOUT;
os_critical_leave();
os_mutex_lock(lock);
return OS_ERR_TIMEOUT;
}else if(ticks!=OS_WAIT_INFINITY){
// 定时
p_thread->errors = OS_ERR_OK;
os_timewheel_add_timer((os_timer_t*)&p_thread->timer, os_condv_ontimeout, 0, ticks, OS_TIMER_FLAG_ONCE);
}
os_critical_leave();
}
os_sched();
{
// 返回当前线程
os_critical_enter();
os_task_t* p_task = os_task_self();
err = p_task->errors;
if(err!=OS_ERR_OK){
p_task->errors = OS_ERR_OK;
os_critical_leave();
os_mutex_lock(lock);
return err;
}
os_critical_leave();
}
os_mutex_lock(lock);
return err;
}
os_err_t os_condv_wait_until(os_condv_t* self, os_mutex_t* lock, os_tick_t ticks){
os_err_t err = OS_ERR_OK;
os_mutex_unlock(lock);
{
os_critical_enter();
os_task_t* p_thread = os_task_self();
os_list_insert_before(&self->wait_list, &p_thread->node);
p_thread->state = kOsTaskState_Wait;
if(ticks==0){
// TIMEOUT
p_thread->errors = OS_ERR_TIMEOUT;
os_critical_leave();
os_mutex_lock(lock);
return OS_ERR_TIMEOUT;
}else if(ticks!=OS_WAIT_INFINITY){
// 定时
p_thread->errors = OS_ERR_OK;
os_timewheel_add_until_timer((os_timer_t*)&p_thread->timer
, os_condv_ontimeout, 0
, ticks, OS_TIMER_FLAG_ONCE);
}
os_critical_leave();
}
os_sched();
{
os_critical_enter();
os_task_t* p_task = os_task_self();
err = p_task->errors;
if(err!=OS_ERR_OK){
p_task->errors = OS_ERR_OK;
os_critical_leave();
os_mutex_lock(lock);
return err;
}
os_critical_leave();
}
os_mutex_lock(lock);
return err;
}
void os_condv_notify_one_in_isr(os_condv_t* self){
os_critical_enter_in_isr();
if(os_list_is_empty(&self->wait_list)){
os_critical_leave();
return;
}
os_list_node_t* p = self->wait_list.next;
os_task_t* thread = os_list_member_of(p, os_task_t, node);
os_list_remove(&thread->node);
os_rdy_list_insert(thread);
// thread->state = OS_TASK_STATE_READY;
os_critical_leave_in_isr();
os_sched_in_isr();
}
void os_condv_notify_all_in_isr(os_condv_t* self){
os_critical_enter_in_isr();
for(os_list_node_t* p = self->wait_list.next; p!=&self->wait_list; ){
os_task_t* thread = os_list_member_of(p, os_task_t, node);
os_list_remove(&thread->node);
p = p->next;
os_rdy_list_insert(thread);
// thread->state = OS_TASK_STATE_READY;
}
os_critical_leave_in_isr();
os_sched_in_isr();
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef INCLUDED_OS_CONDV_H
#define INCLUDED_OS_CONDV_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_MUTEX_H
#include <os_mutex.h>
#endif /*INCLUDED_OS_MUTEX_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct os_condv_t os_condv_t;
struct os_condv_t{
os_list_t wait_list;
};
void os_condv_init(os_condv_t* self);
void os_condv_destroy(os_condv_t* self);
void os_condv_wait(os_condv_t* self, os_mutex_t* lock);
os_err_t os_condv_timed_wait(os_condv_t* self, os_mutex_t* lock, os_tick_t ticks);
os_err_t os_condv_wait_until(os_condv_t* self, os_mutex_t* lock, os_tick_t ticks);
void os_condv_notify_one(os_condv_t* self);
void os_condv_notify_all(os_condv_t* self);
void os_condv_notify_one_in_isr(os_condv_t* self);
void os_condv_notify_all_in_isr(os_condv_t* self);
#endif /*INCLUDED_OS_CONDV_H*/
+37
View File
@@ -0,0 +1,37 @@
#ifndef INCLUDED_OS_CONFIG_H
#define INCLUDED_OS_CONFIG_H
/* ==================================================================================================== */
/* OPTIONS */
#cmakedefine OS_CFG_CPU_INT_NBITS @OS_CFG_CPU_INT_NBITS@
#cmakedefine OS_CFG_TICKS_PER_SECOND @OS_CFG_TICKS_PER_SECOND@
#cmakedefine OS_CFG_SYSCALL_PRIORITY @OS_CFG_SYSCALL_PRIORITY@
#cmakedefine OS_CFG_PRIORITY_MAX @OS_CFG_PRIORITY_MAX@
#cmakedefine OS_CFG_CPU_CLZ_ASM_PRESENT @OS_CFG_CPU_CLZ_ASM_PRESENT@
#cmakedefine OS_CFG_IDLE_TASK_STACK_SIZE @OS_CFG_IDLE_TASK_STACK_SIZE@
#cmakedefine OS_CFG_IDLE_TASK_TICKS @OS_CFG_IDLE_TASK_TICKS@
#cmakedefine OS_CFG_IDLE_TASK_PRIORITY @OS_CFG_IDLE_TASK_PRIORITY@
/* ==================================================================================================== */
/* DEFAULT */
#ifndef OS_CFG_CPU_INT_NBITS
#define OS_CFG_CPU_INT_NBITS 32
#endif /* OS_CFG_CPU_INT_NBITS */
#ifndef OS_CFG_TICKS_PER_SECOND
#define OS_CFG_TICKS_PER_SECOND 1000
#endif /* OS_CFG_TICKS_PER_SECOND */
#ifndef OS_CFG_SYSCALL_PRIORITY
#define OS_CFG_SYSCALL_PRIORITY 0x4
#endif /* OS_CFG_SYSCALL_PRIORITY */
#ifndef OS_CFG_PRIORITY_MAX
#define OS_CFG_PRIORITY_MAX OS_CFG_CPU_INT_NBITS
#endif /* OS_CFG_PRIORITY_MAX */
#endif /*INCLUDED_OS_CONFIG_H*/
+1
View File
@@ -0,0 +1 @@
#include <os_countdownlatch.h>
+85
View File
@@ -0,0 +1,85 @@
#ifndef INCLUDED_OS_COUNTDOWNLATCH_H
#define INCLUDED_OS_COUNTDOWNLATCH_H
#ifndef INCLUDED_OS_MUTEX_H
#include <os_mutex.h>
#endif /*INCLUDED_OS_MUTEX_H*/
#ifndef INCLUDED_OS_CONDV_H
#include <os_condv.h>
#endif /*INCLUDED_OS_CONDV_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct {
os_mutex_t lock;
os_condv_t condv;
os_int_t count;
}os_countdownlatch_t;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void os_countdownlatch_init(os_countdownlatch_t* self, os_int_t cnt){
os_mutex_init(&self->lock);
os_condv_init(&self->condv);
self->count = cnt;
}
OS_STATIC_FORCE_INLINE
void os_countdownlatch_destroy(os_countdownlatch_t* self){
os_condv_destroy(&self->condv);
os_mutex_destroy(&self->lock);
}
OS_STATIC_FORCE_INLINE
void os_countdownlatch_await(os_countdownlatch_t* self){
os_mutex_lock(&self->lock);
while(self->count>0){
os_condv_wait(&self->condv, &self->lock);
}
os_mutex_unlock(&self->lock);
}
OS_STATIC_FORCE_INLINE
os_err_t os_countdownlatch_timed_await(os_countdownlatch_t* self, os_tick_t ticks){
os_err_t err = OS_ERR_OK;
os_mutex_lock(&self->lock);
while(self->count>0){
err = os_condv_timed_wait(&self->condv, &self->lock, ticks);
if(err==OS_ERR_TIMEOUT){
break;
}
}
os_mutex_unlock(&self->lock);
return err;
}
OS_STATIC_FORCE_INLINE
void os_countdownlatch_count_down(os_countdownlatch_t* self){
os_mutex_lock(&self->lock);
if(self->count>0){
self->count--;
if(self->count==0){
os_mutex_unlock(&self->lock);
os_condv_notify_all(&self->condv);
return;
}
}
os_mutex_unlock(&self->lock);
}
OS_STATIC_FORCE_INLINE
os_int_t os_countdownlatch_get_count(os_countdownlatch_t* self){
os_int_t count;
os_mutex_lock(&self->lock);
count = self->count;
os_mutex_unlock(&self->lock);
return count;
}
#endif /*INCLUDED_OS_COUNTDOWNLATCH_H*/
+1
View File
@@ -0,0 +1 @@
#include "os_critical.h"
+15
View File
@@ -0,0 +1,15 @@
#ifndef INCLUDED_OS_CRITICAL_H
#define INCLUDED_OS_CRITICAL_H
#ifndef INCLUDED_OS_PORT_H
#include <os_port.h>
#endif /*INCLUDED_OS_PORT_H*/
#define os_critical_enter() os_uint_t d_os_critical_var = os_port_save_disable_irq()
#define os_critical_leave() os_port_restore_irq(d_os_critical_var)
#define os_critical_enter_in_isr() os_uint_t d_os_critical_var = os_port_save_disable_irq_in_isr()
#define os_critical_leave_in_isr() os_port_restore_irq_in_isr(d_os_critical_var)
#endif /* INCLUDED_OS_CRITICAL_H */
+1
View File
@@ -0,0 +1 @@
#include <os_fairlock.h>
+37
View File
@@ -0,0 +1,37 @@
#ifndef INCLUDED_OS_FAIRLOCK_H
#define INCLUDED_OS_FAIRLOCK_H
#ifndef INCLUDED_OS_MUTEX_H
#include <os_mutex.h>
#endif /*INCLUDED_OS_MUTEX_H*/
typedef struct {
os_mutex_t lock;
}os_fairlock_t;
OS_STATIC_FORCE_INLINE
void os_fairlock_init(os_fairlock_t* self){
os_mutex_init(&self->lock);
}
OS_STATIC_FORCE_INLINE
os_err_t os_fairlock_trylock(os_fairlock_t* self){
return os_mutex_trylock(&self->lock);
}
OS_STATIC_FORCE_INLINE
void os_fairlock_lock(os_fairlock_t* self){
os_mutex_lock(&self->lock);
}
OS_STATIC_FORCE_INLINE
os_err_t os_fairlock_timed_lock(os_fairlock_t* self, os_tick_t ticks){
return os_mutex_timed_lock(&self->lock, ticks);
}
OS_STATIC_FORCE_INLINE
void os_fairlock_unlock(os_fairlock_t* self){
os_mutex_unlock_one(&self->lock);
}
#endif /*INCLUDED_OS_FAIRLOCK_H*/
+50
View File
@@ -0,0 +1,50 @@
#include <os_idle.h>
#include "os_align.h"
#include "os_critical.h"
os_task_t g_os_idle_task;
#ifndef OS_CFG_IDLE_TASK_STACK_SIZE
#define OS_CFG_IDLE_TASK_STACK_SIZE 1024
#endif /* OS_CFG_IDLE_TASK_STACK_SIZE */
#ifndef OS_CFG_IDLE_TASK_TICKS
#define OS_CFG_IDLE_TASK_TICKS 5
#endif /* OS_CFG_IDLE_TASK_TICKS */
#ifndef OS_CFG_IDLE_TASK_PRIORITY
#define OS_CFG_IDLE_TASK_PRIORITY OS_PRIORITY_IDLE
#endif /* OS_CFG_IDLE_TASK_PRIORITY */
OS_ALIGNED(OS_ALIGN_SIZE)
static uint8_t s_os_idle_stack[OS_CFG_IDLE_TASK_STACK_SIZE];
static volatile os_idle_entry_t s_os_idle_entry;
static volatile void* s_os_idle_entry_param;
static OS_NORETURN void os_idle_entry(void* p){
while(1){
if(s_os_idle_entry){
s_os_idle_entry((void*)s_os_idle_entry_param);
}
}
}
void os_idle_init(void){
os_task_init(&g_os_idle_task, os_idle_entry, 0
, s_os_idle_stack, OS_ARRAY_SIZE(s_os_idle_stack)
, OS_CFG_IDLE_TASK_TICKS, OS_CFG_IDLE_TASK_PRIORITY);
}
os_idle_closure_t os_idle_register(os_idle_entry_t entry, void* param){
os_idle_closure_t closure;
os_critical_enter();
closure.entry = s_os_idle_entry;
closure.param = (void*)s_os_idle_entry_param;
s_os_idle_entry = entry;
s_os_idle_entry_param = param;
os_critical_leave();
return closure;
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef INCLUDED_OS_IDLE_H
#define INCLUDED_OS_IDLE_H
#ifndef INCLUDED_OS_TASK_H
#include <os_task.h>
#endif /*INCLUDED_OS_TASK_H*/
extern os_task_t g_os_idle_task;
typedef void (*os_idle_entry_t)(void*);
typedef struct {
os_idle_entry_t entry;
void* param;
}os_idle_closure_t;
void os_idle_init(void);
os_idle_closure_t os_idle_register(os_idle_entry_t entry, void* param);
OS_STATIC_FORCE_INLINE
os_bool_t os_idle_is_idle_task(os_task_t* p_task){
return (&g_os_idle_task == p_task)?OS_TRUE:OS_FALSE;
}
#endif /*INCLUDED_OS_IDLE_H*/
+3
View File
@@ -0,0 +1,3 @@
#include <os_isr.h>
volatile os_size_t g_os_isr_nesting_cnt;
+51
View File
@@ -0,0 +1,51 @@
#ifndef INCLUDED_OS_ISR_H
#define INCLUDED_OS_ISR_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
#ifndef INCLUDED_OS_CRITICAL_H
#include <os_critical.h>
#endif /*INCLUDED_OS_CRITICAL_H*/
#ifndef INCLUDED_OS_SCHED_H
#include <os_sched.h>
#endif /*INCLUDED_OS_SCHED_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
extern volatile os_size_t g_os_isr_nesting_cnt;
OS_STATIC_FORCE_INLINE
void os_isr_enter(void){
os_critical_enter_in_isr();
g_os_isr_nesting_cnt++;
os_critical_leave_in_isr();
}
OS_STATIC_FORCE_INLINE
void os_isr_leave(void){
os_critical_enter_in_isr();
g_os_isr_nesting_cnt--;
if(g_os_isr_nesting_cnt==0){
if(g_os_sched_pending_cnt>0){
g_os_sched_pending_cnt = 0;
os_critical_leave_in_isr();
os_sched_in_isr();
return;
}
}
os_critical_leave_in_isr();
}
#endif /*INCLUDED_OS_ISR_H*/
+104
View File
@@ -0,0 +1,104 @@
#include <os_mutex.h>
#include "os_critical.h"
void os_mutex_init(os_mutex_t* self){
self->owner = 0;
os_waitobject_init(&self->wait_obj);
}
void os_mutex_destroy(os_mutex_t* self){
OS_ASSERT(self->owner==0);
}
os_err_t os_mutex_trylock(os_mutex_t* self){
os_critical_enter();
os_task_t* p_thread = os_task_self();
if(self->owner!=0){ // 已经被锁定了
if(self->owner==p_thread){ // 是当前任务锁定的
os_critical_leave();
return OS_ERR_OK;
}
// 当前任务不是 owner,判断优先级是否反转
if(os_priority_cmp(p_thread->curr_priority, self->owner->curr_priority)==OS_PRIORITY_CMP_HIGH){
// 当前任务的优先级更高,优先级反转了,提升 owner 优先级
self->owner->curr_priority = p_thread->curr_priority;
}
os_critical_leave();
return OS_ERR_FAIL;
}
// 到这里说明没有owner
self->owner = (os_task_t*)p_thread;
os_critical_leave();
return OS_ERR_OK;
}
os_err_t os_mutex_lock(os_mutex_t* self){
while(os_mutex_trylock(self)!=OS_ERR_OK){
os_task_yield(); // 未获得锁,主动让出
}
return OS_ERR_OK;
}
os_err_t os_mutex_timed_lock(os_mutex_t* self, os_tick_t ticks){
if(os_mutex_trylock(self)!=OS_ERR_OK){
os_critical_enter();
os_task_t* p_task = os_task_self();
os_critical_leave();
return os_waitobject_timed_wait(&self->wait_obj, p_task, ticks);
}
return OS_ERR_OK;
}
void os_mutex_unlock(os_mutex_t* self){
os_critical_enter();
os_task_t* p_task = os_task_self();
if(self->owner != p_task){
// 只有 owner 才能 unlock
os_critical_leave();
os_task_yield();
return;
}
if(self->owner->curr_priority!=self->owner->init_priority) {
self->owner->curr_priority = self->owner->init_priority; /* 恢复优先级 */
}
self->owner = 0;
os_critical_leave();
os_waitobject_notify_all(&self->wait_obj);
}
void os_mutex_unlock_one(os_mutex_t* self){
os_critical_enter();
os_task_t* p_task = os_task_self();
if(self->owner != p_task){
// 只有 owner 才能 unlock
os_critical_leave();
os_task_yield();
return;
}
if(self->owner->curr_priority!=self->owner->init_priority) {
self->owner->curr_priority = self->owner->init_priority; /* 恢复优先级 */
}
self->owner = 0;
// 将所有等待任务加入就绪表,等待当前任务用时完成后进行调度
os_critical_leave();
os_waitobject_notify_one(&self->wait_obj);
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef INCLUDED_OS_MUTEX_H
#define INCLUDED_OS_MUTEX_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_TASK_H
#include <os_task.h>
#endif /*INCLUDED_OS_TASK_H*/
#ifndef INCLUDED_OS_WAITOBJECT_H
#include <os_waitobject.h>
#endif /*INCLUDED_OS_WAITOBJECT_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct os_mutex_t os_mutex_t;
struct os_mutex_t{
os_task_t* owner; // 被哪个任务锁定
os_waitobject_t wait_obj;
};
/* ------------------------------------------------------------------------------------------------------------------ */
/* 接口 */
void os_mutex_init(os_mutex_t* self);
void os_mutex_destroy(os_mutex_t* self);
os_err_t os_mutex_trylock(os_mutex_t* self);
os_err_t os_mutex_lock(os_mutex_t* self);
void os_mutex_unlock(os_mutex_t* self);
os_err_t os_mutex_timed_lock(os_mutex_t* self, os_tick_t ticks);
void os_mutex_unlock_one(os_mutex_t* self);
#endif /*INCLUDED_OS_MUTEX_H*/
+35
View File
@@ -0,0 +1,35 @@
#include <os_port.h>
#include "os_critical.h"
#include "os_sched.h"
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
volatile void* g_os_port_switch_from_sp;
volatile void* g_os_port_switch_to_sp;
volatile os_bool_t g_os_port_context_switch_flag;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
void os_port_on_switch_success(void){
os_critical_enter_in_isr();
g_os_sched_current_task_p = g_os_port_switch_to_sp;
g_os_sched_current_task_p->state = kOsTaskState_Running;
g_os_port_context_switch_flag = OS_FALSE;
os_critical_leave_in_isr();
}
void os_port_context_switch(void* from_sp, void* to_sp){
os_critical_enter_in_isr();
if(g_os_port_context_switch_flag==OS_TRUE){
os_critical_leave_in_isr();
return;
}
g_os_port_context_switch_flag = OS_TRUE;
g_os_port_switch_from_sp = from_sp;
g_os_port_switch_to_sp = to_sp;
os_critical_leave_in_isr();
os_port_send_context_switch_request();
}
+78
View File
@@ -0,0 +1,78 @@
#ifndef INCLUDED_OS_PORT_H
#define INCLUDED_OS_PORT_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_TASK_H
#include <os_task.h>
#endif /*INCLUDED_OS_TASK_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
extern volatile void* g_os_port_switch_from_sp;
extern volatile void* g_os_port_switch_to_sp;
extern volatile os_bool_t g_os_port_context_switch_flag;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
/*
* 根据 CPU 平台和型号的规定初始化任务栈
* @param entry - 任务入口
* @param param - 任务参数
* @param stack_base - 栈空间起始地址
* @param stack_size - 栈空间大小
* @param exit_entry - 任务退出时的返回地址
*/
os_stack_t os_port_cpu_stack_init(os_task_entry_t entry, void* param
, void* stack_base, os_size_t stack_size, void(*exit_entry)(void));
/*
* 请求上下文切换
* @param from_sp - 切换的源头任务栈
* @param to_sp - 切换的目标任务栈
*/
void os_port_context_switch(void* from_sp, void* to_sp);
/*
* 发出上下文切换的请求
*/
void os_port_send_context_switch_request(void);
/*
* 清除上下文切换的请求
*/
void os_port_clear_context_switch_request(void);
/*
* 任务切换完成后的回调函数,进行清理工作
*/
void os_port_on_switch_success(void);
/* ------------------------------------------------------------------------------------------------------------------ */
/* 中断管理 */
void os_port_disable_irq(void);
void os_port_enable_irq(void);
os_uint_t os_port_save_disable_irq(void);
void os_port_restore_irq(os_uint_t level);
os_uint_t os_port_save_disable_irq_in_isr(void);
void os_port_restore_irq_in_isr(os_uint_t level);
/* ------------------------------------------------------------------------------------------------------------------ */
/* 初始化和启动 */
void os_port_init(void);
void os_port_startup(void);
#endif /*INCLUDED_OS_PORT_H*/
+25
View File
@@ -0,0 +1,25 @@
#include "os_priority.h"
#include "cpu_clz.h"
#include "os_macros.h"
#include "os_config.h"
#include "os_align.h"
/* ======================================================================================================================== */
/* 私有数据 */
OS_ALIGNED(OS_ALIGN_SIZE)
volatile os_priority_t g_os_priority_table[OS_PRIORITY_TABLE_SIZE];
/* ======================================================================================================================== */
/* 接口方法实现 */
+94
View File
@@ -0,0 +1,94 @@
#ifndef INCLUDED_OS_PRIORITY_H
#define INCLUDED_OS_PRIORITY_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
#ifndef INCLUDED_CPU_CLZ_H
#include <cpu_clz.h>
#endif /*INCLUDED_CPU_CLZ_H*/
/* ======================================================================================================================== */
/* 常量 */
#define OS_PRIORITY_TABLE_SIZE ((OS_CFG_PRIORITY_MAX - 1u)/(OS_CFG_CPU_INT_NBITS) + 1u) // 优先级位图表的大小,单位为os_uint_t的数量
#define OS_PRIORITY_CMP_HIGH (1)
#define OS_PRIORITY_CMP_EQUAL (0)
#define OS_PRIORITY_CMP_LOW (-1)
#define OS_PRIORITY_IDLE OS_PRIORITY_LOWEST
#define OS_PRIORITY_LOWEST (OS_CFG_PRIORITY_MAX-1) /*31*/
#define OS_PRIORITY_HIGHEST (1) /*1*/
#define OS_PRIORITY_NORMAL ((OS_PRIORITY_LOWEST-OS_PRIORITY_HIGHEST)>>1) /*15*/
#define OS_PRIORITY_BELOW_NORMAL (((OS_PRIORITY_LOWEST-OS_PRIORITY_NORMAL)>>1)+OS_PRIORITY_NORMAL) /*23*/
#define OS_PRIORITY_ABOVE_NORMAL ((OS_PRIORITY_NORMAL-OS_PRIORITY_HIGHEST)>>1) /*7*/
/* ======================================================================================================================== */
/* 类型 */
typedef os_uint_t os_priority_t;
extern volatile os_priority_t g_os_priority_table[OS_PRIORITY_TABLE_SIZE];
/* ======================================================================================================================== */
/* 接口 */
OS_STATIC_FORCE_INLINE
void os_priority_init(void){
for(os_uint_t i = 0; i < OS_PRIORITY_TABLE_SIZE; i++){
g_os_priority_table[i] = 0u; // 初始化优先级位图表,将所有优先级位都设置为0,表示所有优先级都没有线程占用
}
}
OS_STATIC_FORCE_INLINE
void os_priority_set(os_priority_t priority){
os_size_t index = priority / OS_CFG_CPU_INT_NBITS; // 计算优先级在优先级位图表中的索引位置
os_size_t bit_idx = priority & (OS_CFG_CPU_INT_NBITS - 1u); // 计算优先级在索引位置的位偏移 0 - 31
os_uint_t bit = 1u << (OS_CFG_CPU_INT_NBITS - 1u - bit_idx); // 计算对应位的掩码,优先级0对应最高位,优先级31对应最低位
g_os_priority_table[index] |= bit; // 将对应位设置为1,表示该优先级被占用
}
OS_STATIC_FORCE_INLINE
void os_priority_clear(os_priority_t priority){
os_size_t index = priority / OS_CFG_CPU_INT_NBITS; // 计算优先级在优先级位图表中的索引位置
os_size_t bit_idx = priority & (OS_CFG_CPU_INT_NBITS - 1u); // 计算优先级在索引位置的位偏移 0 - 31
os_uint_t bit = 1u << (OS_CFG_CPU_INT_NBITS - 1u - bit_idx); // 计算对应位的掩码,优先级0对应最高位,优先级31对应最低位
g_os_priority_table[index] &= ~bit; // 将对应位清零,表示该优先级被释放
}
OS_STATIC_FORCE_INLINE
os_priority_t os_priority_get_highest(void){
os_priority_t* p_table = (os_priority_t*)&g_os_priority_table[0]; // 从优先级位图表的第一个元素开始查找
os_priority_t priority = 0;
while(*p_table == 0u){ // 如果当前元素为0,表示该范围内的优先级都没有线程占用
p_table++; // 移动到下一个元素
priority += OS_CFG_CPU_INT_NBITS; // 增加优先级偏移量,跳过当前范围
}
priority += cpu_clz(*p_table); // 使用内置函数计算当前元素中最高位1的索引位置,得到最高优先级的偏移量
return priority; // 返回最高优先级,优先级0对应最高位,没有线程占用时返回OS_CFG_PRIORITY_MAX
}
OS_STATIC_FORCE_INLINE
os_bool_t os_priority_is_high(os_priority_t prio_a, os_priority_t prio_b){
return (prio_a < prio_b)?OS_TRUE:OS_FALSE; // 优先级数值越小表示优先级越高,因此比较两个优先级的数值大小来判断哪个优先级更高
}
OS_STATIC_FORCE_INLINE
int os_priority_cmp(os_priority_t prio_a, os_priority_t prio_b){
return (int)((prio_a == prio_b)?OS_PRIORITY_CMP_EQUAL:((prio_a < prio_b)?OS_PRIORITY_CMP_HIGH:OS_PRIORITY_CMP_LOW));
}
#endif /* INCLUDED_OS_PRIORITY_H */
+5
View File
@@ -0,0 +1,5 @@
#include <os_rdy_list.h>
#include "os_align.h"
OS_ALIGNED(OS_ALIGN_SIZE)
os_rdy_list_t os_rdy_list_table[OS_CFG_PRIORITY_MAX];
+97
View File
@@ -0,0 +1,97 @@
#ifndef INCLUDED_OS_RDY_LIST_H
#define INCLUDED_OS_RDY_LIST_H
#ifndef INCLUDED_OS_LIST_H
#include "os_list.h"
#endif /* INCLUDED_OS_LIST_H */
#ifndef INCLUDED_OS_PRIORITY_H
#include "os_priority.h"
#endif /* INCLUDED_OS_PRIORITY_H */
#ifndef INCLUDED_OS_TASK_H
#include <os_task.h>
#endif /*INCLUDED_OS_TASK_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct os_rdy_list_t{
os_list_t head;
}os_rdy_list_t;
extern os_rdy_list_t os_rdy_list_table[OS_CFG_PRIORITY_MAX];
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void os_rdy_list_init(void){
os_rdy_list_t* p_rdy_list;
for(os_size_t i=0; i<OS_CFG_PRIORITY_MAX; i++){
p_rdy_list = &os_rdy_list_table[i];
os_list_init(&p_rdy_list->head);
}
}
OS_STATIC_FORCE_INLINE
void os_rdy_list_insert_head(os_task_t* tcb){
os_rdy_list_t* p_rdy_list = &os_rdy_list_table[tcb->curr_priority];
os_list_insert_after(&p_rdy_list->head, &tcb->node);
}
OS_STATIC_FORCE_INLINE
void os_rdy_list_insert_tail(os_task_t* tcb){
os_rdy_list_t* p_rdy_list = &os_rdy_list_table[tcb->curr_priority];
os_list_insert_before(&p_rdy_list->head, &tcb->node);
}
OS_STATIC_FORCE_INLINE
void os_rdy_list_insert(os_task_t* tcb){
// 标记当前优先级
tcb->state = kOsTaskState_Ready;
os_rdy_list_t* p_rdy_list = &os_rdy_list_table[tcb->curr_priority];
if(os_list_is_empty(&p_rdy_list->head)){
os_priority_set(tcb->curr_priority);
}
os_list_insert_before(&p_rdy_list->head, &tcb->node);
}
OS_STATIC_FORCE_INLINE
void os_rdy_list_remove(os_task_t* tcb){
os_priority_t prio = tcb->curr_priority;
os_rdy_list_t* p_rdy_list = &os_rdy_list_table[prio];
os_list_remove(&tcb->node);
if(os_list_is_empty(&p_rdy_list->head)){
os_priority_clear(prio);
}
}
OS_STATIC_FORCE_INLINE
os_rdy_list_t* os_rdy_list_get(os_priority_t priority){
if(priority >= OS_CFG_PRIORITY_MAX){
return NULL;
}
return &os_rdy_list_table[priority];
}
OS_STATIC_FORCE_INLINE
os_bool_t os_rdy_list_is_empty(os_rdy_list_t* p_rdy_list){
return os_list_is_empty(&p_rdy_list->head);
}
OS_STATIC_FORCE_INLINE
os_task_t* os_rdy_list_pop_head_task(os_rdy_list_t* p_rdy_list){
os_list_node_t* p_node = p_rdy_list->head.next;
os_task_t* p_task = os_list_member_of(p_node, os_task_t, node);
os_list_remove(&p_task->node);
if(os_list_is_empty(&p_rdy_list->head)){
os_priority_clear(p_task->curr_priority);
}
return p_task;
}
#endif /* INCLUDED_OS_RDY_LIST_H */
+88
View File
@@ -0,0 +1,88 @@
#include <os_sched.h>
#include "os_port.h"
#include "os_critical.h"
#include "os_rdy_list.h"
#include "os_yield_list.h"
#include "os_idle.h"
#include "os_isr.h"
volatile os_task_t* g_os_sched_current_task_p;
volatile os_size_t g_os_sched_pending_cnt;
static volatile os_task_t* p_curr_task;
static volatile os_task_t* p_next_task;
static os_bool_t s_os_sched_wip_flag;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
void os_sched_init(void){
g_os_sched_current_task_p = 0;
g_os_sched_pending_cnt = 0;
s_os_sched_wip_flag = OS_FALSE;
}
void os_sched_in_isr(void){
os_critical_enter_in_isr();
if(s_os_sched_wip_flag == OS_TRUE){
// 调度正在进行中,返回
os_critical_leave_in_isr();
return;
}
s_os_sched_wip_flag = OS_TRUE;
if(g_os_isr_nesting_cnt>0){
// 中断嵌套
g_os_sched_pending_cnt++;
s_os_sched_wip_flag = OS_FALSE;
os_critical_leave_in_isr();
return;
}
if(g_os_sched_current_task_p && g_os_sched_current_task_p->state == kOsTaskState_Running){
// 当前任务还在运行,返回
s_os_sched_wip_flag = OS_FALSE;
os_critical_leave_in_isr();
return;
}
p_curr_task = g_os_sched_current_task_p;
// 获取下一个任务
os_priority_t priority = os_priority_get_highest();
os_rdy_list_t* p_rdy_list = os_rdy_list_get(priority);
os_list_node_t* p_node = p_rdy_list->head.next;
p_next_task = os_list_member_of(p_node, os_task_t, node);
if(!os_idle_is_idle_task((os_task_t*)p_next_task)){
os_rdy_list_remove((os_task_t*)p_next_task);
}
// yield 的任务加入就绪表
for(p_node = g_os_yield_list.next; p_node!=&g_os_yield_list; ){
os_task_t* p_task = os_list_member_of(p_node, os_task_t, node);
p_node = p_node->next;
os_yield_list_remove(p_task);
if(!os_idle_is_idle_task(p_task)) {
os_rdy_list_insert(p_task);
}
}
// 下个任务就是当前任务, 获得一次运行的机会
if(p_next_task==p_curr_task){
p_next_task->state = kOsTaskState_Running;
p_next_task->remain_ticks = p_next_task->init_ticks;
s_os_sched_wip_flag = OS_FALSE;
os_critical_leave_in_isr();
return;
}
s_os_sched_wip_flag = OS_FALSE;
os_critical_leave_in_isr();
// 执行上下文切换
os_port_context_switch((void*)(p_curr_task?&p_curr_task->stack.sp:0), (void*)&p_next_task->stack.sp);
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef INCLUDED_OS_SCHED_H
#define INCLUDED_OS_SCHED_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct os_task_t os_task_t;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
extern volatile os_task_t* g_os_sched_current_task_p;
extern volatile os_size_t g_os_sched_pending_cnt;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
void os_sched_init(void);
void os_sched(void);
void os_sched_in_isr(void);
#endif /*INCLUDED_OS_SCHED_H*/
+1
View File
@@ -0,0 +1 @@
#include <os_sem.h>
+88
View File
@@ -0,0 +1,88 @@
#ifndef INCLUDED_OS_SEM_H
#define INCLUDED_OS_SEM_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_CRITICAL_H
#include <os_critical.h>
#endif /*INCLUDED_OS_CRITICAL_H*/
#ifndef INCLUDED_OS_WAITOBJECT_H
#include <os_waitobject.h>
#endif /*INCLUDED_OS_WAITOBJECT_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct {
os_size_t value;
os_waitobject_t wait_obj;
}os_sem_t;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void os_sem_init(os_sem_t* self, os_size_t value){
self->value = value;
os_waitobject_init(&self->wait_obj);
}
OS_STATIC_FORCE_INLINE
os_err_t os_sem_timed_wait(os_sem_t* self, os_tick_t ticks){
os_critical_enter();
if(self->value>0){
self->value--;
os_critical_leave();
return OS_ERR_OK;
}
os_critical_leave();
return os_waitobject_timed_wait(&self->wait_obj, os_task_self(), ticks);
}
OS_STATIC_FORCE_INLINE
void os_sem_wait(os_sem_t* self){
os_critical_enter();
if(self->value>0){
self->value--;
os_critical_leave();
}
os_critical_leave();
os_waitobject_wait(&self->wait_obj, os_task_self());
}
OS_STATIC_FORCE_INLINE
void os_sem_notify_all(os_sem_t* self){
os_critical_enter();
self->value++;
os_critical_leave();
os_waitobject_notify_all(&self->wait_obj);
}
OS_STATIC_FORCE_INLINE
void os_sem_notify_one(os_sem_t* self){
os_critical_enter();
self->value++;
os_critical_leave();
os_waitobject_notify_one(&self->wait_obj);
}
OS_STATIC_FORCE_INLINE
void os_sem_notify_all_in_isr(os_sem_t* self){
os_critical_enter_in_isr();
self->value++;
os_critical_leave_in_isr();
os_waitobject_notify_all_in_isr(&self->wait_obj);
}
OS_STATIC_FORCE_INLINE
void os_sem_notify_one_in_isr(os_sem_t* self){
os_critical_enter_in_isr();
self->value++;
os_critical_leave_in_isr();
os_waitobject_notify_one_in_isr(&self->wait_obj);
}
#endif /*INCLUDED_OS_SEM_H*/
+3
View File
@@ -0,0 +1,3 @@
#include <os_systick.h>
volatile os_tick_t g_os_systick_ticks;
+80
View File
@@ -0,0 +1,80 @@
#ifndef INCLUDED_OS_SYSTICK_H
#define INCLUDED_OS_SYSTICK_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
#ifndef INCLUDED_OS_CRITICAL_H
#include <os_critical.h>
#endif /*INCLUDED_OS_CRITICAL_H*/
#ifndef INCLUDED_OS_SCHED_H
#include <os_sched.h>
#endif /*INCLUDED_OS_SCHED_H*/
#ifndef INCLUDED_OS_YIELD_LIST_H
#include <os_yield_list.h>
#endif /*INCLUDED_OS_YIELD_LIST_H*/
#ifndef INCLUDED_OS_TIMEWHEEL_H
#include <os_timewheel.h>
#endif /*INCLUDED_OS_TIMEWHEEL_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
extern volatile os_tick_t g_os_systick_ticks;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void os_systick_tick(void){
os_critical_enter_in_isr();
os_bool_t need_sched_flag = OS_FALSE;
g_os_systick_ticks++;
if(g_os_sched_current_task_p && g_os_sched_current_task_p->state == kOsTaskState_Running){
if(g_os_sched_current_task_p->remain_ticks>0
&& (g_os_sched_current_task_p->remain_ticks <= g_os_sched_current_task_p->init_ticks)){
g_os_sched_current_task_p->remain_ticks--;
if(g_os_sched_current_task_p->remain_ticks==0){
// 时间窗用完了
g_os_sched_current_task_p->remain_ticks = g_os_sched_current_task_p->init_ticks; // 重置时间窗
os_yield_list_insert((os_task_t*)g_os_sched_current_task_p); // 加入yield列表
need_sched_flag = OS_TRUE;
}
}
}
os_err_t err = os_timewheel_tick();
if(err==OS_TIMEWHEEL_TICK_NEED_SCHEDULE){
need_sched_flag = OS_TRUE;
}
os_critical_leave_in_isr();
if(need_sched_flag == OS_TRUE){
os_sched_in_isr();
}
}
OS_STATIC_FORCE_INLINE
os_tick_t os_systick_get(void){
os_critical_enter();
os_tick_t ticks = g_os_systick_ticks;
os_critical_leave();
return ticks;
}
#endif /*INCLUDED_OS_SYSTICK_H*/
+67
View File
@@ -0,0 +1,67 @@
#include <os_task.h>
#include "os_port.h"
#include "os_macros.h"
#include "os_compiler.h"
#include "os_rdy_list.h"
#include "os_critical.h"
#include "os_timewheel.h"
#include "os_sched.h"
#include "os_yield_list.h"
extern os_task_t g_os_idle_task;
static OS_NORETURN void os_task_on_exit(void){
os_critical_enter();
os_task_t* p_task = (os_task_t*)g_os_sched_current_task_p;
p_task->state = kOsTaskState_Terminated;
g_os_sched_current_task_p = 0;
os_critical_leave();
os_sched();
while(1){
OS_ASSERT(1==0);
}
}
void os_task_init(os_task_t* self, os_task_entry_t entry, void* param, void* stack_base, os_size_t stack_size
, os_tick_t ticks, os_priority_t priority){
self->stack = os_port_cpu_stack_init(entry, param, stack_base, stack_size, os_task_on_exit);
os_list_init(&self->node);
self->init_ticks = ticks;
self->remain_ticks = ticks;
self->init_priority = priority;
self->curr_priority = priority;
os_timer_init(&self->timer, 0, 0, 0, OS_TIMER_FLAG_ONCE);
self->state = kOsTaskState_Idle;
os_critical_enter();
os_rdy_list_insert(self);
os_critical_leave();
}
static void os_task_on_timeout(os_timer_t* self){
os_task_t* p_task = self->userdata;
p_task->remain_ticks = p_task->init_ticks;
os_rdy_list_insert(p_task);
}
void os_task_sleep(os_tick_t ticks){
os_critical_enter();
os_task_t* p_task = (os_task_t*)g_os_sched_current_task_p;
p_task->state = kOsTaskState_Delay;
os_timewheel_add_timer(&p_task->timer, os_task_on_timeout, p_task, ticks, OS_TIMER_FLAG_ONCE);
os_critical_leave();
os_sched();
}
void os_task_yield(void){
os_critical_enter();
os_yield_list_insert((os_task_t*)g_os_sched_current_task_p);
os_critical_leave();
os_sched();
}
void os_task_join(os_task_t* self){
while(self->state!=kOsTaskState_Terminated){
os_task_yield();
}
}
+81
View File
@@ -0,0 +1,81 @@
#ifndef INCLUDED_OS_TASK_H
#define INCLUDED_OS_TASK_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_STACK_H
#include <os_stack.h>
#endif /*INCLUDED_OS_STACK_H*/
#ifndef INCLUDED_OS_LIST_H
#include <os_list.h>
#endif /*INCLUDED_OS_LIST_H*/
#ifndef INCLUDED_OS_PRIORITY_H
#include <os_priority.h>
#endif /*INCLUDED_OS_PRIORITY_H*/
#ifndef INCLUDED_OS_UTILS_H
#include <os_utils.h>
#endif /*INCLUDED_OS_UTILS_H*/
#ifndef INCLUDED_OS_TIMER_H
#include <os_timer.h>
#endif /*INCLUDED_OS_TIMER_H*/
#ifndef INCLUDED_OS_SCHED_H
#include <os_sched.h>
#endif /*INCLUDED_OS_SCHED_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef void (*os_task_entry_t)(void*);
typedef enum {
kOsTaskState_Terminated = -1,
kOsTaskState_Idle = 0,
kOsTaskState_Ready = 1,
kOsTaskState_Running = 2,
kOsTaskState_Yield = 3,
kOsTaskState_Delay = 4,
kOsTaskState_Wait = 5,
}os_task_state_t;
typedef struct os_task_t{
os_stack_t stack;
os_list_node_t node;
os_tick_t init_ticks;
os_tick_t remain_ticks;
os_priority_t init_priority;
os_priority_t curr_priority;
os_timer_t timer;
os_task_state_t state;
os_err_t errors;
}os_task_t;
void os_task_init(os_task_t* self, os_task_entry_t entry, void* param, void* stack_base, os_size_t stack_size, os_tick_t ticks, os_priority_t priority);
void os_task_sleep(os_tick_t ticks);
void os_task_yield(void);
void os_task_join(os_task_t* self);
OS_STATIC_FORCE_INLINE
void os_tick_sleep_ms(os_size_t ms){
os_task_sleep(os_tick_from_ms(ms));
}
OS_STATIC_FORCE_INLINE
os_task_t* os_task_self(void){
return (os_task_t*)g_os_sched_current_task_p;
}
#endif /*INCLUDED_OS_TASK_H*/
+2
View File
@@ -0,0 +1,2 @@
#include <os_timer.h>
+59
View File
@@ -0,0 +1,59 @@
#ifndef INCLUDED_OS_TIMER_H
#define INCLUDED_OS_TIMER_H
#ifndef INCLUDED_OS_LIST_H
#include <os_list.h>
#endif /*INCLUDED_OS_LIST_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
/* -------------------------------------------------------------------------------------------------------------- */
/* */
#define OS_TIMER_FLAG_ONCE (1<<0)
#define OS_TIMER_FLAG_REPEAT (1<<1)
/* -------------------------------------------------------------------------------------------------------------- */
/* */
typedef struct os_timer_t os_timer_t;
typedef void (*os_timer_function_t)(os_timer_t* timer);
struct os_timer_t {
os_list_node_t node;
os_timer_function_t function;
void* userdata;
os_tick_t ticks;
os_tick_t expire_tick;
int flag;
};
/* -------------------------------------------------------------------------------------------------------------- */
/* */
OS_STATIC_FORCE_INLINE
void os_timer_init(os_timer_t* timer, os_timer_function_t fn, void* userdata, os_tick_t ticks, int flag) {
timer->function = fn;
timer->userdata = userdata;
timer->ticks = ticks;
timer->expire_tick = 0;
timer->flag = flag;
os_list_init(&timer->node);
}
OS_STATIC_FORCE_INLINE
void os_timer_remove(os_timer_t* self){
os_list_remove(&self->node);
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#define OS_Timer_Init os_timer_init
#endif /*INCLUDED_OS_TIMER_H*/
+47
View File
@@ -0,0 +1,47 @@
#include <os_timewheel.h>
#include <os_macros.h>
/* -------------------------------------------------------------------------------------------------------------- */
/* */
os_list_t os_timewheel__R[TWR_SIZE];
os_list_t os_timewheel__N0[TWN_SIZE];
os_list_t os_timewheel__N1[TWN_SIZE];
os_list_t os_timewheel__N2[TWN_SIZE];
os_list_t os_timewheel__N3[TWN_SIZE];
volatile os_tick_t os_timewheel__tick;
/* -------------------------------------------------------------------------------------------------------------- */
/* */
os_err_t os_timewheel_tick(void) {
os_tick_t current_tick = os_timewheel__tick++;
os_list_node_t* node=0;
os_timer_t* timer_p=0;
os_err_t err = OS_TIMEWHEEL_TICK_OK;
const os_list_t* wheel = os_timewheel_find(current_tick);
for (node = os_list_next(wheel); node!=wheel;) {
timer_p = os_list_member_of(node, os_timer_t, node);
node = os_list_next(node);
if (timer_p->expire_tick <= current_tick) {
os_list_remove(&(timer_p->node));
timer_p->function(timer_p);
if (OS_BIT_GET(timer_p->flag, OS_TIMER_FLAG_REPEAT)) {
timer_p->expire_tick = current_tick + timer_p->ticks;
os_list_t* slot = os_timewheel_find(timer_p->expire_tick);
os_list_insert_before(slot, &timer_p->node);
}
err = OS_TIMEWHEEL_TICK_NEED_SCHEDULE;
}
}
return err;
}
+123
View File
@@ -0,0 +1,123 @@
#ifndef INCLUDED_OS_TIMEWHEEL_H
#define INCLUDED_OS_TIMEWHEEL_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_TIMER_H
#include <os_timer.h>
#endif /*INCLUDED_OS_TIMER_H*/
#ifndef INCLUDED_OS_MACROS_H
#include <os_macros.h>
#endif /*INCLUDED_OS_MACROS_H*/
/* -------------------------------------------------------------------------------------------------------------- */
/* */
#define OS_TIMEWHEEL_TICK_OK 0
#define OS_TIMEWHEEL_TICK_NEED_SCHEDULE 201
/* -------------------------------------------------------------------------------------------------------------- */
/* |------|------|------|------|--------|
* 6 6 6 6 8(R)
* N3 N2 N1 N0
*/
#define TWR_BITS 8
#define TWN_BITS 6
#define TWN_MASK 0x3F
#define TWR_SIZE (1<<TWR_BITS)
#define TWN_SIZE (1<<TWN_BITS)
#define TWR_MAX (0xFFu)
#define TWN0_MAX (0x3FFFu) /*11 1111 1111 1111*/
#define TWN1_MAX (0xFFFFFu) /*1111 1111 1111 1111 1111*/
#define TWN2_MAX (0x3FFFFFFu) /*11 1111 1111 1111 1111 1111 1111*/
#define TWN3_MAX (0xFFFFFFFu) /*1111 1111 1111 1111 1111 1111 1111 1111*/
#define TWN_IDX(T, N) (((T)>>(TWR_BITS + (N)*TWN_BITS)) & TWN_MASK)
/* -------------------------------------------------------------------------------------------------------------- */
/* */
extern volatile os_tick_t os_timewheel__tick;
extern os_list_t os_timewheel__R[TWR_SIZE];
extern os_list_t os_timewheel__N0[TWN_SIZE];
extern os_list_t os_timewheel__N1[TWN_SIZE];
extern os_list_t os_timewheel__N2[TWN_SIZE];
extern os_list_t os_timewheel__N3[TWN_SIZE];
OS_STATIC_FORCE_INLINE
void os_timewheel_init(void) {
os_timewheel__tick = 0;
for (os_size_t i=0; i<OS_ARRAY_SIZE(os_timewheel__R); i++) {
os_list_init(&os_timewheel__R[i]);
}
for (os_size_t i=0; i<OS_ARRAY_SIZE(os_timewheel__N0); i++) {
os_list_init(&os_timewheel__N0[i]);
}
for (os_size_t i=0; i<OS_ARRAY_SIZE(os_timewheel__N1); i++) {
os_list_init(&os_timewheel__N1[i]);
}
for (os_size_t i=0; i<OS_ARRAY_SIZE(os_timewheel__N2); i++) {
os_list_init(&os_timewheel__N2[i]);
}
for (os_size_t i=0; i<OS_ARRAY_SIZE(os_timewheel__N3); i++) {
os_list_init(&os_timewheel__N3[i]);
}
}
OS_STATIC_FORCE_INLINE
os_list_t* os_timewheel_find(os_tick_t tick) {
if (tick<=TWR_MAX) {
return &os_timewheel__R[tick];
}else if (tick<=TWN0_MAX) {
return &os_timewheel__N0[TWN_IDX(tick, 0)];
}else if (tick<=TWN1_MAX) {
return &os_timewheel__N1[TWN_IDX(tick, 1)];
}else if (tick<=TWN2_MAX) {
return &os_timewheel__N2[TWN_IDX(tick, 2)];
}else if (tick<=TWN3_MAX) {
return &os_timewheel__N3[TWN_IDX(tick, 3)];
}else {
return NULL;
}
}
OS_STATIC_FORCE_INLINE
void os_timewheel_add_timer(os_timer_t* timer, os_timer_function_t function, void* userdata, os_tick_t ticks, int flags) {
os_list_remove(&timer->node);
os_timer_init(timer, function, userdata, ticks, flags);
timer->expire_tick = os_timewheel__tick + ticks;
os_list_t* wheel = os_timewheel_find(timer->expire_tick);
os_list_insert_before(wheel, &timer->node);
}
OS_STATIC_FORCE_INLINE
void os_timewheel_add_until_timer(os_timer_t* timer, os_timer_function_t function, void* userdata, os_tick_t ticks, int flags) {
os_timer_init(timer, function, userdata, ticks, flags);
timer->expire_tick = ticks;
os_list_t* wheel = os_timewheel_find(timer->expire_tick);
os_list_insert_before(wheel, &timer->node);
}
os_err_t os_timewheel_tick(void);
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#define OS_AddTimer os_timewheel_add_timer
#define OS_AddUntilTimer os_timewheel_add_until_timer
#define OS_TimerTick os_timewheel_tick
#endif /*INCLUDED_OS_TIMEWHEEL_H*/
+1
View File
@@ -0,0 +1 @@
#include <os_utils.h>
+27
View File
@@ -0,0 +1,27 @@
#ifndef INCLUDED_OS_UTILS_H
#define INCLUDED_OS_UTILS_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_MACROS_H
#include <os_macros.h>
#endif /*INCLUDED_OS_MACROS_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
os_tick_t os_tick_from_ms(os_size_t ms){
return (os_tick_t)((ms * OS_CFG_TICKS_PER_SECOND)/1000);
}
#endif /*INCLUDED_OS_UTILS_H*/
+134
View File
@@ -0,0 +1,134 @@
#include <os_waitobject.h>
#include <os_critical.h>
#include "os_rdy_list.h"
#include "os_priority.h"
void os_waitobject_on_timeout(os_timer_t* timer){
os_task_t* p_thread = timer->userdata;
os_rdy_list_insert(p_thread);
p_thread->errors = OS_ERR_TIMEOUT;
// p_thread->state = OS_TASK_STATE_READY;
p_thread->remain_ticks = p_thread->init_ticks;
// 是否需要抢占当前任务
os_task_t* p_curr_thread_p = os_task_self();
if(p_curr_thread_p && p_curr_thread_p->state==kOsTaskState_Running){
if(os_priority_is_high(p_thread->curr_priority, p_curr_thread_p->curr_priority)){
os_priority_set(p_curr_thread_p->curr_priority);
os_rdy_list_insert_head(p_curr_thread_p); // 放到头部,这样下次调度可以尽快调度这个任务
p_curr_thread_p->state = kOsTaskState_Ready; // 就绪状态
// 不要改变时间窗
// 默认 timewheel 在有 timeout 的 timer 时,会要求调度,因此这里不需要调度
}
}
}
os_err_t os_waitobject_timed_wait(os_waitobject_t* self, os_task_t* task, os_tick_t ticks){
os_critical_enter();
if(ticks==0){
os_critical_leave();
return OS_ERR_TIMEOUT;
}else if(ticks!=OS_WAIT_INFINITY){
os_timewheel_add_timer(&task->timer, os_waitobject_on_timeout
, task, ticks, OS_TIMER_FLAG_ONCE);
}else{
// WAIT_INFINITY
os_waitobject_wait_infinity(self, task);
}
os_critical_leave();
os_sched();
if(task->errors!=OS_ERR_OK){
os_err_t err = task->errors;
task->errors = OS_ERR_OK;
return err;
}
return OS_ERR_OK;
}
os_err_t os_waitobject_wait_until(os_waitobject_t* self, os_task_t* task, os_tick_t ticks){
os_critical_enter();
if(ticks==0){
os_critical_leave();
return OS_ERR_TIMEOUT;
}else if(ticks!=OS_WAIT_INFINITY){
os_timewheel_add_until_timer(&task->timer, os_waitobject_on_timeout
, task, ticks, OS_TIMER_FLAG_ONCE);
}else{
// WAIT_INFINITY
os_waitobject_wait_infinity(self, task);
}
os_critical_leave();
os_sched();
if(task->errors!=OS_ERR_OK){
os_err_t err = task->errors;
task->errors = OS_ERR_OK;
return err;
}
return OS_ERR_OK;
}
void os_waitobject_notify_one_in_isr(os_waitobject_t* self){
os_critical_enter_in_isr();
if(os_list_is_empty(&self->wait_list)){
os_critical_leave_in_isr();
return;
}
os_list_node_t* p = self->wait_list.next;
os_list_remove(p);
os_task_t* p_thread = os_list_member_of(p, os_task_t, node);
os_rdy_list_insert(p_thread);
// p_thread->state = OS_TASK_STATE_READY;
p_thread->remain_ticks = p_thread->init_ticks;
// 尝试抢占当前任务
os_task_t* p_curr_thread_p = os_task_self();
if(p_curr_thread_p && p_curr_thread_p->state==kOsTaskState_Running){
if(os_priority_is_high(p_thread->curr_priority, p_curr_thread_p->curr_priority)){
os_priority_set(p_curr_thread_p->curr_priority);
os_rdy_list_insert_head(p_curr_thread_p); // 放到头部,这样下次调度可以尽快调度这个任务
p_curr_thread_p->state = kOsTaskState_Ready; // 就绪状态
// 不要改变时间窗
}
}
os_critical_leave_in_isr();
os_sched_in_isr();
}
void os_waitobject_notify_all_in_isr(os_waitobject_t * self){
os_critical_enter_in_isr();
os_list_node_t* p = self->wait_list.next;
os_task_t* p_curr_thread_p = os_task_self();
for(;p!=&self->wait_list;){
os_task_t* p_thread = os_list_member_of(p, os_task_t, node);
p = p->next;
os_list_remove(&p_thread->node);
// 将任务加入就绪表
os_rdy_list_insert(p_thread);
p_thread->remain_ticks = p_thread->init_ticks;
// 尝试抢占当前任务
if(p_curr_thread_p && p_curr_thread_p->state==kOsTaskState_Running){
if(os_priority_is_high(p_thread->curr_priority, p_curr_thread_p->curr_priority)){
os_priority_set(p_curr_thread_p->curr_priority);
os_rdy_list_insert_head(p_curr_thread_p); // 放到头部,这样下次调度可以尽快调度这个任务
p_curr_thread_p->state = kOsTaskState_Ready; // 就绪状态
}
}
}
os_critical_leave_in_isr();
os_sched_in_isr();
}
+137
View File
@@ -0,0 +1,137 @@
#ifndef INCLUDED_OS_WAITOBJECT_H
#define INCLUDED_OS_WAITOBJECT_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_LIST_H
#include <os_list.h>
#endif /*INCLUDED_OS_LIST_H*/
#ifndef INCLUDED_OS_TIMEWHEEL_H
#include <os_timewheel.h>
#endif /*INCLUDED_OS_TIMEWHEEL_H*/
#ifndef INCLUDED_OS_TASK_H
#include <os_task.h>
#endif /*INCLUDED_OS_TASK_H*/
#ifndef INCLUDED_OS_CRITICAL_H
#include <os_critical.h>
#endif /*INCLUDED_OS_CRITICAL_H*/
#ifndef INCLUDED_OS_RDY_LIST_H
#include <os_rdy_list.h>
#endif /*INCLUDED_OS_RDY_LIST_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct {
os_list_t wait_list;
}os_waitobject_t;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void os_waitobject_init(os_waitobject_t* self){
os_list_init(&self->wait_list);
}
OS_STATIC_FORCE_INLINE
void os_waitobject_wait_infinity(os_waitobject_t* self, os_task_t* task){
os_list_remove(&task->node);
os_list_insert_before(&self->wait_list, &task->node);
task->state = kOsTaskState_Wait;
task->errors = OS_ERR_OK;
}
void os_waitobject_on_timeout(os_timer_t* timer);
os_err_t os_waitobject_timed_wait(os_waitobject_t* self, os_task_t* task, os_tick_t ticks);
os_err_t os_waitobject_wait_until(os_waitobject_t* self, os_task_t* task, os_tick_t ticks);
OS_STATIC_FORCE_INLINE
void os_waitobject_wait(os_waitobject_t* self, os_task_t* task){
os_waitobject_timed_wait(self, task, OS_WAIT_INFINITY);
}
OS_STATIC_FORCE_INLINE
void os_waitobject_notify_one(os_waitobject_t* self){
os_critical_enter();
if(os_list_is_empty(&self->wait_list)){
os_critical_leave();
return;
}
os_bool_t is_need_schedule_flag = OS_FALSE;
os_list_node_t* p = self->wait_list.next;
os_list_remove(p);
os_task_t* p_thread = os_list_member_of(p, os_task_t, node);
os_rdy_list_insert(p_thread);
p_thread->remain_ticks = p_thread->init_ticks;
// 尝试抢占当前任务
os_task_t* p_curr_thread_p = os_task_self();
if(p_curr_thread_p && p_curr_thread_p->state==kOsTaskState_Running){
if(os_priority_is_high(p_thread->curr_priority, p_curr_thread_p->curr_priority)){
os_priority_set(p_curr_thread_p->curr_priority);
os_rdy_list_insert_head(p_curr_thread_p); // 放到头部,这样下次调度可以尽快调度这个任务
p_curr_thread_p->state = kOsTaskState_Ready; // 就绪状态
// 不要改变时间窗
is_need_schedule_flag = OS_TRUE;
}
}
os_critical_leave();
if(is_need_schedule_flag) {
os_sched();
}
}
OS_STATIC_FORCE_INLINE
void os_waitobject_notify_all(os_waitobject_t * self){
os_critical_enter();
os_bool_t is_need_schedule_flag = OS_FALSE;
os_list_node_t* p = self->wait_list.next;
os_task_t* p_curr_thread_p = os_task_self();
for(;p!=&self->wait_list;){
os_task_t* p_thread = os_list_member_of(p, os_task_t, node);
p = p->next;
os_list_remove(&p_thread->node);
// 将任务加入就绪表
os_rdy_list_insert(p_thread);
// p_thread->state = OS_TASK_STATE_READY;
p_thread->remain_ticks = p_thread->init_ticks;
// 尝试抢占当前任务
if(p_curr_thread_p && p_curr_thread_p->state==kOsTaskState_Running){
if(os_priority_is_high(p_thread->curr_priority, p_curr_thread_p->curr_priority)){
os_priority_set(p_curr_thread_p->curr_priority);
os_rdy_list_insert_head(p_curr_thread_p); // 放到头部,这样下次调度可以尽快调度这个任务
p_curr_thread_p->state = kOsTaskState_Ready; // 就绪状态
is_need_schedule_flag = OS_TRUE;
}
}
}
os_critical_leave();
if(is_need_schedule_flag){
os_sched();
}
}
void os_waitobject_notify_one_in_isr(os_waitobject_t* self);
void os_waitobject_notify_all_in_isr(os_waitobject_t * self);
#endif /*INCLUDED_OS_WAITOBJECT_H*/
+3
View File
@@ -0,0 +1,3 @@
#include <os_yield_list.h>
volatile os_yield_list_t g_os_yield_list;
+51
View File
@@ -0,0 +1,51 @@
#ifndef INCLUDED_OS_YIELD_LIST_H
#define INCLUDED_OS_YIELD_LIST_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_LIST_H
#include <os_list.h>
#endif /*INCLUDED_OS_LIST_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
#ifndef INCLUDED_OS_TASK_H
#include <os_task.h>
#endif /*INCLUDED_OS_TASK_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef os_list_t os_yield_list_t;
extern volatile os_yield_list_t g_os_yield_list;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void os_yield_list_init(void){
os_list_init(&g_os_yield_list);
}
OS_STATIC_FORCE_INLINE
void os_yield_list_insert(os_task_t* p_task){
os_list_insert_before(&g_os_yield_list, &p_task->node);
p_task->state = kOsTaskState_Yield;
}
OS_STATIC_FORCE_INLINE
void os_yield_list_remove(os_task_t* p_task){
os_list_remove(&p_task->node);
}
#endif /*INCLUDED_OS_YIELD_LIST_H*/