add transplant to linux
This commit is contained in:
128
arch/linux/common/include/tos_cpu.h
Normal file
128
arch/linux/common/include/tos_cpu.h
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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 _TOS_CPU_H_
|
||||||
|
#define _TOS_CPU_H_
|
||||||
|
|
||||||
|
typedef void (*task_code)( void * );
|
||||||
|
|
||||||
|
typedef struct cpu_context_st {
|
||||||
|
pthread_t thread_id;
|
||||||
|
task_code entry;
|
||||||
|
task_code exit;
|
||||||
|
void *arg;
|
||||||
|
} cpu_context_t;
|
||||||
|
|
||||||
|
__API__ uint32_t tos_cpu_clz(uint32_t val);
|
||||||
|
|
||||||
|
__API__ void tos_cpu_int_disable(void);
|
||||||
|
|
||||||
|
__API__ void tos_cpu_int_enable(void);
|
||||||
|
|
||||||
|
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void);
|
||||||
|
|
||||||
|
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr);
|
||||||
|
|
||||||
|
#if (TOS_CFG_CPU_HRTIMER_EN > 0u)
|
||||||
|
|
||||||
|
__API__ void tos_cpu_hrtimer_init(void);
|
||||||
|
|
||||||
|
__API__ cpu_hrtimer_t tos_cpu_hrtimer_read(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_init(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_reset(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_sched_start(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_context_switch(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_irq_context_switch(void);
|
||||||
|
|
||||||
|
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||||
|
|
||||||
|
__KERNEL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__KERNEL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||||
|
void *arg,
|
||||||
|
void *exit,
|
||||||
|
k_stack_t *stk_base,
|
||||||
|
size_t stk_size);
|
||||||
|
|
||||||
|
#if TOS_CFG_TICKLESS_EN > 0u
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_resume(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_suspend(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_reload_reset(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_pending_reset(void);
|
||||||
|
|
||||||
|
__KERNEL__ k_time_t cpu_systick_max_delay_millisecond(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_expires_set(k_time_t millisecond);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_reset(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_sleep_mode_enter(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_stop_mode_enter(void);
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_standby_mode_enter(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_flush_fpu(void);
|
||||||
|
|
||||||
|
#endif /* TOS_CFG_CPU_ARM_FPU_EN */
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_fault_diagnosis(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Allocates CPU status register word. */
|
||||||
|
#define TOS_CPU_CPSR_ALLOC() cpu_cpsr_t cpu_cpsr = (cpu_cpsr_t)0u
|
||||||
|
|
||||||
|
/* Save CPU status word & disable interrupts.*/
|
||||||
|
#define TOS_CPU_INT_DISABLE() \
|
||||||
|
do { \
|
||||||
|
cpu_cpsr = tos_cpu_cpsr_save(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Restore CPU status word. */
|
||||||
|
#define TOS_CPU_INT_ENABLE() \
|
||||||
|
do { \
|
||||||
|
tos_cpu_cpsr_restore(cpu_cpsr); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* _TOS_CPU_H_ */
|
||||||
|
|
34
arch/linux/common/include/tos_cpu_def.h
Normal file
34
arch/linux/common/include/tos_cpu_def.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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 _TOS_CPU_DEF_H_
|
||||||
|
#define _TOS_CPU_DEF_H_
|
||||||
|
|
||||||
|
enum CPU_WORD_SIZE {
|
||||||
|
CPU_WORD_SIZE_08,
|
||||||
|
CPU_WORD_SIZE_16,
|
||||||
|
CPU_WORD_SIZE_32,
|
||||||
|
CPU_WORD_SIZE_64,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CPU_STK_GROWTH {
|
||||||
|
CPU_STK_GROWTH_ASCENDING,
|
||||||
|
CPU_STK_GROWTH_DESCENDING,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _TOS_CPU_DEF_H_ */
|
||||||
|
|
61
arch/linux/common/include/tos_cpu_types.h
Normal file
61
arch/linux/common/include/tos_cpu_types.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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 _TOS_CPU_TYPES_H_
|
||||||
|
#define _TOS_CPU_TYPES_H_
|
||||||
|
|
||||||
|
/* CPU address type based on address bus size. */
|
||||||
|
#if (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_64)
|
||||||
|
typedef uint64_t cpu_addr_t;
|
||||||
|
#elif (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_32)
|
||||||
|
typedef uint32_t cpu_addr_t;
|
||||||
|
#elif (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_16)
|
||||||
|
typedef uint16_t cpu_addr_t;
|
||||||
|
#else
|
||||||
|
typedef uint8_t cpu_addr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CPU data type based on data bus size. */
|
||||||
|
#if (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_64)
|
||||||
|
typedef uint64_t cpu_data_t;
|
||||||
|
#elif (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_32)
|
||||||
|
typedef uint32_t cpu_data_t;
|
||||||
|
#elif (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_16)
|
||||||
|
typedef uint16_t cpu_data_t;
|
||||||
|
#else
|
||||||
|
typedef uint8_t cpu_data_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||||
|
#if (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_08)
|
||||||
|
typedef uint8_t cpu_hrtimer_t;
|
||||||
|
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_16)
|
||||||
|
typedef uint16_t cpu_hrtimer_t;
|
||||||
|
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_64)
|
||||||
|
typedef uint64_t cpu_hrtimer_t;
|
||||||
|
#else
|
||||||
|
typedef uint32_t cpu_hrtimer_t;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
typedef uint32_t cpu_hrtimer_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//typedef cpu_addr_t size_t;
|
||||||
|
typedef cpu_addr_t cpu_cpsr_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
236
arch/linux/common/include/tos_fault.h
Normal file
236
arch/linux/common/include/tos_fault.h
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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 _TOS_FAULT_H_
|
||||||
|
#define _TOS_FAULT_H_
|
||||||
|
|
||||||
|
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||||
|
|
||||||
|
typedef int (*k_fault_log_writer_t)(const char *format, ...);
|
||||||
|
|
||||||
|
#define K_FAULT_STACK_DUMP_DEPTH 10u
|
||||||
|
|
||||||
|
#define K_FAULT_CALL_STACK_BACKTRACE_DEPTH 5u
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
typedef struct fault_fpu_frame_st {
|
||||||
|
cpu_data_t s0;
|
||||||
|
cpu_data_t s1;
|
||||||
|
cpu_data_t s2;
|
||||||
|
cpu_data_t s3;
|
||||||
|
cpu_data_t s4;
|
||||||
|
cpu_data_t s5;
|
||||||
|
cpu_data_t s6;
|
||||||
|
cpu_data_t s7;
|
||||||
|
cpu_data_t s8;
|
||||||
|
cpu_data_t s9;
|
||||||
|
cpu_data_t s10;
|
||||||
|
cpu_data_t s11;
|
||||||
|
cpu_data_t s12;
|
||||||
|
cpu_data_t s13;
|
||||||
|
cpu_data_t s14;
|
||||||
|
cpu_data_t s15;
|
||||||
|
cpu_data_t fpscr;
|
||||||
|
} fault_fpu_frame_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct fault_cpu_frame_st {
|
||||||
|
cpu_data_t r0;
|
||||||
|
cpu_data_t r1;
|
||||||
|
cpu_data_t r2;
|
||||||
|
cpu_data_t r3;
|
||||||
|
cpu_data_t r12;
|
||||||
|
cpu_data_t lr;
|
||||||
|
cpu_data_t pc;
|
||||||
|
cpu_data_t spsr;
|
||||||
|
} fault_cpu_frame_t;
|
||||||
|
|
||||||
|
typedef struct fault_exc_frame_st {
|
||||||
|
fault_cpu_frame_t cpu_frame;
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
fault_fpu_frame_t fpu_frame;
|
||||||
|
#endif
|
||||||
|
} fault_exc_frame_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* information we need to do fault backtrace
|
||||||
|
*/
|
||||||
|
typedef struct fault_information_st {
|
||||||
|
int is_thumb : 1; /**< whether it is thumb we use when we fall into fault? */
|
||||||
|
int is_on_task : 1; /**< whether we are on a task when fall into fault? */
|
||||||
|
int is_stk_ovrf : 1; /**< whether we get a stack overflow */
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
int is_ext_stk_frm : 1; /**< whether it is a extended stack frame?(whether the cpu has pushed fpu registers onto the stack) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cpu_addr_t pc; /**< just where fault happens */
|
||||||
|
|
||||||
|
cpu_addr_t sp_before_fault; /**< original sp just before the cpu push the fault exception frame */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* we need main_stack_start & main_stack_limit to do call stack backtrace
|
||||||
|
* when we fall into fault during a task, we should do the call stack backtrace on the task's stack
|
||||||
|
* but if not, which means we are in kernel, we should do the call stack backtrace on the main stack
|
||||||
|
* in arm v7-m, this should be the MSP's start and limit
|
||||||
|
* in arm v7-a, call stack backtrace is another story(much more elegant because we have FP).
|
||||||
|
*/
|
||||||
|
cpu_addr_t stack_start; /**< current sp start address we use. if on task, it'll be the task's stack, otherwise it'll be the msp */
|
||||||
|
cpu_addr_t stack_limit; /**< current sp limit address */
|
||||||
|
cpu_addr_t code_start; /**< current code start address */
|
||||||
|
cpu_addr_t code_limit; /**< current code limit address */
|
||||||
|
} fault_info_t;
|
||||||
|
|
||||||
|
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||||
|
|
||||||
|
#define DEFAULT_CODE_SECTION_NAME ER_IROM1
|
||||||
|
#define DEFAULT_CSTACK_SECTION_NAME STACK
|
||||||
|
|
||||||
|
#define SECTION_START(_name_) _name_##$$Base
|
||||||
|
#define SECTION_END(_name_) _name_##$$Limit
|
||||||
|
#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base
|
||||||
|
#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit
|
||||||
|
#define CSTACK_BLOCK_START(_name_) SECTION_START(_name_)
|
||||||
|
#define CSTACK_BLOCK_END(_name_) SECTION_END(_name_)
|
||||||
|
#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_)
|
||||||
|
#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_)
|
||||||
|
|
||||||
|
extern const int CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
|
||||||
|
extern const int CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
|
||||||
|
extern const int CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
|
||||||
|
extern const int CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)&CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)&CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)&CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)&CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__ICCARM__)
|
||||||
|
|
||||||
|
#define DEFAULT_CODE_SECTION_NAME ".text"
|
||||||
|
#define DEFAULT_CSTACK_SECTION_NAME "CSTACK"
|
||||||
|
|
||||||
|
#pragma section=DEFAULT_CSTACK_SECTION_NAME
|
||||||
|
#pragma section=DEFAULT_CODE_SECTION_NAME
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)__section_begin(DEFAULT_CODE_SECTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)__section_end(DEFAULT_CODE_SECTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)__section_begin(DEFAULT_CSTACK_SECTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)__section_end(DEFAULT_CSTACK_SECTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if we are using keil(armcc) or mdk(iccarm), we probably use the defult link script supplied by the IDE.
|
||||||
|
* the way to locate the text/stack section start and limit is to find them in default link script.
|
||||||
|
* but if we build our project by makefile(or something like scons, cmake, etc), we probably need to write
|
||||||
|
* our own link scrpit, if so, we should do like this(just a demo):
|
||||||
|
*
|
||||||
|
_stext = .;
|
||||||
|
.text : {
|
||||||
|
*(.text.startup)
|
||||||
|
*(.text)
|
||||||
|
*(.text.*)
|
||||||
|
}
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
__bss_start = .;
|
||||||
|
.bss : {
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
_sstack = .;
|
||||||
|
*(.cstack)
|
||||||
|
_estack = .;
|
||||||
|
}
|
||||||
|
__bss_end = .;
|
||||||
|
* by this, we can locate text/stack section start and limit by _stext/_etext and _sstack/_estack
|
||||||
|
*/
|
||||||
|
#define DEFAULT_CODE_SECTION_START _stext
|
||||||
|
#define DEFAULT_CODE_SECTION_END _etext
|
||||||
|
#define DEFAULT_CSTACK_SECTION_START _sstack
|
||||||
|
#define DEFAULT_CSTACK_SECTION_END _estack
|
||||||
|
|
||||||
|
extern const int DEFAULT_CODE_SECTION_START;
|
||||||
|
extern const int DEFAULT_CODE_SECTION_END;
|
||||||
|
|
||||||
|
extern const int DEFAULT_CSTACK_SECTION_START;
|
||||||
|
extern const int DEFAULT_CSTACK_SECTION_END;
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_START));
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_END));
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_START));
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
|
||||||
|
{
|
||||||
|
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_END));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer);
|
||||||
|
|
||||||
|
__KERNEL__ int fault_default_log_writer(const char *format, ...);
|
||||||
|
|
||||||
|
__KERNEL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _TOS_FAULT_H_ */
|
||||||
|
|
264
arch/linux/common/tos_cpu.c
Normal file
264
arch/linux/common/tos_cpu.c
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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.h>
|
||||||
|
|
||||||
|
__API__ uint32_t tos_cpu_clz(uint32_t val)
|
||||||
|
{
|
||||||
|
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 0u)
|
||||||
|
uint32_t nbr_lead_zeros = 0;
|
||||||
|
|
||||||
|
if (!(val & 0XFFFF0000)) {
|
||||||
|
val <<= 16;
|
||||||
|
nbr_lead_zeros += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(val & 0XFF000000)) {
|
||||||
|
val <<= 8;
|
||||||
|
nbr_lead_zeros += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(val & 0XF0000000)) {
|
||||||
|
val <<= 4;
|
||||||
|
nbr_lead_zeros += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(val & 0XC0000000)) {
|
||||||
|
val <<= 2;
|
||||||
|
nbr_lead_zeros += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(val & 0X80000000)) {
|
||||||
|
nbr_lead_zeros += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!val) {
|
||||||
|
nbr_lead_zeros += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (nbr_lead_zeros);
|
||||||
|
#else
|
||||||
|
return port_clz(val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__API__ void tos_cpu_int_disable(void)
|
||||||
|
{
|
||||||
|
port_int_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
__API__ void tos_cpu_int_enable(void)
|
||||||
|
{
|
||||||
|
port_int_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void)
|
||||||
|
{
|
||||||
|
return port_cpsr_save();
|
||||||
|
}
|
||||||
|
|
||||||
|
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr)
|
||||||
|
{
|
||||||
|
port_cpsr_restore(cpsr);
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_init(void)
|
||||||
|
{
|
||||||
|
k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second;
|
||||||
|
cpu_systick_init(k_cpu_cycle_per_tick);
|
||||||
|
|
||||||
|
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
|
||||||
|
tos_cpu_hrtimer_init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_reset(void)
|
||||||
|
{
|
||||||
|
port_cpu_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_sched_start(void)
|
||||||
|
{
|
||||||
|
port_sched_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_context_switch(void)
|
||||||
|
{
|
||||||
|
port_context_switch();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_irq_context_switch(void)
|
||||||
|
{
|
||||||
|
port_irq_context_switch();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick)
|
||||||
|
{
|
||||||
|
port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO);
|
||||||
|
port_systick_config(cycle_per_tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOS_CFG_TICKLESS_EN > 0u
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set value to systick reload value register
|
||||||
|
*
|
||||||
|
* @param cycles The value set to register
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE__ void cpu_systick_reload(k_cycle_t cycle_per_tick)
|
||||||
|
{
|
||||||
|
port_systick_reload(cycle_per_tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable systick interrupt
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
__KERNEL__ void cpu_systick_resume(void)
|
||||||
|
{
|
||||||
|
port_systick_resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable systick interrupt
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
__KERNEL__ void cpu_systick_suspend(void)
|
||||||
|
{
|
||||||
|
port_systick_suspend();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ k_time_t cpu_systick_max_delay_millisecond(void)
|
||||||
|
{
|
||||||
|
return port_systick_max_delay_millisecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_expires_set(k_time_t millisecond)
|
||||||
|
{
|
||||||
|
k_cycle_t cycles;
|
||||||
|
|
||||||
|
cycles = (k_cycle_t)((uint64_t)millisecond * TOS_CFG_CPU_CLOCK / K_TIME_MILLISEC_PER_SEC); /* CLOCK means cycle per second */
|
||||||
|
|
||||||
|
cpu_systick_reload(cycles - 12); /* interrupt delay */
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_pending_reset(void)
|
||||||
|
{
|
||||||
|
port_systick_pending_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_systick_reset(void)
|
||||||
|
{
|
||||||
|
cpu_systick_reload(k_cpu_cycle_per_tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TOS_CFG_TICKLESS_EN */
|
||||||
|
|
||||||
|
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_sleep_mode_enter(void)
|
||||||
|
{
|
||||||
|
port_sleep_mode_enter();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_stop_mode_enter(void)
|
||||||
|
{
|
||||||
|
port_stop_mode_enter();
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_standby_mode_enter(void)
|
||||||
|
{
|
||||||
|
port_standby_mode_enter();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TOS_CFG_PWR_MGR_EN */
|
||||||
|
|
||||||
|
__KERNEL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||||
|
void *arg,
|
||||||
|
void *exit,
|
||||||
|
k_stack_t *stk_base,
|
||||||
|
size_t stk_size)
|
||||||
|
{
|
||||||
|
cpu_context_t *sp;
|
||||||
|
|
||||||
|
sp = (cpu_context_t *)&stk_base[stk_size];
|
||||||
|
sp = (cpu_context_t *)(((cpu_addr_t)sp & 0xFFFFFFFFFFFFFFF8)-sizeof(cpu_context_t));
|
||||||
|
|
||||||
|
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||||
|
uint8_t *slot = (uint8_t *)&stk_base[0];
|
||||||
|
for (; slot < (uint8_t *)sp; ++slot) {
|
||||||
|
*slot = 0xCC;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sp->entry = entry;
|
||||||
|
sp->arg = arg;
|
||||||
|
sp->exit = exit;
|
||||||
|
sp->thread_id = port_create_thread(sp);
|
||||||
|
|
||||||
|
return (k_stack_t *)sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||||
|
|
||||||
|
__KERNEL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth)
|
||||||
|
{
|
||||||
|
uint8_t *slot;
|
||||||
|
uint8_t *sp, *bp;
|
||||||
|
int the_depth = 0;
|
||||||
|
|
||||||
|
bp = (uint8_t *)&stk_base[0];
|
||||||
|
|
||||||
|
sp = &stk_base[stk_size];
|
||||||
|
sp = (uint8_t *)((cpu_addr_t)sp & 0xFFFFFFFFFFFFFFF8);
|
||||||
|
|
||||||
|
for (slot = sp - 1; slot >= bp; --slot) {
|
||||||
|
if (*slot != 0xCC) {
|
||||||
|
the_depth = sp - slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*depth = the_depth;
|
||||||
|
if (the_depth == stk_size) {
|
||||||
|
return K_ERR_TASK_STK_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
return K_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
__KERNEL__ void cpu_flush_fpu(void)
|
||||||
|
{
|
||||||
|
(void)__get_FPSCR();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__KERNEL__ void cpu_fault_diagnosis(void)
|
||||||
|
{
|
||||||
|
port_fault_diagnosis();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||||
|
|
268
arch/linux/common/tos_fault.c
Normal file
268
arch/linux/common/tos_fault.c
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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.h"
|
||||||
|
|
||||||
|
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||||
|
|
||||||
|
__STATIC_INLINE__ void fault_spin(void)
|
||||||
|
{
|
||||||
|
tos_knl_sched_lock();
|
||||||
|
tos_cpu_int_disable();
|
||||||
|
while (K_TRUE) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EXC_RETURN:
|
||||||
|
31 - 28 : EXC_RETURN flag
|
||||||
|
27 - 5 : reserved
|
||||||
|
4 : 1, basic stack frame; 0, extended stack frame
|
||||||
|
3 : 1, return to Thread mode; 0, return to Handler mode
|
||||||
|
2 : 1, return to PSP; 0, return to MSP
|
||||||
|
1 : reserved, 0
|
||||||
|
0 : reserved, 1
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE__ int fault_is_on_task(cpu_data_t lr)
|
||||||
|
{
|
||||||
|
return (lr & (1u << 2)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ int fault_is_thumb(cpu_data_t psr)
|
||||||
|
{
|
||||||
|
return (psr & (1u << 24)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE__ int fault_is_code(fault_info_t *info, cpu_data_t value)
|
||||||
|
{
|
||||||
|
return value >= info->code_start && value <= info->code_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
__STATIC_INLINE__ int fault_is_extended_stack_frame(cpu_data_t lr)
|
||||||
|
{
|
||||||
|
return (lr & (1u << 4)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC__ void fault_dump_fpu_frame(fault_fpu_frame_t *fpu_frame)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* As known, v7-m has a feature named "LAZY PUSH", for the reason we do not do any float
|
||||||
|
* operation in fault_backtrace, cpu will not do the real fpu register push to the stack.
|
||||||
|
* that means the value we dump in fault_dump_fpu_frame will not be the correct value of
|
||||||
|
* each FPU register.
|
||||||
|
* We define a function here which access to FPSCR, if this function involved, cpu will do
|
||||||
|
* the real FPU register push so we will get the correct dump.
|
||||||
|
* I know it's ugly, but it works. If you know a better way, please tell me.
|
||||||
|
*/
|
||||||
|
cpu_flush_fpu();
|
||||||
|
|
||||||
|
k_fault_log_writer("\n\n====================== FPU Registers =======================\n");
|
||||||
|
k_fault_log_writer(" %s: %08x\n", "FPSCR", fpu_frame->fpscr);
|
||||||
|
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||||
|
"S0 ", fpu_frame->s0,
|
||||||
|
"S1 ", fpu_frame->s1,
|
||||||
|
"S2 ", fpu_frame->s2,
|
||||||
|
"S3 ", fpu_frame->s3);
|
||||||
|
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||||
|
"S4 ", fpu_frame->s4,
|
||||||
|
"S5 ", fpu_frame->s5,
|
||||||
|
"S6 ", fpu_frame->s6,
|
||||||
|
"S7 ", fpu_frame->s7);
|
||||||
|
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||||
|
"S8 ", fpu_frame->s8,
|
||||||
|
"S9 ", fpu_frame->s9,
|
||||||
|
"S10", fpu_frame->s10,
|
||||||
|
"S11", fpu_frame->s11);
|
||||||
|
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||||
|
"S12", fpu_frame->s12,
|
||||||
|
"S13", fpu_frame->s13,
|
||||||
|
"S14", fpu_frame->s14,
|
||||||
|
"S15", fpu_frame->s15);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__STATIC__ void fault_dump_cpu_frame(fault_cpu_frame_t *cpu_frame)
|
||||||
|
{
|
||||||
|
k_fault_log_writer("\n\n====================== CPU Registers =======================\n");
|
||||||
|
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||||
|
"R0 ", cpu_frame->r0,
|
||||||
|
"R1 ", cpu_frame->r1,
|
||||||
|
"R2 ", cpu_frame->r2,
|
||||||
|
"R3 ", cpu_frame->r3);
|
||||||
|
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
|
||||||
|
"R12", cpu_frame->r12,
|
||||||
|
"LR ", cpu_frame->lr,
|
||||||
|
"PC ", cpu_frame->pc,
|
||||||
|
"PSR", cpu_frame->spsr);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC__ void fault_dump_stack(fault_info_t *info, size_t depth)
|
||||||
|
{
|
||||||
|
cpu_addr_t sp = info->sp_before_fault;;
|
||||||
|
|
||||||
|
k_fault_log_writer("\nTASK STACK DUMP:\n");
|
||||||
|
while (sp <= info->stack_limit && depth--) {
|
||||||
|
k_fault_log_writer(" addr: %08x data: %08x\n", sp, (cpu_data_t)*(cpu_data_t *)sp);
|
||||||
|
sp += sizeof(cpu_addr_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC__ void fault_call_stack_backtrace(fault_info_t *info, size_t depth)
|
||||||
|
{
|
||||||
|
cpu_data_t value;
|
||||||
|
cpu_addr_t sp = info->sp_before_fault;
|
||||||
|
|
||||||
|
if (info->is_stk_ovrf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_fault_log_writer("\n\n====================== Dump Call Stack =====================\n");
|
||||||
|
|
||||||
|
k_fault_log_writer(" %x\n", info->pc);
|
||||||
|
|
||||||
|
/* walk through the stack, check every content on stack whether is a instruction(code) */
|
||||||
|
for (; sp < info->stack_limit && depth; sp += sizeof(cpu_addr_t)) {
|
||||||
|
value = *((cpu_addr_t *)sp) - sizeof(cpu_addr_t);
|
||||||
|
|
||||||
|
/* if thumb, a instruction's first bit must be 1 */
|
||||||
|
if (info->is_thumb && !(value & 1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fault_is_code(info, value)) {
|
||||||
|
k_fault_log_writer(" %x\n", value);
|
||||||
|
--depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC__ void fault_dump_task(fault_info_t *info)
|
||||||
|
{
|
||||||
|
k_task_t *task;
|
||||||
|
|
||||||
|
if (!info->is_on_task) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
task = k_curr_task;
|
||||||
|
k_fault_log_writer("\n\n====================== Fault on task =======================\n");
|
||||||
|
k_fault_log_writer(" TASK NAME: %s\n", task->name);
|
||||||
|
k_fault_log_writer(" STK BASE: %x\n", info->stack_start);
|
||||||
|
k_fault_log_writer(" STK SIZE: %x\n", task->stk_size * sizeof(k_stack_t));
|
||||||
|
k_fault_log_writer(" STK LIMIT: %x\n", info->stack_limit);
|
||||||
|
|
||||||
|
if (!info->is_stk_ovrf) {
|
||||||
|
fault_dump_stack(info, K_FAULT_STACK_DUMP_DEPTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC__ void fault_dump_information(fault_info_t *info)
|
||||||
|
{
|
||||||
|
k_fault_log_writer("\n\n================== Dump Fault Information ==================\n");
|
||||||
|
k_fault_log_writer(" THUMB: %s\n", info->is_thumb ? "TRUE" : "FALSE");
|
||||||
|
k_fault_log_writer(" ON TASK: %s\n", info->is_on_task? "TRUE" : "FALSE");
|
||||||
|
k_fault_log_writer(" STK OVRF: %s\n", info->is_stk_ovrf? "TRUE" : "FALSE");
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
k_fault_log_writer(" EXT STK: %s\n", info->is_ext_stk_frm? "TRUE" : "FALSE");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
k_fault_log_writer(" PC: %08x\n", info->pc);
|
||||||
|
k_fault_log_writer(" SP: %08x\n", info->sp_before_fault);
|
||||||
|
k_fault_log_writer(" STK START: %08x\n", info->stack_start);
|
||||||
|
k_fault_log_writer(" STK LIMIT: %08x\n", info->stack_limit);
|
||||||
|
k_fault_log_writer(" COD START: %08x\n", info->code_start);
|
||||||
|
k_fault_log_writer(" COD LIMIT: %08x\n", info->code_limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC__ void fault_gather_information(cpu_data_t lr, fault_exc_frame_t *frame, fault_info_t *info)
|
||||||
|
{
|
||||||
|
info->is_thumb = fault_is_thumb(frame->cpu_frame.spsr);
|
||||||
|
info->is_on_task = fault_is_on_task(lr);
|
||||||
|
|
||||||
|
info->pc = frame->cpu_frame.pc;
|
||||||
|
|
||||||
|
info->sp_before_fault = (cpu_addr_t)frame + sizeof(fault_cpu_frame_t);
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
info->is_ext_stk_frm = fault_is_extended_stack_frame(lr);
|
||||||
|
|
||||||
|
if (info->is_ext_stk_frm) {
|
||||||
|
info->sp_before_fault += sizeof(fault_fpu_frame_t);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
info->code_start = fault_code_start();
|
||||||
|
info->code_limit = fault_code_limit();
|
||||||
|
|
||||||
|
if (info->is_on_task) {
|
||||||
|
info->stack_start = (cpu_addr_t)k_curr_task->stk_base;
|
||||||
|
info->stack_limit = info->stack_start + k_curr_task->stk_size * sizeof(k_task_t);
|
||||||
|
} else {
|
||||||
|
info->stack_start = fault_msp_start();
|
||||||
|
info->stack_limit = fault_msp_limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
info->is_stk_ovrf = (info->sp_before_fault < info->stack_start || info->sp_before_fault > info->stack_limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ int fault_default_log_writer(const char *format, ...)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
len = vprintf(format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer)
|
||||||
|
{
|
||||||
|
k_fault_log_writer = log_writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
__KERNEL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame)
|
||||||
|
{
|
||||||
|
fault_info_t info;
|
||||||
|
|
||||||
|
fault_gather_information(lr, frame, &info);
|
||||||
|
|
||||||
|
fault_dump_information(&info);
|
||||||
|
|
||||||
|
fault_dump_task(&info);
|
||||||
|
|
||||||
|
fault_dump_cpu_frame(&frame->cpu_frame);
|
||||||
|
|
||||||
|
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
|
||||||
|
if (info.is_ext_stk_frm) {
|
||||||
|
fault_dump_fpu_frame(&frame->fpu_frame);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fault_call_stack_backtrace(&info, K_FAULT_CALL_STACK_BACKTRACE_DEPTH);
|
||||||
|
|
||||||
|
cpu_fault_diagnosis();
|
||||||
|
|
||||||
|
fault_spin();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
359
arch/linux/posix/gcc/port.c
Normal file
359
arch/linux/posix/gcc/port.c
Normal file
@@ -0,0 +1,359 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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.
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* 'Software'), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tos.h"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/times.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
extern k_task_t *k_curr_task;
|
||||||
|
extern k_task_t *k_next_task;
|
||||||
|
|
||||||
|
__PORT__ void _handle_tick_signal();
|
||||||
|
__PORT__ void _handle_context_switch();
|
||||||
|
__PORT__ void _delay_ms(uint32_t ms);
|
||||||
|
__PORT__ void _suspend_thread(pthread_t thread_id);
|
||||||
|
__PORT__ void _resume_thread(pthread_t thread_id);
|
||||||
|
__PORT__ void _wait_resume();
|
||||||
|
__PORT__ void _handle_suspend_thread();
|
||||||
|
__PORT__ void _handle_resume_thread();
|
||||||
|
__PORT__ void *_thread_entry(void *arg);
|
||||||
|
__PORT__ void _suspend_task(k_task_t *task);
|
||||||
|
__PORT__ void _resume_task(k_task_t *task);
|
||||||
|
__PORT__ void _install_signal(int sig,void (*func)(int));
|
||||||
|
__PORT__ void _filter_signal(sigset_t *sigset);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
sigset_t signal_mask;
|
||||||
|
uint32_t count;
|
||||||
|
}interrupt_manager;
|
||||||
|
|
||||||
|
interrupt_manager _int_manager={
|
||||||
|
.count = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
__PORT__ void port_int_disable(void)
|
||||||
|
{
|
||||||
|
sigset_t signal_mask,*manager_mask=NULL;
|
||||||
|
if(_int_manager.count == 0){
|
||||||
|
manager_mask = &(_int_manager.signal_mask);
|
||||||
|
}
|
||||||
|
_int_manager.count ++;
|
||||||
|
sigfillset(&signal_mask);
|
||||||
|
_filter_signal(&signal_mask);
|
||||||
|
pthread_sigmask(SIG_BLOCK,&signal_mask,manager_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_int_enable(void)
|
||||||
|
{
|
||||||
|
if(_int_manager.count == 0) return;
|
||||||
|
|
||||||
|
_int_manager.count--;
|
||||||
|
if(_int_manager.count == 0){
|
||||||
|
sigaddset(&(_int_manager.signal_mask),SIG_RESUME); //ensure SIG_RESUME is blocked
|
||||||
|
_filter_signal(&(_int_manager.signal_mask));
|
||||||
|
pthread_sigmask(SIG_SETMASK,&(_int_manager.signal_mask),NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ cpu_cpsr_t port_cpsr_save(void)
|
||||||
|
{
|
||||||
|
port_int_disable();
|
||||||
|
return (cpu_cpsr_t)_int_manager.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr)
|
||||||
|
{
|
||||||
|
port_int_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ pthread_t port_create_thread(void *arg)
|
||||||
|
{
|
||||||
|
pthread_t thread_id;
|
||||||
|
pthread_create(&thread_id,NULL,_thread_entry,arg);
|
||||||
|
return thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_sched_start(void)
|
||||||
|
{
|
||||||
|
_install_signal(SIG_SUSPEND, _handle_suspend_thread);
|
||||||
|
_install_signal(SIG_RESUME, _handle_resume_thread);
|
||||||
|
_install_signal(SIG_CONTEXT_SWITCH, _handle_context_switch);
|
||||||
|
|
||||||
|
k_curr_task = k_next_task;
|
||||||
|
_resume_task(k_curr_task);
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
_delay_ms(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_context_switch(void)
|
||||||
|
{
|
||||||
|
raise(SIG_CONTEXT_SWITCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_irq_context_switch(void)
|
||||||
|
{
|
||||||
|
raise(SIG_CONTEXT_SWITCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_cpu_reset(void)
|
||||||
|
{
|
||||||
|
printf("func %s\n",__FUNCTION__);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||||
|
{
|
||||||
|
struct itimerval itimer, oitimer;
|
||||||
|
uint32_t timeer_usec = cycle_per_tick/(TOS_CFG_CPU_CLOCK/1000000u);
|
||||||
|
|
||||||
|
_install_signal(SIG_TICK,_handle_tick_signal);
|
||||||
|
|
||||||
|
/* Initialise the structure with the current timer information. */
|
||||||
|
if ( 0 == getitimer( TIMER_TYPE, &itimer ) )
|
||||||
|
{
|
||||||
|
/* Set the interval between timer events. */
|
||||||
|
itimer.it_interval.tv_sec = 0;
|
||||||
|
itimer.it_interval.tv_usec = timeer_usec;
|
||||||
|
|
||||||
|
/* Set the current count-down. */
|
||||||
|
itimer.it_value.tv_sec = 0;
|
||||||
|
itimer.it_value.tv_usec = timeer_usec;
|
||||||
|
|
||||||
|
/* Set-up the timer interrupt. */
|
||||||
|
if ( 0 != setitimer( TIMER_TYPE, &itimer, &oitimer ) )
|
||||||
|
{
|
||||||
|
printf( "set timer problem.\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf( "get timer problem.\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _filter_signal(sigset_t *sigset)
|
||||||
|
{
|
||||||
|
sigdelset(sigset,SIGINT);
|
||||||
|
sigdelset(sigset,SIGKILL); //ensure program cloud be kill
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__PORT__ uint64_t _get_time_ms(void)
|
||||||
|
{
|
||||||
|
struct timeval timer;
|
||||||
|
gettimeofday( &timer, NULL );
|
||||||
|
|
||||||
|
return (1000 * timer.tv_sec + timer.tv_usec/1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _delay_ms(uint32_t ms)
|
||||||
|
{
|
||||||
|
uint64_t start_time = _get_time_ms();
|
||||||
|
do{
|
||||||
|
usleep(100);
|
||||||
|
}while((_get_time_ms() - start_time) < ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _install_signal(int sig,void (*func)(int))
|
||||||
|
{
|
||||||
|
struct sigaction sig_install;
|
||||||
|
|
||||||
|
sig_install.sa_flags = 0;
|
||||||
|
sig_install.sa_handler = func;
|
||||||
|
sigfillset( &sig_install.sa_mask );
|
||||||
|
|
||||||
|
if ( 0 != sigaction( sig, &sig_install, NULL ) )
|
||||||
|
{
|
||||||
|
printf( "problem installing %d\n",sig );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _handle_tick_signal()
|
||||||
|
{
|
||||||
|
if(tos_knl_is_running()) {
|
||||||
|
tos_knl_irq_enter();
|
||||||
|
tos_tick_handler();
|
||||||
|
tos_knl_irq_leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _suspend_thread(pthread_t thread_id)
|
||||||
|
{
|
||||||
|
pthread_kill(thread_id,SIG_SUSPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _resume_thread(pthread_t thread_id)
|
||||||
|
{
|
||||||
|
pthread_kill(thread_id,SIG_RESUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _suspend_task(k_task_t *task)
|
||||||
|
{
|
||||||
|
cpu_context_t *context = (cpu_context_t *)(task->sp);
|
||||||
|
pthread_t thread_id = context->thread_id;
|
||||||
|
_suspend_thread(thread_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _resume_task(k_task_t *task)
|
||||||
|
{
|
||||||
|
cpu_context_t *context = (cpu_context_t *)(task->sp);
|
||||||
|
pthread_t thread_id = context->thread_id;
|
||||||
|
_resume_thread(thread_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _wait_resume()
|
||||||
|
{
|
||||||
|
sigset_t signals;
|
||||||
|
int sig;
|
||||||
|
sigemptyset( &signals );
|
||||||
|
sigaddset( &signals, SIG_RESUME);
|
||||||
|
pthread_sigmask(SIG_BLOCK, &signals,NULL);
|
||||||
|
sigwait(&signals,&sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _handle_suspend_thread()
|
||||||
|
{
|
||||||
|
_wait_resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _handle_resume_thread()
|
||||||
|
{
|
||||||
|
printf("some thread not block SIG_RESUME\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void *_thread_entry(void *arg)
|
||||||
|
{
|
||||||
|
cpu_context_t *params = (cpu_context_t *)arg;
|
||||||
|
_wait_resume();
|
||||||
|
params->entry(params->arg);
|
||||||
|
params->exit(params->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void _handle_context_switch()
|
||||||
|
{
|
||||||
|
_suspend_task(k_curr_task);
|
||||||
|
k_curr_task = k_next_task;
|
||||||
|
_resume_task(k_curr_task);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOS_CFG_TICKLESS_EN > 0u
|
||||||
|
|
||||||
|
__PORT__ k_time_t port_systick_max_delay_millisecond(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
||||||
|
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
|
||||||
|
{
|
||||||
|
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__PORT__ void port_fault_diagnosis(void)
|
||||||
|
{
|
||||||
|
port_fault_regs_t regs;
|
||||||
|
|
||||||
|
port_fault_do_diagnosis(®s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// implementation jump to fault_backtrace
|
||||||
|
|
||||||
|
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||||
|
|
121
arch/linux/posix/gcc/port.h
Normal file
121
arch/linux/posix/gcc/port.h
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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.
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* 'Software'), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PORT_H_
|
||||||
|
#define _PORT_H_
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define SIG_SUSPEND SIGUSR1
|
||||||
|
#define SIG_RESUME SIGUSR2
|
||||||
|
#define SIG_CONTEXT_SWITCH SIGRTMIN
|
||||||
|
#define SIG_TICK SIGALRM
|
||||||
|
#define TIMER_TYPE ITIMER_REAL
|
||||||
|
|
||||||
|
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||||
|
typedef struct port_fault_regs {
|
||||||
|
uint32_t error_flags;
|
||||||
|
} port_fault_regs_t;
|
||||||
|
|
||||||
|
enum fault_info {
|
||||||
|
//FAULT_INFO_XXX,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const fault_msg[] = {
|
||||||
|
//[FAULT_INFO_XXX] = "FAULT_INFO_XXX string msg",
|
||||||
|
};
|
||||||
|
|
||||||
|
__PORT__ void port_fault_diagnosis(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
|
||||||
|
__PORT__ uint32_t port_clz(uint32_t val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__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); //ok
|
||||||
|
|
||||||
|
__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); //ok
|
||||||
|
|
||||||
|
__PORT__ pthread_t port_create_thread(void *arg);
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#endif /* _PORT_H_ */
|
||||||
|
|
35
arch/linux/posix/gcc/port_config.h
Normal file
35
arch/linux/posix/gcc/port_config.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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_64
|
||||||
|
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_64
|
||||||
|
#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
|
||||||
|
|
||||||
|
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||||
|
#define TOS_CFG_CPU_ARM_FPU_EN 1u
|
||||||
|
#else
|
||||||
|
#define TOS_CFG_CPU_ARM_FPU_EN 0u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _PORT_CONFIG_H_ */
|
||||||
|
|
41
board/Linux_Posix/hello_world/CMakeLists.txt
Normal file
41
board/Linux_Posix/hello_world/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
|
||||||
|
project(hello_world)
|
||||||
|
|
||||||
|
set(CMAKE_BUILD_TYPE "Debug")
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
|
||||||
|
|
||||||
|
set(TINY_ROOT ../../../)
|
||||||
|
|
||||||
|
include_directories(${TINY_ROOT}/osal/cmsis_os)
|
||||||
|
include_directories(${TINY_ROOT}/kernel/core/include)
|
||||||
|
include_directories(${TINY_ROOT}/kernel/evtdrv/include)
|
||||||
|
include_directories(${TINY_ROOT}/kernel/hal/include)
|
||||||
|
include_directories(${TINY_ROOT}/kernel/pm/include)
|
||||||
|
|
||||||
|
aux_source_directory(${TINY_ROOT}/osal/cmsis_os CMSIS_SRCS)
|
||||||
|
aux_source_directory(${TINY_ROOT}/kernel/core CORE_SRCS)
|
||||||
|
aux_source_directory(${TINY_ROOT}/kernel/evtdrv EVTDRV_SRCS)
|
||||||
|
aux_source_directory(${TINY_ROOT}/kernel/pm PM_SRCS)
|
||||||
|
|
||||||
|
set(ARCH_ROOT ${TINY_ROOT}/arch/linux)
|
||||||
|
|
||||||
|
include_directories(${ARCH_ROOT}/common/include)
|
||||||
|
include_directories(${ARCH_ROOT}/posix/gcc)
|
||||||
|
|
||||||
|
aux_source_directory(${ARCH_ROOT}/common ARCH_COMMON_SRCS)
|
||||||
|
aux_source_directory(${ARCH_ROOT}/posix/gcc ARCH_POSIX_SRCS)
|
||||||
|
|
||||||
|
set(ARCH_SRCS ${ARCH_COMMON_SRCS} ${ARCH_POSIX_SRCS})
|
||||||
|
|
||||||
|
set(TINY_SRCS ${ARCH_SRCS} ${CMSIS_SRCS} ${EVTDRV_SRCS} ${PM_SRCS} ${CORE_SRCS} )
|
||||||
|
|
||||||
|
include_directories(./)
|
||||||
|
include_directories(./inc)
|
||||||
|
|
||||||
|
set(APP_SRCS src/main.c)
|
||||||
|
|
||||||
|
add_executable(hello_world ${APP_SRCS} ${TINY_SRCS})
|
||||||
|
|
||||||
|
target_link_libraries(hello_world pthread)
|
46
board/Linux_Posix/hello_world/inc/tos_config.h
Normal file
46
board/Linux_Posix/hello_world/inc/tos_config.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef _TOS_CONFIG_H_
|
||||||
|
#define _TOS_CONFIG_H_
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
|
||||||
|
#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量
|
||||||
|
|
||||||
|
#define TOS_CFG_ROUND_ROBIN_EN 1u // 配置TencentOS tiny的内核是否开启时间片轮转
|
||||||
|
|
||||||
|
#define TOS_CFG_OBJECT_VERIFY 0u // 配置TencentOS tiny是否校验指针合法
|
||||||
|
|
||||||
|
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
|
||||||
|
|
||||||
|
#define TOS_CFG_MMHEAP_EN 1u // 配置TencentOS tiny是否开启动态内存模块
|
||||||
|
|
||||||
|
#define TOS_CFG_MMHEAP_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
|
||||||
|
|
||||||
|
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
|
||||||
|
|
||||||
|
#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块
|
||||||
|
|
||||||
|
#define TOS_CFG_QUEUE_EN 1u // 配置TencentOS tiny是否开启队列模块
|
||||||
|
|
||||||
|
#define TOS_CFG_TIMER_EN 1u // 配置TencentOS tiny是否开启软件定时器模块
|
||||||
|
|
||||||
|
#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块
|
||||||
|
|
||||||
|
#define TOS_CFG_MMBLK_EN 1u
|
||||||
|
|
||||||
|
#if (TOS_CFG_QUEUE_EN > 0u)
|
||||||
|
#define TOS_CFG_MSG_EN 1u
|
||||||
|
#else
|
||||||
|
#define TOS_CFG_MSG_EN 0u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TOS_CFG_MSG_POOL_SIZE 10u // 配置TencentOS tiny消息队列大小
|
||||||
|
|
||||||
|
#define TOS_CFG_IDLE_TASK_STK_SIZE 256u // 配置TencentOS tiny空闲任务栈大小
|
||||||
|
|
||||||
|
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率
|
||||||
|
|
||||||
|
#define TOS_CFG_CPU_CLOCK 1000000u // 配置TencentOS tiny CPU频率
|
||||||
|
|
||||||
|
#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式
|
||||||
|
|
||||||
|
#endif
|
36
board/Linux_Posix/hello_world/readme.md
Normal file
36
board/Linux_Posix/hello_world/readme.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# How to run the demo in linux
|
||||||
|
|
||||||
|
## step1
|
||||||
|
make sure your develop environment.
|
||||||
|
+ `cmake` and version greater than 3.8.2
|
||||||
|
+ `gcc` `gdb` `make` is installed
|
||||||
|
|
||||||
|
## step2
|
||||||
|
make `build` directory and compile in `build`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
## step3
|
||||||
|
run program !!
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# in build directory
|
||||||
|
./hello_world
|
||||||
|
```
|
||||||
|
|
||||||
|
## other
|
||||||
|
you can copy this demo to other path, but if you want do it,
|
||||||
|
you need modify `CMakeLists.txt`. find line
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
set(TINY_ROOT ../../../)
|
||||||
|
```
|
||||||
|
|
||||||
|
and modify `path-to-tinyos`
|
||||||
|
```cmake
|
||||||
|
set(TINY_ROOT path-to-tinyos)
|
||||||
|
```
|
53
board/Linux_Posix/hello_world/src/main.c
Normal file
53
board/Linux_Posix/hello_world/src/main.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#include "cmsis_os.h"
|
||||||
|
|
||||||
|
#define TASK1_STK_SIZE 512
|
||||||
|
void task1(void *arg);
|
||||||
|
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);
|
||||||
|
|
||||||
|
#define TASK2_STK_SIZE 512
|
||||||
|
void task2(void *arg);
|
||||||
|
osThreadDef(task2, osPriorityNormal, 1, TASK2_STK_SIZE);
|
||||||
|
|
||||||
|
void task1(void *arg)
|
||||||
|
{
|
||||||
|
int count = 1;
|
||||||
|
while (1) {
|
||||||
|
printf("###This is task1, %d\r\n", count++);
|
||||||
|
osDelay(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void task2(void *arg)
|
||||||
|
{
|
||||||
|
int count = 1;
|
||||||
|
while (1) {
|
||||||
|
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||||
|
k_err_t rc;
|
||||||
|
int depth;
|
||||||
|
|
||||||
|
rc = tos_task_stack_draught_depth(K_NULL, &depth);
|
||||||
|
printf("%d %d\n", rc, depth);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("***This is task2, %d\r\n", count++);
|
||||||
|
osDelay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void application_entry(void *arg)
|
||||||
|
{
|
||||||
|
osThreadCreate(osThread(task1), NULL); // Create task1
|
||||||
|
osThreadCreate(osThread(task2), NULL); // Create task2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
osKernelInitialize(); //TOS Tiny kernel initialize
|
||||||
|
application_entry(NULL);
|
||||||
|
osKernelStart(); //Start TOS Tiny
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user