git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6255 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
ed4c276d6e
commit
fa8b45cc5b
|
@ -64,7 +64,7 @@ CHIBIOS = ../../..
|
|||
#include $(CHIBIOS)/os/hal/ports/STM32F0xx/platform.mk
|
||||
include $(CHIBIOS)/os/nil/nil.mk
|
||||
#include $(CHIBIOS)/os/rt/osal/osal.mk
|
||||
include $(CHIBIOS)/os/rt/ports/ARMCMx/compilers/GCC/mk/port_stm32f0xx.mk
|
||||
include $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC/mk/port_stm32f0xx.mk
|
||||
#include $(CHIBIOS)/test/test.mk
|
||||
|
||||
# Define linker script file here
|
||||
|
|
|
@ -18,20 +18,19 @@
|
|||
*/
|
||||
|
||||
#include "nil.h"
|
||||
#include "hwinit.h"
|
||||
|
||||
/*
|
||||
* Thread 1.
|
||||
*/
|
||||
NIL_WORKING_AREA(waThread1, 128);
|
||||
NIL_THREAD(Thread1, arg) {
|
||||
THD_WORKING_AREA(waThread1, 128);
|
||||
THD_FUNCTION(Thread1, arg) {
|
||||
|
||||
(void)arg;
|
||||
|
||||
while (true) {
|
||||
gpioSetPad(GPIOC, GPIOC_LED4);
|
||||
// gpioSetPad(GPIOC, GPIOC_LED4);
|
||||
nilThdSleepMilliseconds(500);
|
||||
gpioClearPad(GPIOC, GPIOC_LED4);
|
||||
// gpioClearPad(GPIOC, GPIOC_LED4);
|
||||
nilThdSleepMilliseconds(500);
|
||||
}
|
||||
}
|
||||
|
@ -39,15 +38,15 @@ NIL_THREAD(Thread1, arg) {
|
|||
/*
|
||||
* Thread 2.
|
||||
*/
|
||||
NIL_WORKING_AREA(waThread2, 128);
|
||||
NIL_THREAD(Thread2, arg) {
|
||||
THD_WORKING_AREA(waThread2, 128);
|
||||
THD_FUNCTION(Thread2, arg) {
|
||||
|
||||
(void)arg;
|
||||
|
||||
while (true) {
|
||||
gpioSetPad(GPIOC, GPIOC_LED3);
|
||||
// gpioSetPad(GPIOC, GPIOC_LED3);
|
||||
nilThdSleepMilliseconds(250);
|
||||
gpioClearPad(GPIOC, GPIOC_LED3);
|
||||
// gpioClearPad(GPIOC, GPIOC_LED3);
|
||||
nilThdSleepMilliseconds(250);
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +70,7 @@ int main(void) {
|
|||
* - HW specific initialization.
|
||||
* - Nil RTOS initialization.
|
||||
*/
|
||||
hwInit();
|
||||
// hwInit();
|
||||
nilSysInit();
|
||||
|
||||
/* This is now the idle thread loop, you may perform here a low priority
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
/**
|
||||
* @brief System tick frequency.
|
||||
*/
|
||||
#define NIL_CFG_FREQUENCY 50000
|
||||
#define NIL_CFG_FREQUENCY 1000
|
||||
|
||||
/**
|
||||
* @brief Time delta constant for the tick-less mode.
|
||||
|
@ -51,7 +51,7 @@
|
|||
* The value one is not valid, timeouts are rounded up to
|
||||
* this value.
|
||||
*/
|
||||
#define NIL_CFG_TIMEDELTA 2
|
||||
#define NIL_CFG_TIMEDELTA 0
|
||||
|
||||
/**
|
||||
* @brief System assertions.
|
||||
|
|
|
@ -43,39 +43,21 @@
|
|||
*/
|
||||
#define _NIL_ /**< @brief Nil RTOS identification.*/
|
||||
|
||||
#define NIL_KERNEL_VERSION "0.0.1" /**< @brief Kernel version string. */
|
||||
#define NIL_KERNEL_VERSION "0.1.0alpha"
|
||||
|
||||
#define NIL_KERNEL_MAJOR 0 /**< @brief Version major number. */
|
||||
#define NIL_KERNEL_MINOR 0 /**< @brief Version minor number. */
|
||||
#define NIL_KERNEL_PATCH 1 /**< @brief Version patch number. */
|
||||
#define NIL_KERNEL_MAJOR 0
|
||||
#define NIL_KERNEL_MINOR 1
|
||||
#define NIL_KERNEL_PATCH 0
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Common constants
|
||||
*/
|
||||
/**
|
||||
* @brief Generic 'false' boolean constant.
|
||||
*/
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Generic 'true' boolean constant.
|
||||
*/
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE !FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Wakeup status codes
|
||||
* @name Wakeup messages
|
||||
* @{
|
||||
*/
|
||||
#define NIL_MSG_OK 0 /**< @brief Normal wakeup message. */
|
||||
#define NIL_MSG_TMO -1 /**< @brief Wake-up caused by a timeout
|
||||
#define MSG_OK 0 /**< @brief Normal wakeup message. */
|
||||
#define MSG_TIMEOUT -1 /**< @brief Wake-up caused by a timeout
|
||||
condition. */
|
||||
#define NIL_MSG_RST -2 /**< @brief Wake-up caused by a reset
|
||||
#define MSG_RESET -2 /**< @brief Wake-up caused by a reset
|
||||
condition. */
|
||||
/** @} */
|
||||
|
||||
|
@ -295,7 +277,7 @@ typedef struct {
|
|||
* @note This field is only present if some debug options have been
|
||||
* activated.
|
||||
*/
|
||||
const char *dbg_msg;
|
||||
const char *dbg_panic_msg;
|
||||
#endif
|
||||
} nil_system_t;
|
||||
|
||||
|
@ -303,6 +285,11 @@ typedef struct {
|
|||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief String quotation macro.
|
||||
*/
|
||||
#define __NIL_QUOTE(p) #p
|
||||
|
||||
/**
|
||||
* @name Threads tables definition macros
|
||||
* @{
|
||||
|
@ -325,18 +312,153 @@ typedef struct {
|
|||
#define NIL_THREADS_TABLE_END() \
|
||||
{"idle", 0, NULL, NULL, 0} \
|
||||
};
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Working Areas and Alignment
|
||||
*/
|
||||
/**
|
||||
* @brief Enforces a correct alignment for a stack area size value.
|
||||
*
|
||||
* @param[in] n the stack size to be aligned to the next stack
|
||||
* alignment boundary
|
||||
* @return The aligned stack size.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define THD_ALIGN_STACK_SIZE(n) \
|
||||
((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
|
||||
|
||||
/**
|
||||
* @brief Calculates the total Working Area size.
|
||||
*
|
||||
* @param[in] n the stack size to be assigned to the thread
|
||||
* @return The total used memory in bytes.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define THD_WORKING_AREA_SIZE(n) \
|
||||
THD_ALIGN_STACK_SIZE(sizeof(thread_t) + PORT_WA_SIZE(n))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*
|
||||
* @param[in] s the name to be assigned to the stack array
|
||||
* @param[in] n the stack size to be assigned to the thread
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define THD_WORKING_AREA(s, n) \
|
||||
stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof(stkalign_t)]
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Threads abstraction macros
|
||||
*/
|
||||
/**
|
||||
* @brief Thread declaration macro.
|
||||
* @note Thread declarations should be performed using this macro because
|
||||
* the port layer could define optimizations for thread functions.
|
||||
*/
|
||||
#define THD_FUNCTION(tname, arg) PORT_THD_FUNCTION(tname, arg)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name ISRs abstraction macros
|
||||
*/
|
||||
/**
|
||||
* @brief IRQ handler enter code.
|
||||
* @note Usually IRQ handlers functions are also declared naked.
|
||||
* @note On some architectures this macro can be empty.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define NIL_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE()
|
||||
|
||||
/**
|
||||
* @brief IRQ handler exit code.
|
||||
* @note Usually IRQ handlers function are also declared naked.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define NIL_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE()
|
||||
|
||||
/**
|
||||
* @brief Standard normal IRQ handler declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
* port implementation.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define NIL_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Fast ISRs abstraction macros
|
||||
*/
|
||||
/**
|
||||
* @brief Standard fast IRQ handler declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
* port implementation.
|
||||
* @note Not all architectures support fast interrupts.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define NIL_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Time conversion utilities
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Seconds to system ticks.
|
||||
* @details Converts from seconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] sec number of seconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define S2ST(sec) \
|
||||
((systime_t)((sec) * NIL_CFG_FREQUENCY))
|
||||
|
||||
/**
|
||||
* @brief Milliseconds to system ticks.
|
||||
* @details Converts from milliseconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] msec number of milliseconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define MS2ST(msec) \
|
||||
((systime_t)(((((uint32_t)(msec)) * ((uint32_t)NIL_CFG_FREQUENCY) - 1UL) /\
|
||||
1000UL) + 1UL))
|
||||
|
||||
/**
|
||||
* @brief Microseconds to system ticks.
|
||||
* @details Converts from microseconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] usec number of microseconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define US2ST(usec) \
|
||||
((systime_t)(((((uint32_t)(usec)) * ((uint32_t)NIL_CFG_FREQUENCY) - 1UL) /\
|
||||
1000000UL) + 1UL))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief System halt state.
|
||||
*/
|
||||
#define nilSysHalt() port_halt()
|
||||
|
||||
/**
|
||||
* @brief Enters the kernel lock mode.
|
||||
*
|
||||
|
@ -525,139 +647,33 @@ typedef struct {
|
|||
#define nilTimeIsWithin(time, start, end) \
|
||||
((end) > (start) ? ((time) >= (start)) && ((time) < (end)) : \
|
||||
((time) >= (start)) || ((time) < (end)))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Threads abstraction macros
|
||||
*/
|
||||
/**
|
||||
* @brief Thread declaration macro.
|
||||
* @note Thread declarations should be performed using this macro because
|
||||
* the port layer could define optimizations for thread functions.
|
||||
*/
|
||||
#define NIL_THREAD(tname, arg) PORT_THREAD(tname, arg)
|
||||
|
||||
#if NIL_CFG_ENABLE_ASSERTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Condition assertion.
|
||||
* @details If the condition check fails then the kernel panics with the
|
||||
* specified message and halts.
|
||||
* @details If the condition check fails then the kernel panics with a
|
||||
* message and halts.
|
||||
* @note The condition is tested only if the @p NIL_CFG_ENABLE_ASSERTS
|
||||
* switch is specified in @p nilconf.h else the macro does nothing.
|
||||
* @note The convention for the message is the following:<br>
|
||||
* @<function_name@>(), #@<assert_number@>
|
||||
* switch is specified in @p chconf.h else the macro does nothing.
|
||||
* @note The remark string is not currently used except for putting a
|
||||
* comment in the code about the assertion.
|
||||
*
|
||||
* @param[in] c the condition to be verified to be true
|
||||
* @param[in] m the text message
|
||||
* @param[in] r a remark string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#if !defined(nilDbgAssert)
|
||||
#define nilDbgAssert(c, m, r) { \
|
||||
if (!(c)) { \
|
||||
nil.dbg_msg = (m); \
|
||||
nilSysHalt(); \
|
||||
} \
|
||||
#define nilDbgAssert(c, r) { \
|
||||
if (!(c)) \
|
||||
nilSysHalt("A:"__NIL_QUOTE(__FUNCTION__)":"__NIL_QUOTE(__LINE__)); \
|
||||
}
|
||||
#endif /* !defined(chDbgAssert) */
|
||||
#endif /* !defined(nilDbgAssert) */
|
||||
#else /* !NIL_CFG_ENABLE_ASSERTS */
|
||||
#define nilDbgAssert(c, m, r) {(void)(c);}
|
||||
#define nilDbgAssert(c, r) /*{(void)(c);}*/
|
||||
#endif /* !NIL_CFG_ENABLE_ASSERTS */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name ISRs abstraction macros
|
||||
*/
|
||||
/**
|
||||
* @brief IRQ handler enter code.
|
||||
* @note Usually IRQ handlers functions are also declared naked.
|
||||
* @note On some architectures this macro can be empty.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define NIL_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE()
|
||||
|
||||
/**
|
||||
* @brief IRQ handler exit code.
|
||||
* @note Usually IRQ handlers function are also declared naked.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define NIL_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE()
|
||||
|
||||
/**
|
||||
* @brief Standard normal IRQ handler declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
* port implementation.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define NIL_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Fast ISRs abstraction macros
|
||||
*/
|
||||
/**
|
||||
* @brief Standard fast IRQ handler declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
* port implementation.
|
||||
* @note Not all architectures support fast interrupts.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define NIL_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Time conversion utilities
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Seconds to system ticks.
|
||||
* @details Converts from seconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] sec number of seconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define S2ST(sec) \
|
||||
((systime_t)((sec) * NIL_CFG_FREQUENCY))
|
||||
|
||||
/**
|
||||
* @brief Milliseconds to system ticks.
|
||||
* @details Converts from milliseconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] msec number of milliseconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define MS2ST(msec) \
|
||||
((systime_t)(((((uint32_t)(msec)) * ((uint32_t)NIL_CFG_FREQUENCY) - 1UL) /\
|
||||
1000UL) + 1UL))
|
||||
|
||||
/**
|
||||
* @brief Microseconds to system ticks.
|
||||
* @details Converts from microseconds to system ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] usec number of microseconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define US2ST(usec) \
|
||||
((systime_t)(((((uint32_t)(usec)) * ((uint32_t)NIL_CFG_FREQUENCY) - 1UL) /\
|
||||
1000000UL) + 1UL))
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
@ -671,6 +687,7 @@ extern const thread_config_t nil_thd_configs[NIL_CFG_NUM_THREADS + 1];
|
|||
extern "C" {
|
||||
#endif
|
||||
void nilSysInit(void);
|
||||
void nilSysHalt(const char *reason);
|
||||
void nilSysTimerHandlerI(void);
|
||||
thread_ref_t nilSchReadyI(thread_ref_t trp, msg_t msg);
|
||||
msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout);
|
||||
|
|
|
@ -71,6 +71,12 @@ typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
|||
*/
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
|
||||
/**
|
||||
* @brief Thread function declaration macro optimized for GCC.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) \
|
||||
__attribute__((noreturn)) void tname(void *arg)
|
||||
|
||||
#endif /* _NILTYPES_H_ */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -52,19 +52,4 @@
|
|||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Halts the system.
|
||||
* @note The function is declared as a weak symbol, it is possible
|
||||
* to redefine it in your application code.
|
||||
*/
|
||||
#if !defined(__DOXYGEN__)
|
||||
__attribute__((naked, weak))
|
||||
#endif
|
||||
void port_halt(void) {
|
||||
|
||||
port_disable();
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -112,7 +112,7 @@ void _port_irq_epilogue(regarm_t lr) {
|
|||
port_lock_from_isr();
|
||||
|
||||
/* The extctx structure is pointed by the PSP register.*/
|
||||
ctxp = (struct extctx *)__get_PSP();
|
||||
ctxp = (struct port_extctx *)__get_PSP();
|
||||
|
||||
/* Adding an artificial exception return context, there is no need to
|
||||
populate it fully.*/
|
||||
|
|
|
@ -202,13 +202,13 @@ struct context {
|
|||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(workspace, wsize, pf, arg) { \
|
||||
tp->p_ctx.r13 = (struct port_intctx *)((uint8_t *)workspace + \
|
||||
wsize - \
|
||||
sizeof(struct port_intctx)); \
|
||||
tp->p_ctx.r13->r4 = (regarm_t)(pf); \
|
||||
tp->p_ctx.r13->r5 = (regarm_t)(arg); \
|
||||
tp->p_ctx.r13->lr = (regarm_t)(_port_thread_start); \
|
||||
#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \
|
||||
(tp)->ctxp = (struct port_intctx *)((uint8_t *)workspace + \
|
||||
(size_t)wsize - \
|
||||
sizeof(struct port_intctx)); \
|
||||
(tp)->ctxp->r4 = (regarm_t)(pf); \
|
||||
(tp)->ctxp->r5 = (regarm_t)(arg); \
|
||||
(tp)->ctxp->lr = (regarm_t)(_port_thread_start); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -270,8 +270,8 @@ struct context {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if CH_CFG_TIMEDELTA > 0
|
||||
#include "chcore_timer.h"
|
||||
#if NIL_CFG_TIMEDELTA > 0
|
||||
#include "nilcore_timer.h"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -281,7 +281,6 @@ struct context {
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void port_halt(void);
|
||||
void _port_irq_epilogue(regarm_t lr);
|
||||
void _port_switch_from_isr(void);
|
||||
void _port_exit_from_isr(void);
|
||||
|
|
|
@ -80,7 +80,7 @@ void nilSysInit(void) {
|
|||
tr->timeout = 0;
|
||||
|
||||
/* Port dependent thread initialization.*/
|
||||
SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg);
|
||||
PORT_SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg);
|
||||
|
||||
/* Initialization hook.*/
|
||||
#if defined(NIL_CFG_THREAD_EXT_INIT_HOOK)
|
||||
|
@ -97,6 +97,35 @@ void nilSysInit(void) {
|
|||
nilSysEnable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Halts the system.
|
||||
* @details This function is invoked by the operating system when an
|
||||
* unrecoverable error is detected, for example because a programming
|
||||
* error in the application code that triggers an assertion while
|
||||
* in debug mode.
|
||||
* @note Can be invoked from any system state.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void nilSysHalt(const char *reason) {
|
||||
|
||||
port_disable();
|
||||
|
||||
#if NIL_DBG_ENABLED
|
||||
nil.dbg_panic_msg = reason;
|
||||
#else
|
||||
(void)reason;
|
||||
#endif
|
||||
|
||||
#if defined(NIL_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
|
||||
NIL_CFG_SYSTEM_HALT_HOOK(reason);
|
||||
#endif
|
||||
|
||||
/* Harmless infinite loop.*/
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Time management handler.
|
||||
* @note This handler has to be invoked by a periodic ISR in order to
|
||||
|
@ -113,8 +142,7 @@ void nilSysTimerHandlerI(void) {
|
|||
/* Is the thread in a wait state with timeout?.*/
|
||||
if (tr->timeout > 0) {
|
||||
|
||||
nilDbgAssert(!NIL_THD_IS_READY(tr),
|
||||
"nilSysTimerHandlerI(), #1", "is ready");
|
||||
nilDbgAssert(!NIL_THD_IS_READY(tr), "is ready");
|
||||
|
||||
/* Did the timer reach zero?*/
|
||||
if (--tr->timeout == 0) {
|
||||
|
@ -124,7 +152,7 @@ void nilSysTimerHandlerI(void) {
|
|||
tr->u1.semp->cnt++;
|
||||
else if (NIL_THD_IS_SUSP(tr))
|
||||
tr->u1.trp = NULL;
|
||||
nilSchReadyI(tr, NIL_MSG_TMO);
|
||||
nilSchReadyI(tr, MSG_TIMEOUT);
|
||||
}
|
||||
}
|
||||
/* Lock released in order to give a preemption chance on those
|
||||
|
@ -194,11 +222,9 @@ thread_ref_t nilSchReadyI(thread_ref_t tr, msg_t msg) {
|
|||
|
||||
nilDbgAssert((tr >= nil.threads) &&
|
||||
(tr < &nil.threads[NIL_CFG_NUM_THREADS]),
|
||||
"nilSchReadyI(), #1", "pointer out of range");
|
||||
nilDbgAssert(!NIL_THD_IS_READY(tr),
|
||||
"nilSchReadyI(), #2", "already ready");
|
||||
nilDbgAssert(nil.next <= nil.current,
|
||||
"nilSchReadyI(), #3", "priority ordering");
|
||||
"pointer out of range");
|
||||
nilDbgAssert(!NIL_THD_IS_READY(tr), "already ready");
|
||||
nilDbgAssert(nil.next <= nil.current, "priority ordering");
|
||||
|
||||
tr->u1.msg = msg;
|
||||
tr->state = NIL_THD_READY;
|
||||
|
@ -249,7 +275,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
|
|||
thread_ref_t ntr, otr = nil.current;
|
||||
|
||||
nilDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS],
|
||||
"nilSchGoSleepTimeoutS(), #1", "idle cannot sleep");
|
||||
"idle cannot sleep");
|
||||
|
||||
/* Storing the wait object for the current thread.*/
|
||||
otr->state = newstate;
|
||||
|
@ -304,7 +330,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
|
|||
/* Points to the next thread in lowering priority order.*/
|
||||
ntr++;
|
||||
nilDbgAssert(ntr <= &nil.threads[NIL_CFG_NUM_THREADS],
|
||||
"nilSchGoSleepTimeoutS(), #2", "pointer out of range");
|
||||
"pointer out of range");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +350,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
|
|||
*/
|
||||
msg_t nilThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) {
|
||||
|
||||
nilDbgAssert(*trp == NULL, "nilThdSuspendTimeoutS(), #1", "not NULL");
|
||||
nilDbgAssert(*trp == NULL, "not NULL");
|
||||
|
||||
*trp = nil.current;
|
||||
nil.current->u1.trp = trp;
|
||||
|
@ -346,7 +372,7 @@ void nilThdResumeI(thread_ref_t *trp, msg_t msg) {
|
|||
if (*trp != NULL) {
|
||||
thread_ref_t tr = *trp;
|
||||
|
||||
nilDbgAssert(NIL_THD_IS_SUSP(tr), "nilThdResumeI(), #1", "not suspended");
|
||||
nilDbgAssert(NIL_THD_IS_SUSP(tr), "not suspended");
|
||||
|
||||
*trp = NULL;
|
||||
nilSchReadyI(tr, msg);
|
||||
|
@ -476,13 +502,13 @@ msg_t nilSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) {
|
|||
cnt_t cnt = sp->cnt;
|
||||
if (cnt <= 0) {
|
||||
if (TIME_IMMEDIATE == timeout)
|
||||
return NIL_MSG_TMO;
|
||||
return MSG_TIMEOUT;
|
||||
sp->cnt = cnt - 1;
|
||||
nil.current->u1.semp = sp;
|
||||
return nilSchGoSleepTimeoutS(NIL_THD_WTSEM, timeout);
|
||||
}
|
||||
sp->cnt = cnt - 1;
|
||||
return NIL_MSG_OK;
|
||||
return MSG_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -523,10 +549,9 @@ void nilSemSignalI(semaphore_t *sp) {
|
|||
/* Is this thread waiting on this semaphore?*/
|
||||
if (tr->u1.semp == sp) {
|
||||
|
||||
nilDbgAssert(NIL_THD_IS_WTSEM(tr),
|
||||
"nilSemSignalI(), #1", "not waiting");
|
||||
nilDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting");
|
||||
|
||||
nilSchReadyI(tr, NIL_MSG_OK);
|
||||
nilSchReadyI(tr, MSG_OK);
|
||||
return;
|
||||
}
|
||||
tr++;
|
||||
|
@ -585,11 +610,10 @@ void nilSemResetI(semaphore_t *sp, cnt_t n) {
|
|||
/* Is this thread waiting on this semaphore?*/
|
||||
if (tr->u1.semp == sp) {
|
||||
|
||||
nilDbgAssert(NIL_THD_IS_WTSEM(tr),
|
||||
"nilSemResetI(), #1", "not waiting");
|
||||
nilDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting");
|
||||
|
||||
cnt++;
|
||||
nilSchReadyI(tr, NIL_MSG_RST);
|
||||
nilSchReadyI(tr, MSG_RESET);
|
||||
}
|
||||
tr++;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ void _port_irq_epilogue(regarm_t lr) {
|
|||
port_lock_from_isr();
|
||||
|
||||
/* The extctx structure is pointed by the PSP register.*/
|
||||
ctxp = (struct extctx *)__get_PSP();
|
||||
ctxp = (struct port_extctx *)__get_PSP();
|
||||
|
||||
/* Adding an artificial exception return context, there is no need to
|
||||
populate it fully.*/
|
||||
|
|
|
@ -202,13 +202,13 @@ struct context {
|
|||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(workspace, wsize, pf, arg) { \
|
||||
tp->p_ctx.r13 = (struct port_intctx *)((uint8_t *)workspace + \
|
||||
#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \
|
||||
(tp)->p_ctx.r13 = (struct port_intctx *)((uint8_t *)workspace + \
|
||||
wsize - \
|
||||
sizeof(struct port_intctx)); \
|
||||
tp->p_ctx.r13->r4 = (regarm_t)(pf); \
|
||||
tp->p_ctx.r13->r5 = (regarm_t)(arg); \
|
||||
tp->p_ctx.r13->lr = (regarm_t)(_port_thread_start); \
|
||||
(tp)->p_ctx.r13->r4 = (regarm_t)(pf); \
|
||||
(tp)->p_ctx.r13->r5 = (regarm_t)(arg); \
|
||||
(tp)->p_ctx.r13->lr = (regarm_t)(_port_thread_start); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -281,7 +281,6 @@ struct context {
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void port_halt(void);
|
||||
void _port_irq_epilogue(regarm_t lr);
|
||||
void _port_switch_from_isr(void);
|
||||
void _port_exit_from_isr(void);
|
||||
|
|
|
@ -301,13 +301,13 @@ struct context {
|
|||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(workspace, wsize, pf, arg) { \
|
||||
tp->p_ctx.r13 = (struct port_intctx *)((uint8_t *)workspace + \
|
||||
#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \
|
||||
(tp)->p_ctx.r13 = (struct port_intctx *)((uint8_t *)workspace + \
|
||||
wsize - \
|
||||
sizeof(struct port_intctx)); \
|
||||
tp->p_ctx.r13->r4 = (regarm_t)(pf); \
|
||||
tp->p_ctx.r13->r5 = (regarm_t)(arg); \
|
||||
tp->p_ctx.r13->lr = (regarm_t)(_port_thread_start); \
|
||||
(tp)->p_ctx.r13->r4 = (regarm_t)(pf); \
|
||||
(tp)->p_ctx.r13->r5 = (regarm_t)(arg); \
|
||||
(tp)->p_ctx.r13->lr = (regarm_t)(_port_thread_start); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -184,7 +184,7 @@ thread_t *chThdCreateI(void *wsp, size_t size,
|
|||
chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) &&
|
||||
(prio <= HIGHPRIO) && (pf != NULL));
|
||||
|
||||
PORT_SETUP_CONTEXT(wsp, size, pf, arg);
|
||||
PORT_SETUP_CONTEXT(tp, wsp, size, pf, arg);
|
||||
return _thread_init(tp, prio);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue