新增对于SMP的支持,实现SMP下核间互斥,亲和性等功能的支持,新版本的SMP分支对原有的robin调度和抢占式优先级调度情况均支持。实现对已有所有功能的SMP支持,可以完全兼容已有的API,原有单核程序无需更改任何的API仅需定义USE_SMP的宏为1即可在SMP环境下多核运行。如果需要打开亲和性的支持仅需定义configUSE_CORE_AFFINITY宏为1即可。

This commit is contained in:
sherecho 2024-10-10 16:16:38 +08:00
parent 86a62a3d45
commit 9acf24a83e
41 changed files with 1470 additions and 58 deletions

View File

@ -16,8 +16,10 @@
*---------------------------------------------------------------------------*/
#include "tos_k.h"
#include "core_cm0plus.h"
__PORT__ void port_cpu_reset(void)
{
NVIC_SystemReset();

View File

@ -0,0 +1,99 @@
#ifndef _PICOPORTMACRO_
#define _PICOPORTMACRO_
#include "hardware/sync.h"
#include "hardware/exception.h"//用于修改中断处理函数的头文件
#include "pico/multicore.h"
#include "hardware/clocks.h"
#include "hardware/exception.h"
#include "hardware/irq.h"
#include "pico.h"
#include <assert.h>
#include <stdio.h>
#ifndef configSMP_SPINLOCK_0
#define configSMP_SPINLOCK_0 PICO_SPINLOCK_ID_OS1
#endif
#ifndef configSMP_SPINLOCK_1
#define configSMP_SPINLOCK_1 PICO_SPINLOCK_ID_OS2
#endif
/* Define to trap errors during development. */
#define configASSERT(x) assert(x)
#define INVALID_PRIMARY_CORE_NUM 0xffu
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
//
/* Multi-core */
#define portMAX_CORE_COUNT 2
/* Requires for SMP */
#define portCRITICAL_NESTING_IN_TCB 1
//获取core ID
#define port_GET_CORE_ID() get_core_num()
//这些宏定义在实现实时操作系统RTOS用于控制中断和任务切换的操作
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
//决定是否需要任务切换
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
typedef uint32_t BaseType_t;
#define portRTOS_SPINLOCK_COUNT 2
#define portRESTORE_INTERRUPTS(ulState) __asm volatile ("msr PRIMASK,%0"::"r" (ulState) : )
/* Note this is a single method with uxAcquire parameter since we have
* static vars, the method is always called with a compile time constant for
* uxAcquire, and the compiler should dothe right thing! */
extern uint8_t ucOwnedByCore[ portMAX_CORE_COUNT ];
extern uint8_t ucRecursionCountByLock[ portRTOS_SPINLOCK_COUNT ];
static void vPortRecursiveLock(uint32_t ulLockNum, spin_lock_t *pxSpinLock, BaseType_t uxAcquire) {
configASSERT(ulLockNum >= 0 && ulLockNum < portRTOS_SPINLOCK_COUNT );
uint32_t ulCoreNum = get_core_num();
uint32_t ulLockBit = 1u << ulLockNum;
configASSERT(ulLockBit < 256u );
if( uxAcquire )
{
//printf("Acquire spinlock core !%d \r\n", ulCoreNum);
if( __builtin_expect( !*pxSpinLock, 0 ) )
{
if( ucOwnedByCore[ulCoreNum] & ulLockBit )
{
configASSERT(ucRecursionCountByLock[ulLockNum] != 255u );
ucRecursionCountByLock[ulLockNum]++;
return;
}
while ( __builtin_expect( !*pxSpinLock, 0 ) );
}
__mem_fence_acquire();
configASSERT(ucRecursionCountByLock[ulLockNum] == 0 );
ucRecursionCountByLock[ulLockNum] = 1;
ucOwnedByCore[ulCoreNum] |= ulLockBit;
} else {
//printf("Release spinlock core !%d \r\n", ulCoreNum);
configASSERT((ucOwnedByCore[ulCoreNum] & ulLockBit) != 0 );
configASSERT(ucRecursionCountByLock[ulLockNum] != 0 );
if( !--ucRecursionCountByLock[ulLockNum] )
{
ucOwnedByCore[ulCoreNum] &= ~ulLockBit;
__mem_fence_release();
*pxSpinLock = 1;
}
}
}
#define portGET_ISR_LOCK() vPortRecursiveLock(0, spin_lock_instance(configSMP_SPINLOCK_0), (BaseType_t)1)
#define portRELEASE_ISR_LOCK() vPortRecursiveLock(0, spin_lock_instance(configSMP_SPINLOCK_0), (BaseType_t)0)
#define portGET_TASK_LOCK() vPortRecursiveLock(1, spin_lock_instance(configSMP_SPINLOCK_1), (BaseType_t)1)
#define portRELEASE_TASK_LOCK() vPortRecursiveLock(1, spin_lock_instance(configSMP_SPINLOCK_1), (BaseType_t) 0)
#define portCHECK_IF_IN_ISR() ({ \
uint32_t ulIPSR; \
__asm volatile ("mrs %0, IPSR" : "=r" (ulIPSR)::); \
((uint8_t)ulIPSR)>0;})
#endif

View File

@ -0,0 +1,81 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _PORT_H_
#define _PORT_H_
#include "picoPortMacro.h"
__PORT__ void port_int_disable(void);
__PORT__ void port_int_enable(void);
__PORT__ cpu_cpsr_t port_cpsr_save(void);
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
__PORT__ void port_cpu_reset(void);
__PORT__ void port_sched_start(void) __NO_RETURN__;
__PORT__ void port_context_switch(void);
__PORT__ void port_irq_context_switch(void);
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
__PORT__ void port_systick_priority_set(uint32_t prio);
#if TOS_CFG_TICKLESS_EN > 0u
__PORT__ void port_systick_resume(void);
__PORT__ void port_systick_suspend(void);
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
__PORT__ void port_systick_pending_reset(void);
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
__PORT__ void port_sleep_mode_enter(void);
__PORT__ void port_stop_mode_enter(void);
__PORT__ void port_standby_mode_enter(void);
#endif
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
__PORT__ void HardFault_Handler(void);
__PORT__ void port_fault_diagnosis(void);
#endif
#if USE_SMP > 0u
__PORT__ void portSCHED_CORE (int xCoreID );
__PORT__ static void prvFIFOInterruptHandler(void);
__PORT__ void port_smp_init_kernel(void);
#define port_multicore_launch(x) multicore_launch_core1(x)
extern uint8_t ucPrimaryCoreNum ;
#endif
#endif /* _PORT_H_ */

View File

