📄 hal_arch.h
字号:
CYG_MACRO_END
#endif // HAL_THREAD_INIT_CONTEXT
// ----------------------------------------------------------------------------
// Bit manipulation routines.
externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
#define HAL_LSBIT_INDEX(index, mask) (index) = hal_lsbit_index(mask);
#define HAL_MSBIT_INDEX(index, mask) (index) = hal_msbit_index(mask);
// ----------------------------------------------------------------------------
// Idle thread code.
// This macro is called in the idle thread loop, and gives the HAL the
// chance to insert code. Typical idle thread behaviour might be to halt the
// processor.
externC void hal_idle_thread_action(cyg_uint32 loop_count);
#define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_)
// ----------------------------------------------------------------------------
// Execution reorder barrier.
// When optimizing the compiler can reorder code. In multithreaded systems
// where the order of actions is vital, this can sometimes cause problems.
// This macro may be inserted into places where reordering should not happen.
#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
// ----------------------------------------------------------------------------
// Breakpoint support
// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen
// if executed.
// HAL_BREAKINST is the value of the breakpoint instruction and
// HAL_BREAKINST_SIZE is its size in bytes.
// The host side of GDB debugger uses trap #15 to install breakpoints.
#define CYGNUM_HAL_VECTOR_DEBUGTRAP 47
#define HAL_BREAKPOINT(_label_) \
asm volatile (" .globl " #_label_ ";" \
#_label_":" \
" trap #15" \
);
#define HAL_BREAKINST 0x4E4F
#define HAL_BREAKINST_SIZE 2
// ----------------------------------------------------------------------------
// Thread register state manipulation for GDB support.
typedef struct {
cyg_uint32 d[8];
cyg_uint32 a[8];
cyg_uint32 pc;
cyg_uint32 sr;
} GDB_Registers;
// Translate a stack pointer as saved by the thread context macros above into
// a pointer to a HAL_SavedRegisters structure.
#define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \
(_regs_) = (HAL_SavedRegisters *)(_sp_)
// Copy a set of registers from a HAL_SavedRegisters structure into a
// GDB ordered array.
#define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ ) \
CYG_MACRO_START \
union __gdbreguniontype { \
__typeof__(_aregval_) _aregval2_; \
GDB_Registers *_gdbr; \
} __gdbregunion; \
__gdbregunion._aregval2_ = (_aregval_); \
GDB_Registers *_gdb_ = __gdbregunion._gdbr; \
int _i_; \
\
for( _i_ = 0; _i_ < 8; _i_++ ) \
{ \
_gdb_->d[_i_] = (_regs_)->d[_i_]; \
_gdb_->a[_i_] = (_regs_)->a[_i_]; \
} \
\
_gdb_->pc = (_regs_)->pc; \
_gdb_->sr = (cyg_uint32) ((_regs_)->sr); \
CYG_MACRO_END
// Copy a GDB ordered array into a HAL_SavedRegisters structure.
#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \
CYG_MACRO_START \
union __gdbreguniontype { \
__typeof__(_aregval_) _aregval2_; \
GDB_Registers *_gdbr; \
} __gdbregunion; \
__gdbregunion._aregval2_ = (_aregval_); \
GDB_Registers *_gdb_ = __gdbregunion._gdbr; \
int _i_; \
\
for( _i_ = 0; _i_ < 8; _i_++ ) \
{ \
(_regs_)->d[_i_] = _gdb_->d[_i_]; \
(_regs_)->a[_i_] = _gdb_->a[_i_]; \
} \
\
(_regs_)->pc = _gdb_->pc; \
(_regs_)->sr = (CYG_WORD16)(_gdb_->sr); \
CYG_MACRO_END
#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
defined(CYGPKG_HAL_EXCEPTIONS)
// ----------------------------------------------------------------------------
// Exception handling function.
// This function is defined by the kernel according to this prototype. It is
// invoked from the HAL to deal with any CPU exceptions that the HAL does
// not want to deal with itself. It usually invokes the kernel's exception
// delivery mechanism.
externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
#endif // defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)
// ----------------------------------------------------------------------------
// Minimal and sensible stack sizes: the intention is that applications
// will use these to provide a stack size in the first instance prior to
// proper analysis. Idle thread stack should be this big.
// THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES.
// THEY ARE HOWEVER ENOUGH TO START PROGRAMMING.
// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES!
// This is not a config option because it should not be adjusted except
// under "enough rope" sort of disclaimers.
// Stack frame overhead per call: 6 data registers, 5 address registers,
// frame pointer, and return address. We can't guess the local variables so
// just assume that using all of the registers averages out.
#define CYGNUM_HAL_STACK_FRAME_SIZE ((6 + 5 + 1 + 1) * 4)
// Stack needed for a context switch.
// All registers + pc + sr + vector.
#ifndef CYGNUM_HAL_STACK_CONTEXT_SIZE
#define CYGNUM_HAL_STACK_CONTEXT_SIZE ((8+8+1)*4 + (1+1)*2)
#endif // CYGNUM_HAL_STACK_CONTEXT_SIZE
// Interrupt (rounded up) + call to ISR, interrupt_end() and the DSR.
#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
((CYGNUM_HAL_STACK_CONTEXT_SIZE) + (2*CYGNUM_HAL_STACK_FRAME_SIZE))
// We define a minimum stack size as the minimum any thread could ever
// legitimately get away with. We can throw asserts if users ask for less
// than this. Allow enough for four interrupt sources - clock, serial,
// nic, and one other.
// No separate interrupt stack exists. Make sure all threads contain
// a stack sufficiently large.
#define CYGNUM_HAL_STACK_SIZE_MINIMUM \
((4*CYGNUM_HAL_STACK_INTERRUPT_SIZE) \
+ (16*CYGNUM_HAL_STACK_FRAME_SIZE))
// Now make a reasonable choice for a typical thread size. Pluck figures
// from thin air and say 30 call frames with an average of 16 words of
// automatic variables per call frame.
#define CYGNUM_HAL_STACK_SIZE_TYPICAL \
(CYGNUM_HAL_STACK_SIZE_MINIMUM + \
(30 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4))))
// -------------------------------------------------------------------------
// Macros for switching context between two eCos instances (jump from
// code in ROM to code in RAM or vice versa).
#define CYGARC_HAL_SAVE_GP()
#define CYGARC_HAL_RESTORE_GP()
// -------------------------------------------------------------------------
// hal_setjmp/hal_longjmp
// We must save all of the registers that are preserved across routine
// calls. The assembly code assumes that this structure is defined in the
// following format. Any changes to this structure will result in changes to
// the assembly code!!
typedef struct {
// D registers
cyg_uint32 d2;
cyg_uint32 d3;
cyg_uint32 d4;
cyg_uint32 d5;
cyg_uint32 d6;
cyg_uint32 d7;
// A registers
cyg_uint32 a2;
cyg_uint32 a3;
cyg_uint32 a4;
cyg_uint32 a5;
cyg_uint32 a6;
#ifdef CYGHWR_HAL_COLDFIRE_MAC
// MAC registers
cyg_uint32 macc;
cyg_uint32 macsr;
cyg_uint32 mask;
#endif
// SP and PC
cyg_uint32 sp;
cyg_uint32 pc;
} hal_jmp_buf_t;
// This type is used by normal routines to pass the address of the structure
// into our routines without having to explicitly take the address
// of the structure.
typedef cyg_uint32 hal_jmp_buf[sizeof(hal_jmp_buf_t) / sizeof(cyg_uint32)];
// Define the generic setjmp and longjmp routines
externC int hal_setjmp(hal_jmp_buf env);
externC void hal_longjmp(hal_jmp_buf env, int val);
#define hal_setjmp(_env) hal_setjmp(_env)
#define hal_longjmp(_env, _val) hal_longjmp(_env, _val)
// ---------------------------------------------------------------------------
// End of hal_arch.h
#endif // CYGONCE_HAL_ARCH_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -