diff --git a/include/arch.h b/include/arch.h index 26cc060..fd0dc60 100644 --- a/include/arch.h +++ b/include/arch.h @@ -18,7 +18,7 @@ typedef enum IRQn { /****** Cortex-Mx Processor Exceptions Numbers ***************************************************/ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ - HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ + HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ MemoryManagement_IRQn = -12, /*!< 4 Cortex-Mx Memory Management Interrupt */ BusFault_IRQn = -11, /*!< 5 Cortex-Mx Bus Fault Interrupt */ UsageFault_IRQn = -10, /*!< 6 Cortex-Mx Usage Fault Interrupt */ diff --git a/include/port.h b/include/port.h index 04e2f48..84ae5a6 100644 --- a/include/port.h +++ b/include/port.h @@ -122,10 +122,55 @@ typedef struct { * Define the common svc call function interface. */ #if defined(__CC_ARM) + +/** + * @brief Trigger system svc call. + */ __svc(SVC_KERNAL_INVOKE_NUMBER) u32_t _impl_kernal_svc_call(u32_t args_0, u32_t args_1, u32_t args_2, u32_t args_3); + +/** + * @brief Schedule the first thread. + */ __asm void _impl_port_run_theFirstThread(u32_t sp); +#if 0 /* Disable it to use CMSIS Library */ +/** + * @brief To check if it's in interrupt content. + */ +static inline b_t _impl_port_isInInterruptContent(void) +{ + register u32_t reg_ipsr __asm("ipsr"); + if (reg_ipsr) { + return TRUE; + } + + register u32_t reg_primask __asm("primask"); + if (reg_primask == 0x01u) { + return TRUE; + } + + return FALSE; +} + +/** + * @brief To check if it's in kernal thread content. + */ +static inline b_t _impl_port_isInThreadMode(void) +{ + register u32_t reg_ipsr __asm("ipsr"); + if (reg_ipsr) { + return FALSE; + } + + return TRUE; +} +#endif + #elif (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + +/** + * @brief Trigger system svc call. + */ static inline u32_t _impl_kernal_svc_call(u32_t args_0, u32_t args_1, u32_t args_2, u32_t args_3) { register u32_t r0 __asm__("r0") = args_0; @@ -137,13 +182,97 @@ static inline u32_t _impl_kernal_svc_call(u32_t args_0, u32_t args_1, u32_t args return r0; } + +/** + * @brief Schedule the first thread. + */ void _impl_port_run_theFirstThread(u32_t sp); +#if 0 /* Disable it to use CMSIS Library */ +/** + * @brief To check if it's in interrupt content. + */ +static inline b_t _impl_port_isInInterruptContent(void) +{ + u32_t ipsr; + + __asm__ volatile("mrs %0, IPSR\n\t" : "=r"(ipsr)); + if (ipsr) { + return TRUE; + } + + u32_t primask; + + __ASM volatile("MRS %0, primask" : "=r"(primask)); + if (primask) { + return TRUE; + } + + return FALSE; +} + +/** + * @brief To check if it's in kernal thread content. + */ +static inline b_t _impl_port_isInThreadMode(void) +{ + u32_t ipsr; + + __asm__ volatile("mrs %0, IPSR\n\t" : "=r"(ipsr)); + if (reg_ipsr) { + return FALSE; + } + + return TRUE; +} +#endif + #elif defined(__ICCARM__) #pragma swi_number = SVC_KERNAL_INVOKE_NUMBER + +/** + * @brief Trigger system svc call. + */ __swi u32_t _impl_kernal_svc_call(u32_t args_0, u32_t args_1, u32_t args_2, u32_t args_3); + +/** + * @brief Schedule the first thread. + */ void _impl_port_run_theFirstThread(u32_t sp); +#if 0 /* Disable it to use CMSIS Library */ +/** + * @brief To check if it's in interrupt content. + */ +static inline b_t _impl_port_isInInterruptContent(void) +{ + register u32_t reg_ipsr = __arm_rsr("IPSR"); + if (reg_ipsr) { + return TRUE; + } + + register u32_t reg_primask = __arm_rsr("PRIMASK"); + if (reg_primask == 0x01u) { + return TRUE; + } + + return FALSE; +} + +/** + * @brief To check if it's in kernal thread content. + */ +static inline b_t _impl_port_isInThreadMode(void) +{ + register u32_t reg_ipsr = __arm_rsr("IPSR"); + if (reg_ipsr) { + return FALSE; + } + + return TRUE; +} +#endif + #elif defined(__GUNC__) /* TODO */ @@ -164,9 +293,9 @@ void _impl_port_run_theFirstThread(u32_t sp); /** * The implement function lists for rtos kernal internal use. */ -void _impl_port_setPendSV(void); b_t _impl_port_isInInterruptContent(void); b_t _impl_port_isInThreadMode(void); +void _impl_port_setPendSV(void); void _impl_port_interrupt_init(void); u32_t _impl_port_stack_frame_init(void (*pEntryFunction)(void), u32_t *pAddress, u32_t size);