@ -0,0 +1,178 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
#include "core_cm0plus.h"
extern __KNL__ void knl_sched(void);
__PORT__ void port_cpu_reset(void)
{
NVIC_SystemReset();
}
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
{
(void)SysTick_Config(cycle_per_tick);
}
__PORT__ void port_systick_priority_set(uint32_t prio)
{
NVIC_SetPriority(SysTick_IRQn, prio);
}
#if TOS_CFG_TICKLESS_EN > 0u
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
{
k_time_t max_millisecond;
uint32_t max_cycle;
max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit
max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second
return max_millisecond;
}
__PORT__ void port_systick_resume(void)
{
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
__PORT__ void port_systick_suspend(void)
{
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
{
port_systick_config(cycle_per_tick);
}
__PORT__ void port_systick_pending_reset(void)
{
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
}
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
__PORT__ void port_sleep_mode_enter(void)
{
#if 1
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
#else
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
#endif
}
__PORT__ void port_stop_mode_enter(void)
{
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
__PORT__ void port_standby_mode_enter(void)
{
HAL_PWR_EnterSTANDBYMode();
}
#endif
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
__PORT__ void port_fault_diagnosis(void)
{
k_fault_log_writer("fault diagnosis is not supported in CORTEX M0+\n");
}
/*------------------ RealView Compiler -----------------*/
/* V5 */
#if defined(__CC_ARM)
__PORT__ __ASM__ void HardFault_Handler(void)
{
IMPORT fault_backtrace
MOV r0, lr
TST lr, #0x04
ITE EQ
MRSEQ r1, MSP
MRSNE r1, PSP
BL fault_backtrace
}
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
__PORT__ void __NAKED__ HardFault_Handler(void)
{
__ASM__ __VOLATILE__ (
"MOV r0, lr\n\t"
"TST lr, #0x04\n\t"
"ITE EQ\n\t"
"MRSEQ r1, MSP\n\t"
"MRSNE r1, PSP\n\t"
"BL fault_backtrace\n\t"
);
}
#endif /* ARMCC VERSION */
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
#if USE_SMP ==1u
#define INVALID_PRIMARY_CORE_NUM 0xffu
uint8_t ucPrimaryCoreNum = INVALID_PRIMARY_CORE_NUM;
__PORT__ void portSCHED_CORE (int xCoreID ){
assert(xCoreID != port_GET_CORE_ID());
#if USE_SMP>0u
/* Non blocking, will cause interrupt on other core if the queue isn't already full,
in which case an IRQ must be pending */
sio_hw->fifo_wr = 0;
#endif
}
__PORT__ __STATIC__ void prvFIFOInterruptHandler(void)
{
/* We must remove the contents (which we don't care about)
* to clear the IRQ */
multicore_fifo_drain();
/* And explicitly clear any other IRQ flags */
multicore_fifo_clear_irq();
#if (USE_SMP == 1u)
//portYIELD_FROM_ISR(1);
//port_context_switch();
knl_sched();
#endif /* portRUNNING_ON_BOTH_CORES */
}
__PORT__ void port_smp_init_kernel(void){
//设置PENDSV_EXCEPTION中断处理函数用于切换上下文
//exception_set_exclusive_handler( PENDSV_EXCEPTION, PendSV_smp_Handler);
/* Install FIFO handler to receive interrupt from other core */
multicore_fifo_clear_irq();
multicore_fifo_drain();
uint32_t ulIRQNum = SIO_IRQ_PROC0 + get_core_num();
irq_set_priority( ulIRQNum, portMIN_INTERRUPT_PRIORITY );
irq_set_exclusive_handler( ulIRQNum, prvFIFOInterruptHandler );
irq_set_enabled( ulIRQNum, 1 );
}
uint8_t ucOwnedByCore[ portMAX_CORE_COUNT ]={0};
uint8_t ucRecursionCountByLock[ portRTOS_SPINLOCK_COUNT ]={0};
#endif

View File

@ -0,0 +1,30 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _PORT_CONFIG_H_
#define _PORT_CONFIG_H_
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32
#define TOS_CFG_CPU_HRTIMER_EN 0u
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
#endif /* _PORT_CONFIG_H_ */

View File

@ -0,0 +1,213 @@
.equ SMP, 1
.global port_int_disable
.global port_int_enable
.global port_cpsr_save
.global port_cpsr_restore
.global port_sched_start
.global port_context_switch
.global port_irq_context_switch
.ifdef SMP
.global PendSV_smp_Handler
.global k_curr_tasks
.global k_next_tasks
.else
.global PendSV_Handler
.global k_curr_task
.global k_next_task
.endif
.equ NVIC_INT_CTRL , 0xE000ED04 @Interrupt control state register.
.equ NVIC_SYSPRI14 , 0xE000ED20 @System priority register (priority 14).
.equ NVIC_PENDSV_PRI , 0x00FF0000 @ PendSV priority value (lowest).
.equ NVIC_PENDSVSET , 0x10000000 @ Value to trigger PendSV exception.
.equ SIO_ID , 0xD0000000 @ code ID
.text
.align 2
.thumb
.syntax unified
.type port_int_disable, %function
port_int_disable:
CPSID I
BX LR
.type port_int_enable, %function
port_int_enable:
CPSIE I
BX LR
.type port_cpsr_save, %function
port_cpsr_save:
MRS R0, PRIMASK
CPSID I
BX LR
.type port_cpsr_restore, %function
port_cpsr_restore:
MSR PRIMASK, R0
BX LR
.thumb_func
.type port_sched_start, %function
port_sched_start:
LDR R0, =NVIC_SYSPRI14
LDR R1, =NVIC_PENDSV_PRI
STR R1, [R0]
MOVS R0, #0
MSR PSP, R0
LDR R0, =NVIC_INT_CTRL
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
CPSIE I
__unreachable:
B __unreachable
.thumb_func
.type port_context_switch, %function
port_context_switch:
LDR R0, =NVIC_INT_CTRL
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
BX LR
.thumb_func
.type port_irq_context_switch, %function
port_irq_context_switch:
LDR R0, =NVIC_INT_CTRL
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
BX LR
.ifdef SMP
.thumb_func
.type PendSV_smp_Handler, %function
PendSV_smp_Handler:
CPSID I
MRS R0, PSP
CMP R0, #0
BEQ PendSVHandler_smp_nosave
SUBS R0, R0, #0x20
STMIA R0!, {R4 - R7}
MOV R4, R8
MOV R5, R9
MOV R6, R10
MOV R7, R11
STMIA R0!, {R4-R7}
SUBS R0, R0, #0x20
LDR R1, =k_curr_tasks
LDR R2, = SIO_ID
LDR R2, [R2]
LSLS R2 ,R2 ,#2
ADDS R1, R2
LDR R1, [R1]
STR R0, [R1]
PendSVHandler_smp_nosave:
LDR R0, =k_curr_tasks
LDR R1, =k_next_tasks
@R3= Core number
LDR R3, = SIO_ID
LDR R3, [R3]
LSLS R3 ,R3 ,#2
@R0=&k_curr_tasks[Core number]
ADDS R0, R3
@R1=&k_next_tasks[Core number]
ADDS R1, R3
@R2=k_next_tasks[Core number]
LDR R2, [R1]
@k_curr_tasks[Core number]=k_next_tasks[Core number]
STR R2, [R0]
LDR R0, [R2]
LDMIA R0!, {R4 - R7}
LDMIA R0!, {R2 - R3}
MOV R8, R2
MOV R9, R3
LDMIA R0!, {R2 - R3}
MOV R10, R2
MOV R11, R3
MSR PSP, R0
MOV R0, R14
MOVS R1, #0x04
ORRS R0, R1
MOV R14, R0
CPSIE I
BX LR
.else
.thumb_func
.type PendSV_Handler, %function
PendSV_Handler:
CPSID I
MRS R0, PSP
CMP R0, #0
BEQ PendSVHandler_nosave
SUBS R0, R0, #0x20
STMIA R0!, {R4 - R7}
MOV R4, R8
MOV R5, R9
MOV R6, R10
MOV R7, R11
STMIA R0!, {R4-R7}
SUBS R0, R0, #0x20
LDR R1, =k_curr_task
LDR R1, [R1]
STR R0, [R1]
PendSVHandler_nosave:
LDR R0, =k_curr_task
LDR R1, =k_next_task
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2]
LDMIA R0!, {R4 - R7}
LDMIA R0!, {R2 - R3}
MOV R8, R2
MOV R9, R3
LDMIA R0!, {R2 - R3}
MOV R10, R2
MOV R11, R3
MSR PSP, R0
MOV R0, R14
MOVS R1, #0x04
ORRS R0, R1
MOV R14, R0
CPSIE I
BX LR
.endif
.end

View File

@ -20,12 +20,14 @@
/* interrupt nesting count */
extern k_nesting_t k_irq_nest_cnt;
extern k_nesting_t k_irq_nest_cnts[configNUM_CORES];
/* schedule lock nesting count */
extern k_nesting_t k_sched_lock_nest_cnt;
/* kernel running state */
extern knl_state_t k_knl_state;
extern knl_state_t k_knl_states[configNUM_CORES];
/* ready queue of tasks */
extern readyqueue_t k_rdyq;
@ -35,15 +37,21 @@ extern k_tick_t k_tick_count;
/* current task */
extern k_task_t *k_curr_task;
extern k_task_t *k_curr_tasks[configNUM_CORES];
#define k_curr_task TaskGetCurrentKernelTaskHandle()
k_task_t * TaskGetCurrentKernelTaskHandle(void);
/* next task to run */
extern k_task_t *k_next_task;
extern k_task_t *k_next_tasks[configNUM_CORES];
/* idle task related stuff */
extern k_task_t k_idle_task;
extern k_task_t k_idle_tasks[configNUM_CORES];
extern k_stack_t k_idle_task_stk[];
extern k_stack_t *const k_idle_task_stk_addr;
extern size_t const k_idle_task_stk_size;
extern k_stack_t k_idle_core1_task_stk[TOS_CFG_IDLE_TASK_STK_SIZE];
extern k_stack_t *const k_idle_task_stk_addrs[configNUM_CORES];
#if TOS_CFG_OBJ_DYNAMIC_CREATE_EN > 0u
/* list to hold all the destroyed dynamic created tasks */
extern k_list_t k_dead_task_list;

View File

@ -68,6 +68,11 @@
#endif
#include <tos_global.h>
#include <tos_version.h>
// #ifndef portGET_TASK_LOCK()
// #define portGET_TASK_LOCK()
// #endif
// #ifndef portRELEASE_TASK_LOCK()
// #define portRELEASE_TASK_LOCK()
// #endif
#endif /* _TOS_K_H_ */

View File

@ -37,6 +37,7 @@ __KNL__ void readyqueue_init(void);
__KNL__ int readyqueue_is_prio_onlyone(k_prio_t prio);
__KNL__ k_task_t *readyqueue_first_task_get(k_prio_t prio);
__KNL__ k_task_t *readyqueue_first_task_get_smp(k_prio_t prio,int corenum);
__KNL__ k_task_t *readyqueue_highest_ready_task_get(void);

View File

@ -19,6 +19,8 @@
#define _TOS_SYS_H_
__CDECLS_BEGIN
#define configMAX_TASK_NAME_LEN 16
#define configIDLE_TASK_NAME "idle"
#define K_NESTING_LIMIT_IRQ (k_nesting_t)250u
#define K_NESTING_LIMIT_SCHED_LOCK (k_nesting_t)250u
@ -165,6 +167,18 @@ __API__ k_err_t tos_knl_sched_lock(void);
* @retval K_ERR_NONE return successfully.
*/
__API__ k_err_t tos_knl_sched_unlock(void);
/////////////////new for smp//////////////////////////////////////////
#if (USE_SMP ==1u)
__API__ static void prvDisableInterruptsAndPortStartSchedulerOnCore( void );
__API__ void smp_init_core0(void);
__API__ k_err_t tos_knl_smp_init(void);
__KNL__ int knl_is_idle_pre(k_task_t *task);
__API__ k_err_t tos_knl_start_smp(void);
#if ( configUSE_CORE_AFFINITY == 1u )
__API__ void tos_TaskCoreAffinitySet( k_task_t * Task, BaseType_t CoreAffinityMask );
__API__ BaseType_t vTaskCoreAffinityGet( const k_task_t * Task );
#endif
#endif
#if TOS_CFG_TICKLESS_EN > 0u
__KNL__ k_tick_t knl_next_expires_get(void);

View File

@ -131,6 +131,13 @@ struct k_task_st {
k_event_flag_t *flag_match; /**< if we pend an event successfully, flag_match will be set by the event poster, and will be returned
by tos_event_pend to the caller */
#endif
#if (USE_SMP == 1u )
BaseType_t RunningOnCore;
BaseType_t IsIDLE;
#if ( configUSE_CORE_AFFINITY == 1u )
BaseType_t CoreAffinityMask;
#endif
#endif
};
/**
@ -434,7 +441,13 @@ __DEBUG__ __STATIC_INLINE__ void task_default_walker(k_task_t *task)
state_str = state_str;
tos_kprintln("tsk name: %s", task->name);
#if(USE_SMP==1u)
if(task->RunningOnCore!=-1){
state_str = "RUNNING";
}
else
#endif
{
if (tos_task_curr_task_get() == task) {
state_str = "RUNNING";
} else if (task->state == K_TASK_STATE_PENDTIMEOUT_SUSPENDED) {
@ -454,6 +467,7 @@ __DEBUG__ __STATIC_INLINE__ void task_default_walker(k_task_t *task)
} else if (task->state == K_TASK_STATE_READY) {
state_str = "READY";
}
}
tos_kprintln("tsk stat: %s", state_str);
tos_kprintln("stk size: %d", task->stk_size);

View File

@ -43,12 +43,16 @@ __API__ k_err_t tos_barrier_destroy(k_barrier_t *barrier)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&barrier->pend_obj, PEND_STATE_DESTROY);
pend_object_deinit(&barrier->pend_obj);
TOS_OBJ_DEINIT(barrier);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -65,7 +69,9 @@ __API__ k_err_t tos_barrier_pend(k_barrier_t *barrier)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (barrier->count == 0u) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_BARRIER_OVERFLOW;
}
@ -74,11 +80,13 @@ __API__ k_err_t tos_barrier_pend(k_barrier_t *barrier)
barrier->count = (k_barrier_cnt_t)0u;
pend_wakeup_all(&barrier->pend_obj, PEND_STATE_POST);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
@ -86,6 +94,7 @@ __API__ k_err_t tos_barrier_pend(k_barrier_t *barrier)
--barrier->count;
pend_task_block(k_curr_task, &barrier->pend_obj, TOS_TIME_FOREVER);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -100,7 +109,9 @@ __API__ k_err_t tos_barrier_reset(k_barrier_t *barrier, k_barrier_cnt_t count)
TOS_OBJ_VERIFY(barrier, KNL_OBJ_TYPE_BARRIER);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
barrier->count = count;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;

View File

@ -218,10 +218,12 @@ __API__ k_err_t tos_bin_heap_push(k_bin_heap_t *bin_heap, void *item, size_t ite
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
bin_heap_item_copy_from(bin_heap, item);
bin_heap_percolate_up(bin_heap, item);
bin_heap_item_increase(bin_heap);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -235,6 +237,7 @@ __API__ k_err_t tos_bin_heap_pop(k_bin_heap_t *bin_heap, void *item, size_t *ite
TOS_OBJ_VERIFY(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (tos_bin_heap_is_empty(bin_heap)) {
TOS_CPU_INT_ENABLE();
@ -245,6 +248,7 @@ __API__ k_err_t tos_bin_heap_pop(k_bin_heap_t *bin_heap, void *item, size_t *ite
bin_heap_item_decrease(bin_heap);
bin_heap_percolate_down(bin_heap);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
@ -258,7 +262,11 @@ __API__ k_err_t tos_bin_heap_flush(k_bin_heap_t *bin_heap)
TOS_OBJ_VERIFY(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
bin_heap->total = 0;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
@ -273,7 +281,9 @@ __API__ int tos_bin_heap_is_empty(k_bin_heap_t *bin_heap)
TOS_OBJ_VERIFY_RC(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP, K_FALSE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
is_empty = (bin_heap->total == 0);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return is_empty;
@ -288,7 +298,9 @@ __API__ int tos_bin_heap_is_full(k_bin_heap_t *bin_heap)
TOS_OBJ_VERIFY_RC(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP, K_FALSE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
is_full = (bin_heap->total == bin_heap->item_cnt ? K_TRUE : K_FALSE);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return is_full;

View File

@ -114,16 +114,18 @@ __API__ int tos_chr_fifo_push_stream(k_chr_fifo_t *chr_fifo, uint8_t *stream, si
TOS_OBJ_VERIFY_RC(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO, 0);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
while (i < size) {
err = tos_ring_q_enqueue(&chr_fifo->ring_q, &stream[i], sizeof(uint8_t));
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return i;
}
++i;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return i;
}
@ -147,14 +149,17 @@ __API__ int tos_chr_fifo_pop_stream(k_chr_fifo_t *chr_fifo, uint8_t *buffer, siz
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
while (i < size) {
if (tos_ring_q_dequeue(&chr_fifo->ring_q, &data, K_NULL) != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return i;
}
buffer[i++] = data;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return i;
}

View File

@ -39,12 +39,15 @@ __API__ k_err_t tos_completion_destroy(k_completion_t *completion)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&completion->pend_obj, PEND_STATE_DESTROY);
pend_object_deinit(&completion->pend_obj);
TOS_OBJ_DEINIT(completion);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -60,24 +63,30 @@ __API__ k_err_t tos_completion_pend_timed(k_completion_t *completion, k_tick_t t
TOS_OBJ_VERIFY(completion, KNL_OBJ_TYPE_COMPLETION);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (completion->done > (completion_done_t)0u) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (timeout == TOS_TIME_NOWAIT) { // no wait, return immediately
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
pend_task_block(k_curr_task, &completion->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -98,7 +107,10 @@ __STATIC__ k_err_t completion_do_post(k_completion_t *completion, opt_post_t opt
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (completion->done == (completion_done_t)-1) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_COMPLETION_OVERFLOW;
}
@ -106,12 +118,14 @@ __STATIC__ k_err_t completion_do_post(k_completion_t *completion, opt_post_t opt
++completion->done;
if (pend_is_nopending(&completion->pend_obj)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
pend_wakeup(&completion->pend_obj, PEND_STATE_POST, opt);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -136,7 +150,9 @@ __API__ k_err_t tos_completion_reset(k_completion_t *completion)
TOS_OBJ_VERIFY(completion, KNL_OBJ_TYPE_COMPLETION);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
completion->done = (completion_done_t)0u;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
@ -151,7 +167,9 @@ __API__ int tos_completion_is_done(k_completion_t *completion)
TOS_OBJ_VERIFY_RC(completion, KNL_OBJ_TYPE_COMPLETION, K_FALSE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
is_done = (completion->done > (completion_done_t)0u ? K_TRUE : K_FALSE);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return is_done;

View File

@ -39,12 +39,14 @@ __API__ k_err_t tos_countdownlatch_destroy(k_countdownlatch_t *countdownlatch)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&countdownlatch->pend_obj, PEND_STATE_DESTROY);
pend_object_deinit(&countdownlatch->pend_obj);
TOS_OBJ_DEINIT(countdownlatch);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -61,23 +63,28 @@ __API__ k_err_t tos_countdownlatch_pend_timed(k_countdownlatch_t *countdownlatch
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (countdownlatch->count == (k_countdownlatch_cnt_t)0u) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (timeout == TOS_TIME_NOWAIT) { // no wait, return immediately
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
pend_task_block(k_curr_task, &countdownlatch->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -97,8 +104,10 @@ __API__ k_err_t tos_countdownlatch_post(k_countdownlatch_t *countdownlatch)
TOS_OBJ_VERIFY(countdownlatch, KNL_OBJ_TYPE_COUNTDOWNLATCH);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (countdownlatch->count == (k_countdownlatch_cnt_t)0) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_COUNTDOWNLATCH_OVERFLOW;
}
@ -106,12 +115,14 @@ __API__ k_err_t tos_countdownlatch_post(k_countdownlatch_t *countdownlatch)
--countdownlatch->count;
if (countdownlatch->count > (k_countdownlatch_cnt_t)0) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
pend_wakeup_one(&countdownlatch->pend_obj, PEND_STATE_POST);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -126,7 +137,9 @@ __API__ k_err_t tos_countdownlatch_reset(k_countdownlatch_t *countdownlatch, k_c
TOS_OBJ_VERIFY(countdownlatch, KNL_OBJ_TYPE_COUNTDOWNLATCH);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
countdownlatch->count = count;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;

View File

@ -49,6 +49,7 @@ __API__ k_err_t tos_event_destroy(k_event_t *event)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&event->pend_obj, PEND_STATE_DESTROY);
event->flag = (k_event_flag_t)0u;
@ -61,6 +62,7 @@ __API__ k_err_t tos_event_destroy(k_event_t *event)
knl_object_alloc_reset(&event->knl_obj);
#endif
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -105,6 +107,7 @@ __API__ k_err_t tos_event_destroy_dyn(k_event_t *event)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&event->pend_obj, PEND_STATE_DESTROY);
event->flag = (k_event_flag_t)0u;
@ -115,6 +118,7 @@ __API__ k_err_t tos_event_destroy_dyn(k_event_t *event)
tos_mmheap_free(event);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -158,20 +162,24 @@ __API__ k_err_t tos_event_pend(k_event_t *event, k_event_flag_t flag_expect, k_e
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (event_is_match(event->flag, flag_expect, flag_match, opt_pend)) {
if (opt_pend & TOS_OPT_EVENT_PEND_CLR) { // destroy the bridge after get across the river
event->flag = (k_event_flag_t)0u;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (timeout == TOS_TIME_NOWAIT) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
@ -182,6 +190,7 @@ __API__ k_err_t tos_event_pend(k_event_t *event, k_event_flag_t flag_expect, k_e
pend_task_block(k_curr_task, &event->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -207,6 +216,7 @@ __STATIC__ k_err_t event_do_post(k_event_t *event, k_event_flag_t flag, opt_even
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
TOS_LIST_FOR_EACH_ENTRY_SAFE(task, tmp, k_task_t, pend_list, &event->pend_obj.list) {
if (event_is_match(event->flag, task->flag_expect, task->flag_match, task->opt_event_pend)) {
@ -220,6 +230,7 @@ __STATIC__ k_err_t event_do_post(k_event_t *event, k_event_flag_t flag, opt_even
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();

View File

@ -18,17 +18,34 @@
#include <tos_k.h>
k_nesting_t k_irq_nest_cnt = (k_nesting_t)0;
k_nesting_t k_irq_nest_cnts[configNUM_CORES] = {(k_nesting_t)0};
k_nesting_t k_sched_lock_nest_cnt = (k_nesting_t)0;
knl_state_t k_knl_state = KNL_STATE_STOPPED;
knl_state_t k_knl_states[configNUM_CORES] = {KNL_STATE_STOPPED};
readyqueue_t k_rdyq;
k_tick_t k_tick_count = (k_tick_t)0u;
k_task_t *k_curr_task = K_NULL;
k_task_t *k_next_task = K_NULL;
//k_task_t *k_curr_task = K_NULL;
k_task_t * k_curr_tasks[configNUM_CORES] = {K_NULL};
k_task_t * TaskGetCurrentKernelTaskHandle(void){
k_task_t * xReturn;
TOS_CPU_CPSR_ALLOC();
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
xReturn = k_curr_tasks[ port_GET_CORE_ID() ];
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return xReturn;
}
k_task_t *k_next_task = K_NULL;
k_task_t *k_next_tasks[configNUM_CORES] = {K_NULL};
k_task_t k_idle_tasks[configNUM_CORES] ;
k_task_t k_idle_task;
k_stack_t k_idle_task_stk[TOS_CFG_IDLE_TASK_STK_SIZE];
k_stack_t k_idle_core1_task_stk[TOS_CFG_IDLE_TASK_STK_SIZE];
k_stack_t *const k_idle_task_stk_addrs[configNUM_CORES]={&k_idle_task_stk[0],&k_idle_core1_task_stk[0]};
k_stack_t *const k_idle_task_stk_addr = &k_idle_task_stk[0];
size_t const k_idle_task_stk_size = TOS_CFG_IDLE_TASK_STK_SIZE;

View File

@ -52,8 +52,10 @@ __API__ k_err_t tos_mail_q_destroy(k_mail_q_t *mail_q)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
err = tos_ring_q_destroy(&mail_q->ring_q);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -65,6 +67,7 @@ __API__ k_err_t tos_mail_q_destroy(k_mail_q_t *mail_q)
TOS_OBJ_DEINIT(mail_q);
knl_object_alloc_reset(&mail_q->knl_obj);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -103,9 +106,10 @@ __API__ k_err_t tos_mail_q_destroy_dyn(k_mail_q_t *mail_q)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
err = tos_ring_q_destroy_dyn(&mail_q->ring_q);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -117,6 +121,7 @@ __API__ k_err_t tos_mail_q_destroy_dyn(k_mail_q_t *mail_q)
TOS_OBJ_DEINIT(mail_q);
knl_object_alloc_reset(&mail_q->knl_obj);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -142,19 +147,22 @@ __API__ k_err_t tos_mail_q_pend(k_mail_q_t *mail_q, void *mail_buf, size_t *mail
TOS_OBJ_VERIFY(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (tos_ring_q_dequeue(&mail_q->ring_q, mail_buf, mail_size) == K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (timeout == TOS_TIME_NOWAIT) {
*mail_size = 0;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
@ -162,6 +170,7 @@ __API__ k_err_t tos_mail_q_pend(k_mail_q_t *mail_q, void *mail_buf, size_t *mail
k_curr_task->mail = mail_buf;
pend_task_block(k_curr_task, &mail_q->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -193,13 +202,15 @@ __STATIC__ k_err_t mail_q_do_post(k_mail_q_t *mail_q, void *mail_buf, size_t mai
TOS_OBJ_VERIFY(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (pend_is_nopending(&mail_q->pend_obj)) {
err = tos_ring_q_enqueue(&mail_q->ring_q, mail_buf, mail_size);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -212,7 +223,7 @@ __STATIC__ k_err_t mail_q_do_post(k_mail_q_t *mail_q, void *mail_buf, size_t mai
mail_task_recv(task, mail_buf, mail_size);
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();

View File

@ -58,8 +58,10 @@ __API__ k_err_t tos_msg_q_destroy(k_msg_q_t *msg_q)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
err = tos_ring_q_destroy(&msg_q->ring_q);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -74,6 +76,7 @@ __API__ k_err_t tos_msg_q_destroy(k_msg_q_t *msg_q)
knl_object_alloc_reset(&msg_q->knl_obj);
#endif
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -113,8 +116,10 @@ __API__ k_err_t tos_msg_q_destroy_dyn(k_msg_q_t *msg_q)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
err = tos_ring_q_destroy_dyn(&msg_q->ring_q);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -126,6 +131,7 @@ __API__ k_err_t tos_msg_q_destroy_dyn(k_msg_q_t *msg_q)
TOS_OBJ_DEINIT(msg_q);
knl_object_alloc_reset(&msg_q->knl_obj);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -151,25 +157,30 @@ __API__ k_err_t tos_msg_q_pend(k_msg_q_t *msg_q, void **msg_ptr, k_tick_t timeou
TOS_OBJ_VERIFY(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (tos_ring_q_dequeue(&msg_q->ring_q, msg_ptr, K_NULL) == K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (timeout == TOS_TIME_NOWAIT) {
*msg_ptr = K_NULL;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
pend_task_block(k_curr_task, &msg_q->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -198,13 +209,16 @@ __STATIC__ k_err_t msg_q_do_post(k_msg_q_t *msg_q, void *msg_ptr, opt_post_t opt
TOS_OBJ_VERIFY(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (pend_is_nopending(&msg_q->pend_obj)) {
err = tos_ring_q_enqueue(&msg_q->ring_q, &msg_ptr, sizeof(void*));
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -217,6 +231,7 @@ __STATIC__ k_err_t msg_q_do_post(k_msg_q_t *msg_q, void *msg_ptr, opt_post_t opt
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();

View File

@ -165,7 +165,9 @@ __API__ k_err_t tos_mmblk_alloc(k_mmblk_pool_t *mbp, void **blk)
TOS_OBJ_VERIFY(mbp, KNL_OBJ_TYPE_MMBLK_POOL);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (mbp->blk_free == 0) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
*blk = K_NULL;
return K_ERR_MMBLK_POOL_EMPTY;
@ -173,6 +175,7 @@ __API__ k_err_t tos_mmblk_alloc(k_mmblk_pool_t *mbp, void **blk)
*blk = mbp->free_list;
mbp->free_list = *(void **)mbp->free_list;
--mbp->blk_free;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -186,7 +189,9 @@ __API__ k_err_t tos_mmblk_free(k_mmblk_pool_t *mbp, void *blk)
TOS_OBJ_VERIFY(mbp, KNL_OBJ_TYPE_MMBLK_POOL);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (mbp->blk_free >= mbp->blk_max) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_MMBLK_POOL_FULL;
}
@ -194,6 +199,7 @@ __API__ k_err_t tos_mmblk_free(k_mmblk_pool_t *mbp, void *blk)
*(void **)blk = mbp->free_list;
mbp->free_list = blk;
++mbp->blk_free;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}

View File

@ -102,6 +102,7 @@ __API__ k_err_t tos_mutex_destroy(k_mutex_t *mutex)
#endif
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&mutex->pend_obj, PEND_STATE_DESTROY);
@ -117,6 +118,7 @@ __API__ k_err_t tos_mutex_destroy(k_mutex_t *mutex)
knl_object_alloc_reset(&mutex->knl_obj);
#endif
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -164,6 +166,7 @@ __API__ k_err_t tos_mutex_destroy_dyn(k_mutex_t *mutex)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&mutex->pend_obj, PEND_STATE_DESTROY);
@ -177,6 +180,7 @@ __API__ k_err_t tos_mutex_destroy_dyn(k_mutex_t *mutex)
tos_mmheap_free(mutex);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -194,28 +198,34 @@ __API__ k_err_t tos_mutex_pend_timed(k_mutex_t *mutex, k_tick_t timeout)
TOS_OBJ_VERIFY(mutex, KNL_OBJ_TYPE_MUTEX);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (mutex->pend_nesting == (k_nesting_t)0u) { // first come
mutex_fresh_owner_mark(mutex, k_curr_task);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (knl_is_self(mutex->owner)) { // come again
if (mutex->pend_nesting == (k_nesting_t)-1) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_MUTEX_NESTING_OVERFLOW;
}
++mutex->pend_nesting;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_MUTEX_NESTING;
}
if (timeout == TOS_TIME_NOWAIT) { // no wait, return immediately
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
@ -229,6 +239,7 @@ __API__ k_err_t tos_mutex_pend_timed(k_mutex_t *mutex, k_tick_t timeout)
pend_task_block(k_curr_task, &mutex->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -250,13 +261,16 @@ __API__ k_err_t tos_mutex_post(k_mutex_t *mutex)
TOS_OBJ_VERIFY(mutex, KNL_OBJ_TYPE_MUTEX);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (!knl_is_self(mutex->owner)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_MUTEX_NOT_OWNER;
}
--mutex->pend_nesting;
if (mutex->pend_nesting > (k_nesting_t)0u) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_MUTEX_NESTING;
}
@ -264,6 +278,7 @@ __API__ k_err_t tos_mutex_post(k_mutex_t *mutex)
mutex_old_owner_release(mutex);
if (pend_is_nopending(&mutex->pend_obj)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -277,6 +292,7 @@ __API__ k_err_t tos_mutex_post(k_mutex_t *mutex)
mutex_new_owner_mark(mutex, pending_task);
pend_wakeup_one(&mutex->pend_obj, PEND_STATE_POST);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();

View File

@ -59,9 +59,11 @@ __API__ k_err_t tos_prio_mail_q_destroy(k_prio_mail_q_t *prio_mail_q)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
err = tos_prio_q_destroy(&prio_mail_q->prio_q);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -76,6 +78,7 @@ __API__ k_err_t tos_prio_mail_q_destroy(k_prio_mail_q_t *prio_mail_q)
TOS_OBJ_DEINIT(prio_mail_q);
knl_object_alloc_reset(&prio_mail_q->knl_obj);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -114,9 +117,10 @@ __API__ k_err_t tos_prio_mail_q_destroy_dyn(k_prio_mail_q_t *prio_mail_q)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
err = tos_prio_q_destroy_dyn(&prio_mail_q->prio_q);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -128,6 +132,7 @@ __API__ k_err_t tos_prio_mail_q_destroy_dyn(k_prio_mail_q_t *prio_mail_q)
TOS_OBJ_DEINIT(prio_mail_q);
knl_object_alloc_reset(&prio_mail_q->knl_obj);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -153,19 +158,23 @@ __API__ k_err_t tos_prio_mail_q_pend(k_prio_mail_q_t *prio_mail_q, void *mail_bu
TOS_OBJ_VERIFY(prio_mail_q, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (tos_prio_q_dequeue(&prio_mail_q->prio_q, mail_buf, mail_size, K_NULL) == K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (timeout == TOS_TIME_NOWAIT) {
*mail_size = 0;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
@ -173,6 +182,7 @@ __API__ k_err_t tos_prio_mail_q_pend(k_prio_mail_q_t *prio_mail_q, void *mail_bu
k_curr_task->mail = mail_buf;
pend_task_block(k_curr_task, &prio_mail_q->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -204,13 +214,16 @@ __STATIC__ k_err_t prio_mail_q_do_post(k_prio_mail_q_t *prio_mail_q, void *mail_
TOS_OBJ_VERIFY(prio_mail_q, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (pend_is_nopending(&prio_mail_q->pend_obj)) {
err = tos_prio_q_enqueue(&prio_mail_q->prio_q, mail_buf, mail_size, prio);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -224,6 +237,7 @@ __STATIC__ k_err_t prio_mail_q_do_post(k_prio_mail_q_t *prio_mail_q, void *mail_
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();

View File

@ -59,9 +59,11 @@ __API__ k_err_t tos_prio_msg_q_destroy(k_prio_msg_q_t *prio_msg_q)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
err = tos_prio_q_destroy(&prio_msg_q->prio_q);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -76,6 +78,7 @@ __API__ k_err_t tos_prio_msg_q_destroy(k_prio_msg_q_t *prio_msg_q)
TOS_OBJ_DEINIT(prio_msg_q);
knl_object_alloc_reset(&prio_msg_q->knl_obj);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -114,9 +117,11 @@ __API__ k_err_t tos_prio_msg_q_destroy_dyn(k_prio_msg_q_t *prio_msg_q)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
err = tos_prio_q_destroy_dyn(&prio_msg_q->prio_q);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -131,6 +136,7 @@ __API__ k_err_t tos_prio_msg_q_destroy_dyn(k_prio_msg_q_t *prio_msg_q)
TOS_OBJ_DEINIT(prio_msg_q);
knl_object_alloc_reset(&prio_msg_q->knl_obj);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -156,25 +162,30 @@ __API__ k_err_t tos_prio_msg_q_pend(k_prio_msg_q_t *prio_msg_q, void **msg_ptr,
TOS_OBJ_VERIFY(prio_msg_q, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (tos_prio_q_dequeue(&prio_msg_q->prio_q, msg_ptr, K_NULL, K_NULL) == K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (timeout == TOS_TIME_NOWAIT) {
*msg_ptr = K_NULL;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
pend_task_block(k_curr_task, &prio_msg_q->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -203,13 +214,16 @@ __STATIC__ k_err_t prio_msg_q_do_post(k_prio_msg_q_t *prio_msg_q, void *msg_ptr,
TOS_OBJ_VERIFY(prio_msg_q, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (pend_is_nopending(&prio_msg_q->pend_obj)) {
err = tos_prio_q_enqueue(&prio_msg_q->prio_q, &msg_ptr, sizeof(void *), prio);
if (err != K_ERR_NONE) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -222,6 +236,7 @@ __STATIC__ k_err_t prio_msg_q_do_post(k_prio_msg_q_t *prio_msg_q, void *msg_ptr,
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();

View File

@ -290,11 +290,13 @@ __API__ k_err_t tos_prio_q_enqueue(k_prio_q_t *prio_q, void *item, size_t item_s
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
the_slot = prio_q_pool_mgr_slot_alloc(&prio_q->pool_mgr);
TOS_ASSERT(the_slot != PRIO_Q_POOL_SLOT_INVALID);
prio_q_do_enqueue(prio_q, item, the_slot, prio);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -320,10 +322,12 @@ __API__ k_err_t tos_prio_q_dequeue(k_prio_q_t *prio_q, void *item, size_t *item_
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
the_slot = prio_q_prio_mgr_slot_dequeue(&prio_q->prio_mgr, prio);
prio_q_do_dequeue(prio_q, item, item_size, the_slot);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -336,11 +340,13 @@ __API__ k_err_t tos_prio_q_flush(k_prio_q_t *prio_q)
TOS_OBJ_VERIFY(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
prio_q_pool_mgr_reset(&prio_q->pool_mgr, prio_q->item_cnt);
prio_q_prio_mgr_reset(&prio_q->prio_mgr);
prio_q->total = 0;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -354,7 +360,9 @@ __API__ int tos_prio_q_is_empty(k_prio_q_t *prio_q)
TOS_OBJ_VERIFY_RC(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE, K_FALSE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
is_empty = (prio_q->total == 0);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return is_empty;
@ -369,7 +377,9 @@ __API__ int tos_prio_q_is_full(k_prio_q_t *prio_q)
TOS_OBJ_VERIFY_RC(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE, K_FALSE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
is_full = (prio_q->total == prio_q->item_cnt);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return is_full;

View File

@ -147,8 +147,10 @@ __API__ k_err_t tos_ring_q_enqueue(k_ring_q_t *ring_q, void *item, size_t item_s
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (tos_ring_q_is_full(ring_q)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_RING_Q_FULL;
}
@ -156,6 +158,7 @@ __API__ k_err_t tos_ring_q_enqueue(k_ring_q_t *ring_q, void *item, size_t item_s
ring_q_item_copy_from(ring_q, item);
ring_q_item_increase(ring_q);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -169,8 +172,10 @@ __API__ k_err_t tos_ring_q_dequeue(k_ring_q_t *ring_q, void *item, size_t *item_
TOS_OBJ_VERIFY(ring_q, KNL_OBJ_TYPE_RING_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (tos_ring_q_is_empty(ring_q)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_RING_Q_EMPTY;
}
@ -178,6 +183,7 @@ __API__ k_err_t tos_ring_q_dequeue(k_ring_q_t *ring_q, void *item, size_t *item_
ring_q_item_copy_to(ring_q, item, item_size);
ring_q_item_decrease(ring_q);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
@ -191,11 +197,13 @@ __API__ k_err_t tos_ring_q_flush(k_ring_q_t *ring_q)
TOS_OBJ_VERIFY(ring_q, KNL_OBJ_TYPE_RING_QUEUE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
ring_q->head = 0u;
ring_q->tail = 0u;
ring_q->total = 0;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
@ -210,7 +218,9 @@ __API__ int tos_ring_q_is_empty(k_ring_q_t *ring_q)
TOS_OBJ_VERIFY_RC(ring_q, KNL_OBJ_TYPE_RING_QUEUE, K_FALSE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
is_empty = (ring_q->total == 0 ? K_TRUE : K_FALSE);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return is_empty;
@ -225,7 +235,9 @@ __API__ int tos_ring_q_is_full(k_ring_q_t *ring_q)
TOS_OBJ_VERIFY_RC(ring_q, KNL_OBJ_TYPE_RING_QUEUE, K_FALSE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
is_full = (ring_q->total == ring_q->item_cnt ? K_TRUE : K_FALSE);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return is_full;

View File

@ -24,6 +24,7 @@ __API__ void tos_robin_default_timeslice_config(k_timeslice_t default_timeslice)
TOS_CPU_CPSR_ALLOC();
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (default_timeslice > (k_timeslice_t)0u) {
k_robin_default_timeslice = default_timeslice;
@ -31,6 +32,7 @@ __API__ void tos_robin_default_timeslice_config(k_timeslice_t default_timeslice)
k_robin_default_timeslice = TOS_CFG_CPU_TICK_PER_SECOND / 10;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -43,6 +45,7 @@ __API__ void tos_robin_timeslice_set(k_task_t *task, k_timeslice_t timeslice)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (timeslice == (k_timeslice_t)0u) {
task->timeslice_reload = k_robin_default_timeslice;
@ -53,6 +56,7 @@ __API__ void tos_robin_timeslice_set(k_task_t *task, k_timeslice_t timeslice)
if (task->timeslice_reload > task->timeslice) {
task->timeslice = task->timeslice_reload;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -60,15 +64,14 @@ __KNL__ void robin_sched(k_prio_t prio)
{
TOS_CPU_CPSR_ALLOC();
k_task_t *task;
#if (USE_SMP ==0u)
TOS_CPU_INT_DISABLE();
task = readyqueue_first_task_get(prio);
if (!task || knl_is_idle(task)) {
TOS_CPU_INT_ENABLE();
return;
}
if (readyqueue_is_prio_onlyone(prio)) {
TOS_CPU_INT_ENABLE();
return;
@ -96,9 +99,50 @@ __KNL__ void robin_sched(k_prio_t prio)
} else {
task->timeslice = task->timeslice_reload;
}
TOS_CPU_INT_ENABLE();
knl_sched();
# else
TOS_CPU_INT_DISABLE();
BaseType_t num=configNUM_CORES-1;
BaseType_t xCoreID;
BaseType_t x;
xCoreID = port_GET_CORE_ID();
int issched=1;
for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configNUM_CORES; x++ ){
//task = readyqueue_first_task_get_smp(prio,x-bias);
task=k_curr_tasks[x];
if(task==K_NULL)
continue;
if (!task || knl_is_idle(task))
continue;
if (knl_is_sched_locked()) {
TOS_CPU_INT_ENABLE();
return;
}
if (task->timeslice > (k_timeslice_t)0u) {
--task->timeslice;
}
if (task->timeslice > (k_timeslice_t)0u) {
if(x==xCoreID)
issched=0;
continue;
}
readyqueue_remove(task);
readyqueue_add(task);
if (task->timeslice_reload == (k_timeslice_t)0u) {
task->timeslice = k_robin_default_timeslice;
} else {
task->timeslice = task->timeslice_reload;
}
if( x != xCoreID ){
portSCHED_CORE (x);
}
}
TOS_CPU_INT_ENABLE();
if(issched)
knl_sched();
#endif
}
#endif

View File

@ -72,15 +72,139 @@ __KNL__ k_task_t *readyqueue_first_task_get(k_prio_t prio)
task_list = &k_rdyq.task_list_head[prio];
return TOS_LIST_FIRST_ENTRY_OR_NULL(task_list, k_task_t, pend_list);
}
__KNL__ k_task_t *readyqueue_highest_ready_task_get(void)
__KNL__ k_task_t *readyqueue_first_task_get_smp(k_prio_t prio,int corenum)
{
k_list_t *task_list;
task_list = &k_rdyq.task_list_head[k_rdyq.highest_prio];
return TOS_LIST_FIRST_ENTRY(task_list, k_task_t, pend_list);
task_list = &k_rdyq.task_list_head[prio];
if(corenum==0)
return TOS_LIST_FIRST_ENTRY_OR_NULL(task_list, k_task_t, pend_list);
k_list_t * Head=&k_rdyq.task_list_head[prio];
task_list=task_list->next;
while(corenum>0){
while(task_list->next!=Head&&corenum>0){
task_list=task_list->next;
corenum--;
}
if(corenum>0){
prio++;
task_list=&k_rdyq.task_list_head[prio];
Head=&k_rdyq.task_list_head[prio];
if(tos_list_empty(task_list)){
return K_NULL;
}
else{
corenum--;
if(corenum==0)
break;
task_list=task_list->next;
}
}
}
return TOS_LIST_ENTRY(task_list, k_task_t, pend_list);
}
__KNL__ k_task_t *readyqueue_highest_ready_task_get ( void )
{
k_list_t *task_list;
#if ( USE_SMP == 1 )
#if ( configUSE_CORE_AFFINITY == 1u )
k_task_t * prvtask=K_NULL;
#endif
const BaseType_t xCoreID= port_GET_CORE_ID();
k_prio_t uxCurrentPriority= k_rdyq.highest_prio;
BaseType_t TaskScheduled = 0;
while(TaskScheduled==0){
//BaseType_t xDecrementTopPriority=1;
k_list_t * cur_task_list = &k_rdyq.task_list_head[uxCurrentPriority];
k_task_t * cur_task;
// whether the current linked list of the highest priority queue is empty
if(!tos_list_empty(cur_task_list)) {
/* The ready task list for uxCurrentPriority is not empty, so uxTopReadyPriority
* must not be decremented any further */
k_list_t *headNode=cur_task_list;
//Traverse linked list
do{
cur_task_list=cur_task_list->next;
cur_task=TOS_LIST_ENTRY(cur_task_list, k_task_t, pend_list);
if(cur_task->RunningOnCore==-1){
/* If the task is not being executed by any core swap it in */
#if ( configUSE_CORE_AFFINITY == 1u )
if( ( cur_task->CoreAffinityMask & ( 1 << xCoreID ) ) != 0 )
#endif
{
#if ( configUSE_CORE_AFFINITY == 1u )
prvtask=k_curr_tasks[xCoreID];
#endif
k_curr_tasks[xCoreID]->RunningOnCore=-1;
cur_task->RunningOnCore=xCoreID;
TaskScheduled=1;
}
}
else if( cur_task== k_curr_tasks[ xCoreID ]){
/* The task is already running on this core, mark it as scheduled */
#if ( configUSE_CORE_AFFINITY == 1u )
if( ( cur_task->CoreAffinityMask & ( 1 << xCoreID ) ) != 0 )
#endif
{
cur_task->RunningOnCore=xCoreID;
TaskScheduled=1;
}
}
if( TaskScheduled != 0 ){
/* Once a task has been selected to run on this core*/
break;
}
}while(cur_task_list->next!=headNode);
}
if(TaskScheduled==1){
return cur_task;
}
if(uxCurrentPriority<TOS_CFG_TASK_PRIO_MAX) {
uxCurrentPriority++;//decrease priority
}
else{
return K_NULL;
}
}
#if ( configUSE_CORE_AFFINITY == 1u )
if(prvtask!=K_NULL&&TOS_LIST_FIRST_ENTRY(&k_rdyq.task_list_head[prvtask->prio], k_task_t, pend_list)==prvtask){
BaseType_t uxCoreMap = prvtask->CoreAffinityMask;
BaseType_t xLowestPriority = prvtask->prio;
BaseType_t xLowestPriorityCore = -1;
if( ( uxCoreMap & ( 1 << xCoreID ) ) != 0 )
{
uxCoreMap &= ~( k_curr_tasks[ xCoreID ]->CoreAffinityMask );
}
uxCoreMap &= ( ( 1 << configNUM_CORES ) - 1 );
while( uxCoreMap != 0 )
{
int uxCore = 31UL - ( uint32_t ) __builtin_clz( uxCoreMap );
configASSERT( ( 0 <= xCoreID ) && ( xCoreID < configNUM_CORES ) );
uxCoreMap &= ~( 1 << uxCore );
BaseType_t xTaskPriority = ( BaseType_t ) k_curr_tasks[ uxCore ]->prio;
if( ( xTaskPriority < xLowestPriority ) && ( k_curr_tasks[ uxCore ]->RunningOnCore != -1 ) ){
xLowestPriority = xTaskPriority;
xLowestPriorityCore = uxCore;
}
}
if( ( 0 <= xLowestPriorityCore ) && ( xLowestPriorityCore < configNUM_CORES )){
portSCHED_CORE(xLowestPriorityCore);
}
}
#endif
#else
task_list = &k_rdyq.task_list_head[k_rdyq.highest_prio];
return TOS_LIST_FIRST_ENTRY(task_list, k_task_t, pend_list);
#endif
}
__KNL__ void readyqueue_init(void)
{
uint8_t i;
@ -100,7 +224,6 @@ __KNL__ void readyqueue_add_head(k_task_t *task)
{
k_prio_t task_prio;
k_list_t *task_list;
task_prio = task->prio;
task_list = &k_rdyq.task_list_head[task_prio];
@ -118,7 +241,6 @@ __KNL__ void readyqueue_add_tail(k_task_t *task)
task_prio = task->prio;
task_list = &k_rdyq.task_list_head[task_prio];
if (tos_list_empty(task_list)) {
readyqueue_prio_mark(task_prio);
}

View File

@ -59,6 +59,7 @@ __API__ k_err_t tos_sem_destroy(k_sem_t *sem)
#endif
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&sem->pend_obj, PEND_STATE_DESTROY);
@ -70,6 +71,7 @@ __API__ k_err_t tos_sem_destroy(k_sem_t *sem)
knl_object_alloc_reset(&sem->knl_obj);
#endif
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -124,6 +126,7 @@ __API__ k_err_t tos_sem_destroy_dyn(k_sem_t *sem)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
pend_wakeup_all(&sem->pend_obj, PEND_STATE_DESTROY);
@ -133,6 +136,7 @@ __API__ k_err_t tos_sem_destroy_dyn(k_sem_t *sem)
tos_mmheap_free(sem);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -149,20 +153,24 @@ __STATIC__ k_err_t sem_do_post(k_sem_t *sem, opt_post_t opt)
TOS_OBJ_VERIFY(sem, KNL_OBJ_TYPE_SEMAPHORE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (sem->count == sem->count_max) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_SEM_OVERFLOW;
}
if (pend_is_nopending(&sem->pend_obj)) {
++sem->count;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
pend_wakeup(&sem->pend_obj, PEND_STATE_POST, opt);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -188,25 +196,30 @@ __API__ k_err_t tos_sem_pend(k_sem_t *sem, k_tick_t timeout)
TOS_OBJ_VERIFY(sem, KNL_OBJ_TYPE_SEMAPHORE);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (sem->count > (k_sem_cnt_t)0u) {
--sem->count;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
if (timeout == TOS_TIME_NOWAIT) { // no wait, return immediately
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_NOWAIT;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_PEND_SCHED_LOCKED;
}
pend_task_block(k_curr_task, &sem->pend_obj, timeout);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();

View File

@ -16,7 +16,97 @@
*---------------------------------------------------------------------------*/
#include "tos_k.h"
#if (USE_SMP ==1u)
extern uint8_t ucPrimaryCoreNum ;
__API__ static void prvDisableInterruptsAndPortStartSchedulerOnCore( void )
{
TOS_CPU_CPSR_ALLOC();
TOS_CPU_INT_DISABLE();
port_smp_init_kernel();
tos_knl_start();
}
__API__ void smp_init_core0(void){
/* No one else should use these! */
spin_lock_claim( configSMP_SPINLOCK_0 );
spin_lock_claim( configSMP_SPINLOCK_1 );
#if (USE_SMP == 1u)
ucPrimaryCoreNum = configTICK_CORE;
configASSERT( get_core_num() == 0) ; // we must be started on core 0
#else
ucPrimaryCoreNum = get_core_num();
#endif
//主核初始化
port_smp_init_kernel();
}
__API__ k_err_t tos_knl_smp_init(void)
{
k_err_t err;
err=tos_knl_init();
TOS_CPU_CPSR_ALLOC();
//关全局中断
TOS_CPU_INT_DISABLE();
smp_init_core0();
//开全局中断
TOS_CPU_INT_ENABLE();
return err;
}
#if ( configUSE_CORE_AFFINITY == 1u )
__API__ void tos_TaskCoreAffinitySet( k_task_t * Task, BaseType_t CoreAffinityMask ){
int flag=0;
//ensure the core is valid
CoreAffinityMask &= ( ( 1 << configNUM_CORES ) - 1 );
TOS_CPU_CPSR_ALLOC();
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
Task->CoreAffinityMask=CoreAffinityMask;
if(!tos_knl_is_running()){
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
BaseType_t xCoreID = ( BaseType_t ) Task->RunningOnCore;
if(xCoreID!=-1&&(CoreAffinityMask & ( 1 << xCoreID ) ) == 0){
if(xCoreID==port_GET_CORE_ID()){
flag=1;
}
else{
portSCHED_CORE (xCoreID);
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
if(flag){
knl_sched();
}
return ;
}
__API__ BaseType_t vTaskCoreAffinityGet( const k_task_t * Task )
{
BaseType_t uxCoreAffinityMask;
TOS_CPU_CPSR_ALLOC();
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
uxCoreAffinityMask = Task->CoreAffinityMask;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return uxCoreAffinityMask;
}
#endif
#endif
__API__ k_err_t tos_knl_init(void)
{
k_err_t err;
@ -64,12 +154,18 @@ __API__ void tos_knl_irq_enter(void)
if (!tos_knl_is_running()) {
return;
}
#if (USE_SMP == 1u)
if (unlikely(k_irq_nest_cnts[ port_GET_CORE_ID()] >= K_NESTING_LIMIT_IRQ)) {
return;
}
++k_irq_nest_cnts[ port_GET_CORE_ID()];
#else
if (unlikely(k_irq_nest_cnt >= K_NESTING_LIMIT_IRQ)) {
return;
}
++k_irq_nest_cnt;
#endif
}
__API__ void tos_knl_irq_leave(void)
@ -81,30 +177,41 @@ __API__ void tos_knl_irq_leave(void)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (!knl_is_inirq()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
--k_irq_nest_cnt;
#if (USE_SMP == 1u)
--k_irq_nest_cnts[ port_GET_CORE_ID()];
#else
--k_irq_nest_cnt;
#endif
if (knl_is_inirq()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
if (knl_is_sched_locked()) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
k_next_task = readyqueue_highest_ready_task_get();
#if ( USE_SMP == 1u)
k_next_tasks[port_GET_CORE_ID()]=k_next_task;
#endif
if (knl_is_self(k_next_task)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
cpu_irq_context_switch();
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -123,7 +230,9 @@ __API__ k_err_t tos_knl_sched_lock(void)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
++k_sched_lock_nest_cnt;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -143,31 +252,61 @@ __API__ k_err_t tos_knl_sched_unlock(void)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
--k_sched_lock_nest_cnt;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
return K_ERR_NONE;
}
__API__ k_err_t tos_knl_start_smp(void)
{
//启动应用核心
port_multicore_launch(prvDisableInterruptsAndPortStartSchedulerOnCore);
//启动主核心调度
if(port_GET_CORE_ID()==ucPrimaryCoreNum){
return tos_knl_start();
}
return K_ERR_NONE;
}
__API__ k_err_t tos_knl_start(void)
{
if (unlikely(tos_knl_is_running())) {
return K_ERR_KNL_RUNNING;
}
#if( USE_SMP == 1u )
TOS_CPU_CPSR_ALLOC();
//关全局中断
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
k_next_task = readyqueue_highest_ready_task_get();
k_next_tasks[port_GET_CORE_ID()]=k_next_task;
k_curr_tasks[port_GET_CORE_ID()]=k_next_task;
portRELEASE_TASK_LOCK();
//开全局中断
TOS_CPU_INT_ENABLE();
k_knl_states[port_GET_CORE_ID()] = KNL_STATE_RUNNING;
#else
k_next_task = readyqueue_highest_ready_task_get();
k_curr_task = k_next_task;
k_knl_state = KNL_STATE_RUNNING;
#endif
cpu_sched_start();
return K_ERR_NONE;
}
__API__ int tos_knl_is_running(void)
{
return k_knl_state == KNL_STATE_RUNNING;
#if( USE_SMP == 1u )
return k_knl_states[port_GET_CORE_ID()] == KNL_STATE_RUNNING;
#else
return k_knl_state == KNL_STATE_RUNNING;
#endif
}
#if TOS_CFG_TICKLESS_EN > 0u
@ -198,7 +337,6 @@ __KNL__ k_tick_t knl_next_expires_get(void)
}
#endif
__KNL__ void knl_sched(void)
{
TOS_CPU_CPSR_ALLOC();
@ -216,13 +354,19 @@ __KNL__ void knl_sched(void)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK(); /* Must always acquire the task lock first */
k_next_task = readyqueue_highest_ready_task_get();
#if (USE_SMP == 1u )
k_next_tasks[port_GET_CORE_ID()]=k_next_task;
#endif
if (knl_is_self(k_next_task)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
cpu_context_switch();
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -233,12 +377,32 @@ __KNL__ int knl_is_sched_locked(void)
__KNL__ int knl_is_inirq(void)
{
return k_irq_nest_cnt > 0u;
#if (USE_SMP == 1u )
//return portCHECK_IF_IN_ISR() ;
return k_irq_nest_cnts[port_GET_CORE_ID()] > 0u;
#else
return k_irq_nest_cnt > 0u;
#endif
}
__KNL__ int knl_is_idle_pre(k_task_t *task)
{
int x=0;
for(x;x<configNUM_CORES;x++){
if(task==&k_idle_tasks[x])
return 1;
}
return 0;
}
__KNL__ int knl_is_idle(k_task_t *task)
{
return task == &k_idle_task;
#if (USE_SMP == 1u )
return task->IsIDLE==1;
#else
return task == &k_idle_task;
#endif
}
__KNL__ int knl_is_self(k_task_t *task)
@ -246,28 +410,71 @@ __KNL__ int knl_is_self(k_task_t *task)
return task == k_curr_task;
}
__STATIC__ void knl_idle1_entry(void *arg)
{
arg = arg; // make compiler happy
while (K_TRUE) {
knl_sched();
}
}
__STATIC__ void knl_idle_entry(void *arg)
{
arg = arg; // make compiler happy
while (K_TRUE) {
#if TOS_CFG_OBJ_DYNAMIC_CREATE_EN > 0u
#if TOS_CFG_OBJ_DYNAMIC_CREATE_EN > 0u
task_free_all();
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
pm_power_manager();
#endif
#endif
if(k_rdyq.highest_prio<K_TASK_PRIO_IDLE){
knl_sched();
}
}
}
__KNL__ k_err_t knl_idle_init(void)
{
#if USE_SMP ==1u
k_err_t xReturn=K_ERR_NONE;
char cIdleName[ configMAX_TASK_NAME_LEN ];
BaseType_t x;
BaseType_t xCoreID;
for( xCoreID = ( BaseType_t ) 0; xCoreID < ( BaseType_t ) configNUM_CORES; xCoreID++ ){
if( xReturn !=K_ERR_NONE ){
break;
}
for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configMAX_TASK_NAME_LEN; x++ ){
cIdleName[ x ] = configIDLE_TASK_NAME[ x ];
if( cIdleName[ x ] == ( char ) 0x00 )
break;
}
if( x < configMAX_TASK_NAME_LEN ){
cIdleName[ x++ ] = xCoreID + '0';
/* And append a null character if there is space */
if( x < configMAX_TASK_NAME_LEN )
cIdleName[ x ] = '\0';
}
xReturn=tos_task_create(&k_idle_tasks[xCoreID] , cIdleName,
knl_idle_entry, K_NULL,
K_TASK_PRIO_IDLE,
k_idle_task_stk_addrs[xCoreID],
k_idle_task_stk_size,
0);
k_idle_tasks[xCoreID].IsIDLE=1;
}
#else
return tos_task_create(&k_idle_task, "idle",
knl_idle_entry, K_NULL,
K_TASK_PRIO_IDLE,
k_idle_task_stk_addr,
k_idle_task_stk_size,
0);
#endif
}

View File

@ -44,6 +44,13 @@ __STATIC_INLINE__ void task_reset(k_task_t *task)
task->mail = K_NULL;
task->mail_size = 0;
#endif
#if (USE_SMP ==1u)
task->RunningOnCore=-1;
task->IsIDLE=0;
#if ( configUSE_CORE_AFFINITY == 1 )
task->CoreAffinityMask=( 1 << configNUM_CORES ) - 1;
#endif
#endif
TOS_OBJ_DEINIT(task);
}
@ -102,10 +109,15 @@ __API__ k_err_t tos_task_create(k_task_t *task,
if (unlikely(stk_size < K_TASK_STK_SIZE_MIN)) {
return K_ERR_TASK_STK_SIZE_INVALID;
}
#if (USE_SMP == 1u )
if (unlikely(prio == K_TASK_PRIO_IDLE && !knl_is_idle_pre(task))) {
return K_ERR_TASK_PRIO_INVALID;
}
#else
if (unlikely(prio == K_TASK_PRIO_IDLE && !knl_is_idle(task))) {
return K_ERR_TASK_PRIO_INVALID;
}
#endif
if (unlikely(prio > K_TASK_PRIO_IDLE)) {
return K_ERR_TASK_PRIO_INVALID;
@ -138,14 +150,25 @@ __API__ k_err_t tos_task_create(k_task_t *task,
#endif
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
task_state_set_ready(task);
readyqueue_add_tail(task);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
#if (USE_SMP ==1u)
BaseType_t x;
BaseType_t xCoreID = port_GET_CORE_ID();
for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configNUM_CORES; x++ ){
if( x != xCoreID ){
if( k_knl_states[x] == KNL_STATE_RUNNING)
portSCHED_CORE (x);
}
}
#endif
if (tos_knl_is_running()) {
knl_sched();
}
return K_ERR_NONE;
}
@ -158,6 +181,7 @@ __STATIC__ k_err_t task_do_destroy(k_task_t *task)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
#if TOS_CFG_MUTEX_EN > 0u
// when we die, wakeup all the people in this land.
@ -177,13 +201,18 @@ __STATIC__ k_err_t task_do_destroy(k_task_t *task)
}
tos_list_del(&task->stat_list);
//if the destroyed task is running on other cores must be stopped
#if (USE_SMP ==1u)
if(task->RunningOnCore!= port_GET_CORE_ID()&&task->RunningOnCore!=-1){
portSCHED_CORE (task->RunningOnCore);
}
#endif
task_reset(task);
task_state_set_deleted(task);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
return K_ERR_NONE;
}
@ -224,12 +253,14 @@ __KNL__ void task_free_all(void)
k_task_t *task, *tmp;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
TOS_LIST_FOR_EACH_ENTRY_SAFE(task, tmp, k_task_t, dead_list, &k_dead_task_list) {
tos_list_del(&task->dead_list);
task_free(task);
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -263,10 +294,12 @@ __API__ k_err_t tos_task_create_dyn(k_task_t **task,
TOS_CPU_CPSR_ALLOC();
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
the_task->stk_base = stk_base;
err = tos_task_create(the_task, name, entry, arg, prio, stk_base, stk_size, timeslice);
if (err != K_ERR_NONE) {
task_free(the_task);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return err;
}
@ -274,6 +307,7 @@ __API__ k_err_t tos_task_create_dyn(k_task_t **task,
knl_object_alloc_set_dynamic(&the_task->knl_obj);
*task = the_task;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
@ -330,12 +364,14 @@ __API__ void tos_task_yield(void)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
readyqueue_remove(k_curr_task);
readyqueue_add_tail(k_curr_task);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
}
__API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new)
@ -354,8 +390,10 @@ __API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (task->prio == prio_new) { // just kidding
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
return K_ERR_NONE;
@ -391,7 +429,17 @@ __API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new)
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
#if (USE_SMP ==1u)
BaseType_t x;
BaseType_t xCoreID = port_GET_CORE_ID();
for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configNUM_CORES; x++ ){
if( x != xCoreID ){
portSCHED_CORE (x);
}
}
#endif
knl_sched();
return K_ERR_NONE;
@ -416,6 +464,7 @@ __API__ k_err_t tos_task_suspend(k_task_t *task)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (task_state_is_ready(task)) { // kill the good kid
readyqueue_remove(task);
@ -427,7 +476,11 @@ __API__ k_err_t tos_task_suspend(k_task_t *task)
tick_list_remove(task);
}
task_state_set_suspended(task);
#if (USE_SMP == 1u)
if(task->RunningOnCore!= port_GET_CORE_ID()&&task->RunningOnCore!=-1)
portSCHED_CORE (task->RunningOnCore);
#endif
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
@ -446,8 +499,10 @@ __API__ k_err_t tos_task_resume(k_task_t *task)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (!task_state_is_suspended(task)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
return K_ERR_NONE;
@ -458,7 +513,17 @@ __API__ k_err_t tos_task_resume(k_task_t *task)
readyqueue_add(task);
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
#if (USE_SMP ==1u)
BaseType_t x;
BaseType_t xCoreID = port_GET_CORE_ID();
for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configNUM_CORES; x++ ){
if( x != xCoreID ){
portSCHED_CORE (x);
}
}
#endif
knl_sched();
return K_ERR_NONE;
@ -483,13 +548,29 @@ __API__ k_err_t tos_task_delay(k_tick_t delay)
// if you wanna delay your task forever, why don't just suspend?
return K_ERR_DELAY_FOREVER;
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
#if(USE_SMP==1u)
if(k_curr_task->RunningOnCore!= port_GET_CORE_ID()){
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
knl_sched();
return K_ERR_NONE;
}
#endif
tick_list_add(k_curr_task, delay);
readyqueue_remove(k_curr_task);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
#if (USE_SMP ==1u)
BaseType_t x;
BaseType_t xCoreID = port_GET_CORE_ID();
for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configNUM_CORES; x++ ){
if( x != xCoreID ){
portSCHED_CORE (x);
}
}
#endif
knl_sched();
return K_ERR_NONE;
@ -504,21 +585,33 @@ __API__ k_err_t tos_task_delay_abort(k_task_t *task)
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (knl_is_self(task) || !task_state_is_sleeping(task)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_TASK_NOT_DELAY;
}
if (task_state_is_suspended(task)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_TASK_SUSPENDED;
}
tick_list_remove(task);
readyqueue_add(task);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
#if (USE_SMP ==1u)
BaseType_t x;
BaseType_t xCoreID = port_GET_CORE_ID();
for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configNUM_CORES; x++ ){
if( x != xCoreID ){
if( k_knl_states[x] == KNL_STATE_RUNNING)
portSCHED_CORE (x);
}
}
#endif
knl_sched();
return K_ERR_NONE;
@ -530,9 +623,15 @@ __API__ k_task_t *tos_task_curr_task_get(void)
k_task_t *curr_task = K_NULL;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (likely(tos_knl_is_running())) {
#if (USE_SMP ==1u)
curr_task = k_curr_tasks[port_GET_CORE_ID()];
#else
curr_task = k_curr_task;
#endif
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return curr_task;
@ -548,14 +647,17 @@ __API__ k_task_t *tos_task_find(const char *name)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
TOS_LIST_FOR_EACH_ENTRY(task, k_task_t, stat_list, &k_stat_list) {
if (strncmp(task->name, name, K_TASK_NAME_LEN_MAX) == 0) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return task;
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_NULL;
}
@ -570,11 +672,13 @@ __API__ void tos_task_walkthru(k_task_walker_t walker)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
TOS_LIST_FOR_EACH_ENTRY(task, k_task_t, stat_list, &k_stat_list) {
walker(task);
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -599,7 +703,9 @@ __API__ k_err_t tos_task_stack_draught_depth(k_task_t *task, int *depth)
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
rc = cpu_task_stack_draught_depth(task->stk_base, task->stk_size, depth);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return rc;

View File

@ -24,6 +24,7 @@ __STATIC__ void tick_task_place(k_task_t *task, k_tick_t timeout)
k_tick_t curr_expires, prev_expires = (k_tick_t)0u;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
task->tick_expires = timeout;
@ -45,6 +46,7 @@ __STATIC__ void tick_task_place(k_task_t *task, k_tick_t timeout)
}
tos_list_add_tail(&task->tick_list, &curr_task->tick_list);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -54,6 +56,7 @@ __STATIC__ void tick_task_takeoff(k_task_t *task)
k_task_t *next;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
next = TOS_LIST_FIRST_ENTRY_OR_NULL(&task->tick_list, k_task_t, tick_list);
if (next && task->tick_list.next != &k_tick_list) { // not the only one
@ -66,6 +69,7 @@ __STATIC__ void tick_task_takeoff(k_task_t *task)
tos_list_del(&task->tick_list);
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -87,9 +91,11 @@ __KNL__ void tick_update(k_tick_t tick)
k_task_t *first, *task, *tmp;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
k_tick_count += tick;
if (tos_list_empty(&k_tick_list)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
@ -99,6 +105,7 @@ __KNL__ void tick_update(k_tick_t tick)
first->tick_expires = (k_tick_t)0u;
} else {
first->tick_expires -= tick;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
@ -112,6 +119,7 @@ __KNL__ void tick_update(k_tick_t tick)
pend_task_wakeup(task, PEND_STATE_TIMEOUT);
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -122,10 +130,12 @@ __KNL__ k_tick_t tick_next_expires_get(void)
k_task_t *first;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
first = TOS_LIST_FIRST_ENTRY_OR_NULL(&k_tick_list, k_task_t, tick_list);
next_expires = first ? first->tick_expires : TOS_TIME_FOREVER;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return next_expires;
}
@ -143,7 +153,19 @@ __API__ void tos_tick_handler(void)
#endif
#if TOS_CFG_ROUND_ROBIN_EN > 0u
robin_sched(k_curr_task->prio);
#if (USE_SMP ==1u)
if(k_curr_task->prio>k_rdyq.highest_prio){
k_task_t *task;
task = readyqueue_first_task_get(k_rdyq.highest_prio);
if(task->RunningOnCore==-1)
tos_task_resume(task);
}
else
robin_sched(k_rdyq.highest_prio);
#else
robin_sched(k_curr_task->prio);
#endif
#endif
}

View File

@ -23,7 +23,9 @@ __API__ k_tick_t tos_systick_get(void)
k_tick_t tick;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
tick = k_tick_count;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return tick;
}
@ -33,7 +35,9 @@ __API__ void tos_systick_set(k_tick_t tick)
TOS_CPU_CPSR_ALLOC();
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
k_tick_count = tick;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}

View File

@ -25,6 +25,7 @@ __STATIC__ void timer_place(k_timer_t *tmr)
k_timer_t *iter = K_NULL;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
tmr->expires += k_tick_count;
@ -52,6 +53,7 @@ __STATIC__ void timer_place(k_timer_t *tmr)
}
#endif
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -61,6 +63,7 @@ __STATIC__ void timer_takeoff(k_timer_t *tmr)
k_timer_t *first, *next;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
first = TOS_LIST_FIRST_ENTRY(&k_timer_ctl.list, k_timer_t, list);
@ -77,6 +80,7 @@ __STATIC__ void timer_takeoff(k_timer_t *tmr)
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -333,6 +337,7 @@ __KNL__ k_tick_t soft_timer_next_expires_get(void)
k_tick_t next_expires;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
if (k_timer_ctl.next_expires == TOS_TIME_FOREVER) {
next_expires = TOS_TIME_FOREVER;
@ -342,6 +347,7 @@ __KNL__ k_tick_t soft_timer_next_expires_get(void)
next_expires = k_timer_ctl.next_expires - k_tick_count;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return next_expires;
}

View File

@ -23,7 +23,11 @@ static osStatus errno_knl2cmsis(k_err_t err)
// ==== Kernel Control Functions ====
osStatus osKernelStart(void)
{
#if( USE_SMP == 1u )
return errno_knl2cmsis(tos_knl_start_smp());
#else
return errno_knl2cmsis(tos_knl_start());
#endif
}
/**
@ -32,7 +36,11 @@ osStatus osKernelStart(void)
*/
osStatus osKernelInitialize(void)
{
return errno_knl2cmsis(tos_knl_init());
#if (USE_SMP ==1u)
return errno_knl2cmsis(tos_knl_smp_init());
#else
return errno_knl2cmsis(tos_knl_init());
#endif
}
/**

View File

@ -42,7 +42,11 @@ static osStatus_t errno_knl2cmsis(k_err_t err) {
/*---------------------------------------------------------------------------*/
osStatus_t osKernelInitialize(void) {
return errno_knl2cmsis(tos_knl_init());
#if (USE_SMP ==1u)
return errno_knl2cmsis(tos_knl_smp_init());
#else
return errno_knl2cmsis(tos_knl_init());
#endif
}
osStatus_t osKernelGetInfo(osVersion_t* version,
@ -65,8 +69,14 @@ osStatus_t osKernelGetInfo(osVersion_t* version,
osKernelState_t osKernelGetState(void) {
osKernelState_t state;
knl_state_t k_state_core;
#if( USE_SMP == 1u )
k_state_core=k_knl_state[port_GET_CORE_ID()];
#else
k_state_core=k_knl_state;
#endif
switch (k_knl_state) {
switch (k_state_core) {
case KNL_STATE_RUNNING:
state = osKernelRunning;
break;
@ -79,7 +89,11 @@ osKernelState_t osKernelGetState(void) {
}
osStatus_t osKernelStart(void) {
return errno_knl2cmsis(tos_knl_start());
#if( USE_SMP == 1u )
return errno_knl2cmsis(tos_knl_start_smp());
#else
return errno_knl2cmsis(tos_knl_start());
#endif
}
int32_t osKernelLock(void) {
@ -343,10 +357,12 @@ uint32_t osThreadGetCount(void) {
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
TOS_LIST_FOR_EACH_ENTRY(task, k_task_t, stat_list, &k_stat_list) {
count += 1;
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return count;
@ -360,6 +376,7 @@ uint32_t osThreadEnumerate(osThreadId_t* thread_array, uint32_t array_items) {
k_task_t* task;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
TOS_LIST_FOR_EACH_ENTRY(task, k_task_t, stat_list, &k_stat_list) {
while (count < array_items) {
@ -368,6 +385,7 @@ uint32_t osThreadEnumerate(osThreadId_t* thread_array, uint32_t array_items) {
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}

View File

@ -33,9 +33,11 @@ __KNL__ int mqueue_id_add(mqd_t id, mqueue_ctl_t *mqueue_ctl)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
mqueue_ctl_table[id] = mqueue_ctl;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return 0;
@ -47,14 +49,17 @@ __KNL__ mqd_t mqueue_id_alloc(void)
int i = 0;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
for (i = 0; i < TOS_COUNT_OF(mqueue_ctl_table); ++i) {
if (!mqueue_ctl_table[i]) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return (mqd_t)i;
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return -1;
}
@ -70,9 +75,11 @@ __KNL__ int mqueue_id_free(mqd_t id)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
mqueue_ctl_table[id] = K_NULL;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return 0;

View File

@ -36,15 +36,18 @@ __KNL__ pthread_ctl_t *pthread_ctl_self(void)
self_task = tos_task_curr_task_get();
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
for (i = 0; i < TOS_COUNT_OF(thread_ctl_table); ++i) {
the_info = thread_ctl_table[i];
if (the_info && the_info->the_ktask == self_task) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return the_info;
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_NULL;
}
@ -81,9 +84,11 @@ __KNL__ int pthread_id_add(pthread_t id, pthread_ctl_t *info)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
thread_ctl_table[id] = info;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return 0;
@ -95,14 +100,17 @@ __KNL__ pthread_t pthread_id_alloc(void)
int i = 0;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
for (i = 0; i < TOS_COUNT_OF(thread_ctl_table); ++i) {
if (!thread_ctl_table[i]) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return (pthread_t)i;
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return -1;
}
@ -118,9 +126,11 @@ __KNL__ int pthread_id_free(pthread_t id)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
thread_ctl_table[id] = K_NULL;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return 0;

View File

@ -34,8 +34,10 @@ __KNL__ int timer_id_add(timer_t id, ptimer_ctl_t *ptimer_ctl)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
ptimer_ctl_table[id] = ptimer_ctl;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return 0;
@ -47,14 +49,17 @@ __KNL__ timer_t timer_id_alloc(void)
int i = 0;
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
for (i = 0; i < TOS_COUNT_OF(ptimer_ctl_table); ++i) {
if (!ptimer_ctl_table[i]) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return (timer_t)i;
}
}
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return -1;
}
@ -70,9 +75,11 @@ __KNL__ int timer_id_free(timer_t id)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
ptimer_ctl_table[id] = K_NULL;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return 0;

View File

@ -30,7 +30,9 @@ __API__ k_err_t tos_pm_cpu_lpwr_mode_set(k_cpu_lpwr_mode_t cpu_lpwr_mode)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
k_cpu_lpwr_mode = cpu_lpwr_mode;
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}

View File

@ -107,6 +107,7 @@ __STATIC__ void tickless_tick_fix(k_tick_t tick_sleep)
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
/* we wakeup from SLEEP mode, fix the system's tick & timer */
tick_update(tick_sleep);
@ -116,6 +117,7 @@ __STATIC__ void tickless_tick_fix(k_tick_t tick_sleep)
tickless_tick_resume();
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
}
@ -149,14 +151,17 @@ __KNL__ void tickless_proc(void)
}
TOS_CPU_INT_DISABLE();
portGET_TASK_LOCK();
time_sleep = tickless_cpu_sleep_time_get(lpwr_mode); /* in millisecond */
if (unlikely(time_sleep == (k_time_t)0)) {
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
return;
}
tickless_enter();
portRELEASE_TASK_LOCK();
TOS_CPU_INT_ENABLE();
tickless_wkup_alarm_setup(lpwr_mode, time_sleep);
pm_cpu_lpwr_mode_enter(lpwr_mode);