support avr architecture based on ATMega32
1. IAR project, see TencentOS-tiny\board\ATMega32\IAR, both 4.12 and 7.20 is supplied.
This commit is contained in:
157
arch/avr/ATMega32/iccavr/port_s.asm
Normal file
157
arch/avr/ATMega32/iccavr/port_s.asm
Normal file
@@ -0,0 +1,157 @@
|
||||
#include <iom32.h>
|
||||
|
||||
RSEG CODE
|
||||
|
||||
EXTERN k_curr_task
|
||||
EXTERN k_next_task
|
||||
|
||||
PUBLIC port_int_disable
|
||||
PUBLIC port_int_enable
|
||||
PUBLIC port_cpsr_save
|
||||
PUBLIC port_cpsr_restore
|
||||
PUBLIC port_sched_start
|
||||
PUBLIC port_irq_context_switch
|
||||
PUBLIC port_context_switch
|
||||
|
||||
port_int_disable:
|
||||
CLI
|
||||
RET
|
||||
|
||||
|
||||
port_int_enable:
|
||||
SEI
|
||||
RET
|
||||
|
||||
|
||||
port_cpsr_save:
|
||||
IN R16, SREG
|
||||
CLI
|
||||
RET
|
||||
|
||||
|
||||
port_cpsr_restore:
|
||||
OUT SREG, R16
|
||||
RET
|
||||
|
||||
|
||||
port_sched_start:
|
||||
JMP _context_restore
|
||||
|
||||
|
||||
port_irq_context_switch:
|
||||
port_context_switch:
|
||||
_context_save:
|
||||
PUSH R0
|
||||
|
||||
/* save SREG */
|
||||
IN R0, SREG
|
||||
CLI
|
||||
PUSH R0
|
||||
|
||||
PUSH R1
|
||||
PUSH R2
|
||||
PUSH R3
|
||||
PUSH R4
|
||||
PUSH R5
|
||||
PUSH R6
|
||||
PUSH R7
|
||||
PUSH R8
|
||||
PUSH R9
|
||||
PUSH R10
|
||||
PUSH R11
|
||||
PUSH R12
|
||||
PUSH R13
|
||||
PUSH R14
|
||||
PUSH R15
|
||||
PUSH R16
|
||||
PUSH R17
|
||||
PUSH R18
|
||||
PUSH R19
|
||||
PUSH R20
|
||||
PUSH R21
|
||||
PUSH R22
|
||||
PUSH R23
|
||||
PUSH R24
|
||||
PUSH R25
|
||||
PUSH R26
|
||||
PUSH R27
|
||||
PUSH R28
|
||||
PUSH R29
|
||||
PUSH R30
|
||||
PUSH R31
|
||||
|
||||
/* k_curr_task->sp = SP */
|
||||
LDS R30, k_curr_task
|
||||
LDS R31, k_curr_task + 1
|
||||
|
||||
IN R0, SPL
|
||||
IN R1, SPH
|
||||
|
||||
ST Z, R0
|
||||
STD Z + 1, R1
|
||||
|
||||
_context_restore:
|
||||
/* k_curr_task = k_next_task */
|
||||
LDI R28, low(k_curr_task)
|
||||
LDI R29, high(k_curr_task)
|
||||
|
||||
LDI R30, low(k_next_task)
|
||||
LDI R31, high(k_next_task)
|
||||
|
||||
LD R0, Z
|
||||
LDD R1, Z + 1
|
||||
|
||||
ST Y, R0
|
||||
STD Y + 1, R1
|
||||
|
||||
/* SP = k_next_task->sp */
|
||||
LDS R30, k_next_task
|
||||
LDS R31, k_next_task + 1
|
||||
|
||||
LD R0, Z
|
||||
LDD R1, Z + 1
|
||||
|
||||
OUT SPL, R0
|
||||
OUT SPH, R1
|
||||
|
||||
/* do restore */
|
||||
POP R31
|
||||
POP R30
|
||||
POP R29
|
||||
POP R28
|
||||
POP R27
|
||||
POP R26
|
||||
POP R25
|
||||
POP R24
|
||||
POP R23
|
||||
POP R22
|
||||
POP R21
|
||||
POP R20
|
||||
POP R19
|
||||
POP R18
|
||||
POP R17
|
||||
POP R16
|
||||
POP R15
|
||||
POP R14
|
||||
POP R13
|
||||
POP R12
|
||||
POP R11
|
||||
POP R10
|
||||
POP R9
|
||||
POP R8
|
||||
POP R7
|
||||
POP R6
|
||||
POP R5
|
||||
POP R4
|
||||
POP R3
|
||||
POP R2
|
||||
POP R1
|
||||
|
||||
POP R0
|
||||
OUT SREG, R0
|
||||
POP R0
|
||||
|
||||
RET
|
||||
|
||||
END
|
||||
|
155
arch/avr/common/include/tos_cpu.h
Normal file
155
arch/avr/common/include/tos_cpu.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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 struct cpu_context_st {
|
||||
cpu_data_t R31;
|
||||
cpu_data_t R30;
|
||||
cpu_data_t R29;
|
||||
cpu_data_t R28;
|
||||
cpu_data_t R27;
|
||||
cpu_data_t R26;
|
||||
cpu_data_t R25;
|
||||
cpu_data_t R24;
|
||||
cpu_data_t R23;
|
||||
cpu_data_t R22;
|
||||
cpu_data_t R21;
|
||||
cpu_data_t R20;
|
||||
cpu_data_t R19;
|
||||
cpu_data_t R18;
|
||||
cpu_data_t R17;
|
||||
cpu_data_t R16;
|
||||
cpu_data_t R15;
|
||||
cpu_data_t R14;
|
||||
cpu_data_t R13;
|
||||
cpu_data_t R12;
|
||||
cpu_data_t R11;
|
||||
cpu_data_t R10;
|
||||
cpu_data_t R9;
|
||||
cpu_data_t R8;
|
||||
cpu_data_t R7;
|
||||
cpu_data_t R6;
|
||||
cpu_data_t R5;
|
||||
cpu_data_t R4;
|
||||
cpu_data_t R3;
|
||||
cpu_data_t R2;
|
||||
cpu_data_t R1;
|
||||
|
||||
cpu_data_t SREG;
|
||||
cpu_data_t R0;
|
||||
|
||||
cpu_data_t PCH;
|
||||
cpu_data_t PCL;
|
||||
cpu_data_t LRH;
|
||||
cpu_data_t LRL;
|
||||
} 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
|
||||
|
||||
__KNL__ void cpu_init(void);
|
||||
|
||||
__KNL__ void cpu_reset(void);
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick);
|
||||
|
||||
__KNL__ void cpu_sched_start(void);
|
||||
|
||||
__KNL__ void cpu_context_switch(void);
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void);
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth);
|
||||
|
||||
#endif
|
||||
|
||||
__KNL__ 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
|
||||
|
||||
__KNL__ void cpu_systick_resume(void);
|
||||
|
||||
__KNL__ void cpu_systick_suspend(void);
|
||||
|
||||
__KNL__ void cpu_systick_reload_reset(void);
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void);
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void);
|
||||
|
||||
__KNL__ void cpu_systick_expires_set(k_time_t millisecond);
|
||||
|
||||
__KNL__ void cpu_systick_reset(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void);
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void);
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
|
||||
|
||||
__KNL__ 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_ */
|
||||
|
30
arch/avr/common/include/tos_cpu_def.h
Normal file
30
arch/avr/common/include/tos_cpu_def.h
Normal 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 _TOS_CPU_DEF_H_
|
||||
#define _TOS_CPU_DEF_H_
|
||||
|
||||
#define CPU_WORD_SIZE_08 1
|
||||
#define CPU_WORD_SIZE_16 2
|
||||
#define CPU_WORD_SIZE_32 3
|
||||
#define CPU_WORD_SIZE_64 4
|
||||
|
||||
#define CPU_STK_GROWTH_ASCENDING 1
|
||||
#define CPU_STK_GROWTH_DESCENDING 2
|
||||
|
||||
#endif /* _TOS_CPU_DEF_H_ */
|
||||
|
56
arch/avr/common/include/tos_cpu_types.h
Normal file
56
arch/avr/common/include/tos_cpu_types.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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_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_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 cpu_cpsr_t;
|
||||
|
||||
#endif
|
||||
|
206
arch/avr/common/include/tos_fault.h
Normal file
206
arch/avr/common/include/tos_fault.h
Normal file
@@ -0,0 +1,206 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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
|
||||
|
||||
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;
|
||||
} 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 */
|
||||
|
||||
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);
|
||||
|
||||
__KNL__ int fault_default_log_writer(const char *format, ...);
|
||||
|
||||
__KNL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_FAULT_H_ */
|
||||
|
306
arch/avr/common/tos_cpu.c
Normal file
306
arch/avr/common/tos_cpu.c
Normal file
@@ -0,0 +1,306 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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"
|
||||
|
||||
__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);
|
||||
}
|
||||
|
||||
__KNL__ 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
|
||||
}
|
||||
|
||||
__KNL__ void cpu_reset(void)
|
||||
{
|
||||
port_cpu_reset();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_sched_start(void)
|
||||
{
|
||||
port_sched_start();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_context_switch(void)
|
||||
{
|
||||
port_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_irq_context_switch(void)
|
||||
{
|
||||
port_irq_context_switch();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_init(k_cycle_t cycle_per_tick)
|
||||
{
|
||||
#if 0
|
||||
port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO);
|
||||
port_systick_config(cycle_per_tick);
|
||||
#endif
|
||||
}
|
||||
|
||||
#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
|
||||
*/
|
||||
__KNL__ void cpu_systick_resume(void)
|
||||
{
|
||||
port_systick_resume();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable systick interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__KNL__ void cpu_systick_suspend(void)
|
||||
{
|
||||
port_systick_suspend();
|
||||
}
|
||||
|
||||
__KNL__ k_time_t cpu_systick_max_delay_millisecond(void)
|
||||
{
|
||||
return port_systick_max_delay_millisecond();
|
||||
}
|
||||
|
||||
__KNL__ 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 */
|
||||
}
|
||||
|
||||
__KNL__ void cpu_systick_pending_reset(void)
|
||||
{
|
||||
port_systick_pending_reset();
|
||||
}
|
||||
|
||||
__KNL__ 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
|
||||
|
||||
__KNL__ void cpu_sleep_mode_enter(void)
|
||||
{
|
||||
port_sleep_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_stop_mode_enter(void)
|
||||
{
|
||||
port_stop_mode_enter();
|
||||
}
|
||||
|
||||
__KNL__ void cpu_standby_mode_enter(void)
|
||||
{
|
||||
port_standby_mode_enter();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_PWR_MGR_EN */
|
||||
|
||||
__KNL__ k_stack_t *cpu_task_stk_init(void *entry,
|
||||
void *arg,
|
||||
void *exit,
|
||||
k_stack_t *stk_base,
|
||||
size_t stk_size)
|
||||
{
|
||||
cpu_data_t *sp;
|
||||
|
||||
sp = (cpu_data_t *)&stk_base[stk_size];
|
||||
|
||||
#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 = (cpu_data_t)((uint16_t)exit & 0xFF); /* LRL */
|
||||
*--sp = (cpu_data_t)(((uint16_t)exit >> 8) & 0xFF); /* LRH */
|
||||
|
||||
*--sp = (cpu_data_t)((uint16_t)entry & 0xFF); /* PCL */
|
||||
*--sp = (cpu_data_t)(((uint16_t)entry >> 8) & 0xFF); /* PCH */
|
||||
|
||||
*--sp = 0x00; /* R0 */
|
||||
|
||||
/* SREG:
|
||||
---------------------------------
|
||||
| I | T | H | S | V | N | Z | C |
|
||||
|--------------------------------
|
||||
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
||||
---------------------------------
|
||||
*/
|
||||
*--sp = 0x80; /* SREG */
|
||||
|
||||
*--sp = 0x01; /* R1 */
|
||||
*--sp = 0x02; /* R2 */
|
||||
*--sp = 0x03; /* R3 */
|
||||
*--sp = 0x04; /* R4 */
|
||||
*--sp = 0x05; /* R5 */
|
||||
*--sp = 0x06; /* R6 */
|
||||
*--sp = 0x07; /* R7 */
|
||||
*--sp = 0x08; /* R8 */
|
||||
*--sp = 0x09; /* R9 */
|
||||
*--sp = 0x10; /* R10 */
|
||||
*--sp = 0x11; /* R11 */
|
||||
*--sp = 0x12; /* R12 */
|
||||
*--sp = 0x13; /* R13 */
|
||||
*--sp = 0x14; /* R14 */
|
||||
*--sp = 0x15; /* R15 */
|
||||
*--sp = 0x16; /* R16 */
|
||||
*--sp = 0x17; /* R17 */
|
||||
*--sp = 0x18; /* R18 */
|
||||
*--sp = 0x19; /* R19 */
|
||||
*--sp = 0x20; /* R20 */
|
||||
*--sp = 0x21; /* R21 */
|
||||
*--sp = 0x22; /* R22 */
|
||||
*--sp = 0x23; /* R23 */
|
||||
|
||||
*--sp = (cpu_data_t)((uint16_t)arg & 0xFF); /* R24 */
|
||||
*--sp = (cpu_data_t)(((uint16_t)arg >> 8) & 0xFF); /* R25 */
|
||||
|
||||
*--sp = 0x26; /* R26 X */
|
||||
*--sp = 0x27; /* R27 */
|
||||
*--sp = 0x28; /* R28 Y */
|
||||
*--sp = 0x29; /* R29 */
|
||||
*--sp = 0x30; /* R30 Z */
|
||||
*--sp = 0x31; /* R31 */
|
||||
|
||||
/* ATTENTION:
|
||||
must do a sp decrease here in AVR
|
||||
*/
|
||||
return (k_stack_t *)(--sp);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
|
||||
__KNL__ 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];
|
||||
|
||||
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
|
||||
|
||||
__KNL__ void cpu_fault_diagnosis(void)
|
||||
{
|
||||
port_fault_diagnosis();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
205
arch/avr/common/tos_fault.c
Normal file
205
arch/avr/common/tos_fault.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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"
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
__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");
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
__KNL__ 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;
|
||||
}
|
||||
|
||||
__KNL__ 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);
|
||||
|
||||
fault_call_stack_backtrace(&info, K_FAULT_CALL_STACK_BACKTRACE_DEPTH);
|
||||
|
||||
cpu_fault_diagnosis();
|
||||
|
||||
fault_spin();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
70
arch/stm8/iccstm8/port.h
Normal file
70
arch/stm8/iccstm8/port.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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_
|
||||
|
||||
#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);
|
||||
|
||||
__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
|
||||
|
||||
#endif /* _PORT_H_ */
|
||||
|
296
arch/stm8/iccstm8/port_c.c
Normal file
296
arch/stm8/iccstm8/port_c.c
Normal file
@@ -0,0 +1,296 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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_k.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
#if 0
|
||||
NVIC_SystemReset();
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
|
||||
{
|
||||
#if 0
|
||||
(void)SysTick_Config(cycle_per_tick);
|
||||
#endif
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio)
|
||||
{
|
||||
#if 0
|
||||
NVIC_SetPriority(SysTick_IRQn, prio);
|
||||
#endif
|
||||
}
|
||||
|
||||
#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__ k_cycle_t port_systick_max_reload_cycle(void)
|
||||
{
|
||||
return SysTick_LOAD_RELOAD_Msk;
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
uint32_t max_cycle;
|
||||
|
||||
max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit
|
||||
|
||||
if (max_cycle - SysTick->VAL > cycle_per_tick - 1u) {
|
||||
SysTick->LOAD = max_cycle;
|
||||
} else {
|
||||
SysTick->LOAD = (cycle_per_tick - 1u) + SysTick->VAL;
|
||||
}
|
||||
|
||||
SysTick->VAL = 0;
|
||||
}
|
||||
|
||||
__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
|
||||
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
|
||||
|
||||
if (regs->hfsr.bits.VECTBL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_HFSR_VECTBL]);
|
||||
}
|
||||
if (regs->hfsr.bits.FORCED) {
|
||||
/* Memory Management Fault */
|
||||
if (regs->cfsr.part.mfsr.value) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_IACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_DACCVIOL]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MUNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MUNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.mfsr.bits.MSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MSTKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MLSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MLSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.mfsr.bits.MMARVALID) {
|
||||
if (regs->cfsr.part.mfsr.bits.IACCVIOL || regs->cfsr.part.mfsr.bits.DACCVIOL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_MMAR], regs->mmar);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Bus Fault */
|
||||
if (regs->cfsr.part.bfsr.value) {
|
||||
if (regs->cfsr.part.bfsr.bits.IBUSERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IBUSERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_PRECISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.IMPREISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IMPREISERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.UNSTKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_UNSTKERR]);
|
||||
}
|
||||
if (regs->cfsr.part.bfsr.bits.STKERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_STKERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.LSPERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_LSPERR]);
|
||||
}
|
||||
|
||||
if (regs->cfsr.part.bfsr.bits.BFARVALID) {
|
||||
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_BFAR], regs->bfar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Usage Fault */
|
||||
if (regs->cfsr.part.ufsr.value) {
|
||||
if (regs->cfsr.part.ufsr.bits.UNDEFINSTR) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNDEFINSTR]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVSTATE) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVSTATE]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.INVPC) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVPC]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.NOCP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_NOCP]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.UNALIGNED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNALIGNED]);
|
||||
}
|
||||
if (regs->cfsr.part.ufsr.bits.DIVBYZERO0) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_DIVBYZERO0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Debug Fault */
|
||||
if (regs->hfsr.bits.DEBUGEVT) {
|
||||
if (regs->dfsr.value) {
|
||||
if (regs->dfsr.bits.HALTED) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_HALTED]);
|
||||
}
|
||||
if (regs->dfsr.bits.BKPT) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_BKPT]);
|
||||
}
|
||||
if (regs->dfsr.bits.DWTTRAP) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_DWTTRAP]);
|
||||
}
|
||||
if (regs->dfsr.bits.VCATCH) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_VCATCH]);
|
||||
}
|
||||
if (regs->dfsr.bits.EXTERNAL) {
|
||||
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_EXTERNAL]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
port_fault_regs_t regs;
|
||||
|
||||
regs.syshndctrl.value = SCB->SHCSR;
|
||||
regs.cfsr.value = SCB->CFSR;
|
||||
regs.mmar = SCB->MMFAR;
|
||||
regs.bfar = SCB->BFAR;
|
||||
regs.hfsr.value = SCB->HFSR;
|
||||
regs.dfsr.value = SCB->DFSR;
|
||||
regs.afsr = SCB->AFSR;
|
||||
|
||||
port_fault_do_diagnosis(®s);
|
||||
}
|
||||
|
||||
/*------------------ 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 */
|
||||
|
30
arch/stm8/iccstm8/port_config.h
Normal file
30
arch/stm8/iccstm8/port_config.h
Normal 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_08
|
||||
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_08
|
||||
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
|
||||
#define TOS_CFG_CPU_HRTIMER_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
|
||||
|
||||
#define TOS_CFG_CPU_ARM_FPU_EN 0u
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
@@ -70,7 +70,7 @@ _context_save:
|
||||
LDW (X), Y
|
||||
|
||||
_context_restore:
|
||||
; k_curr_task = k_next_task
|
||||
/* k_curr_task = k_next_task */
|
||||
LDW X, k_next_task
|
||||
LDW Y, #k_curr_task /* equals to: "ldr r0, =k_curr_task "*/
|
||||
LDW (Y), X
|
Reference in New Issue
Block a user