import
This commit is contained in:
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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*/
|
||||
@@ -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*/
|
||||
@@ -0,0 +1 @@
|
||||
#include <os_countdownlatch.h>
|
||||
@@ -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*/
|
||||
@@ -0,0 +1 @@
|
||||
#include "os_critical.h"
|
||||
@@ -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 */
|
||||
@@ -0,0 +1 @@
|
||||
#include <os_fairlock.h>
|
||||
@@ -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*/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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*/
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <os_isr.h>
|
||||
|
||||
volatile os_size_t g_os_isr_nesting_cnt;
|
||||
@@ -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*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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*/
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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*/
|
||||
@@ -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];
|
||||
|
||||
/* ======================================================================================================================== */
|
||||
/* 接口方法实现 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -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];
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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*/
|
||||
@@ -0,0 +1 @@
|
||||
#include <os_sem.h>
|
||||
@@ -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*/
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <os_systick.h>
|
||||
|
||||
volatile os_tick_t g_os_systick_ticks;
|
||||
@@ -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*/
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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*/
|
||||
@@ -0,0 +1,2 @@
|
||||
#include <os_timer.h>
|
||||
|
||||
@@ -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*/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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*/
|
||||
@@ -0,0 +1 @@
|
||||
#include <os_utils.h>
|
||||
@@ -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*/
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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*/
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <os_yield_list.h>
|
||||
|
||||
volatile os_yield_list_t g_os_yield_list;
|
||||
@@ -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*/
|
||||
Reference in New Issue
Block a user