Nil working on M3/M4.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6265 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
986a9d1db1
commit
15a54ae359
|
@ -79,9 +79,9 @@ THD_FUNCTION(Thread3, arg) {
|
||||||
* match NIL_CFG_NUM_THREADS.
|
* match NIL_CFG_NUM_THREADS.
|
||||||
*/
|
*/
|
||||||
THD_TABLE_BEGIN
|
THD_TABLE_BEGIN
|
||||||
THD_TABLE_ENTRY("blinker1", Thread1, NULL, waThread1, sizeof(waThread1))
|
THD_TABLE_ENTRY(waThread1, "blinker1", Thread1, NULL)
|
||||||
THD_TABLE_ENTRY("blinker2", Thread2, NULL, waThread2, sizeof(waThread2))
|
THD_TABLE_ENTRY(waThread2, "blinker2", Thread2, NULL)
|
||||||
THD_TABLE_ENTRY("hello", Thread3, NULL, waThread3, sizeof(waThread3))
|
THD_TABLE_ENTRY(waThread3, "hello", Thread3, NULL)
|
||||||
THD_TABLE_END
|
THD_TABLE_END
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -59,15 +59,18 @@
|
||||||
*
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(NIL_CFG_USE_EVENTS) || defined(__DOXYGEN__)
|
|
||||||
#define NIL_CFG_USE_EVENTS TRUE
|
#define NIL_CFG_USE_EVENTS TRUE
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief System assertions.
|
* @brief System assertions.
|
||||||
*/
|
*/
|
||||||
#define NIL_CFG_ENABLE_ASSERTS FALSE
|
#define NIL_CFG_ENABLE_ASSERTS FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stack check.
|
||||||
|
*/
|
||||||
|
#define NIL_CFG_ENABLE_STACK_CHECK FALSE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Threads descriptor structure extension.
|
* @brief Threads descriptor structure extension.
|
||||||
* @details User fields added to the end of the @p thread_t structure.
|
* @details User fields added to the end of the @p thread_t structure.
|
||||||
|
|
|
@ -65,8 +65,8 @@ THD_FUNCTION(Thread3, arg) {
|
||||||
* PA9 and PA10 are routed to USART1.
|
* PA9 and PA10 are routed to USART1.
|
||||||
*/
|
*/
|
||||||
sdStart(&SD1, NULL);
|
sdStart(&SD1, NULL);
|
||||||
palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(1)); /* USART1 TX. */
|
palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(7)); /* USART1 TX. */
|
||||||
palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(1)); /* USART1 RX. */
|
palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(7)); /* USART1 RX. */
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
chnWrite(&SD1, (const uint8_t *)"Hello World!\r\n", 14);
|
chnWrite(&SD1, (const uint8_t *)"Hello World!\r\n", 14);
|
||||||
|
@ -79,9 +79,9 @@ THD_FUNCTION(Thread3, arg) {
|
||||||
* match NIL_CFG_NUM_THREADS.
|
* match NIL_CFG_NUM_THREADS.
|
||||||
*/
|
*/
|
||||||
THD_TABLE_BEGIN
|
THD_TABLE_BEGIN
|
||||||
THD_TABLE_ENTRY("blinker1", Thread1, NULL, waThread1, sizeof(waThread1))
|
THD_TABLE_ENTRY(waThread1, "blinker1", Thread1, NULL)
|
||||||
THD_TABLE_ENTRY("blinker2", Thread2, NULL, waThread2, sizeof(waThread2))
|
THD_TABLE_ENTRY(waThread2, "blinker2", Thread2, NULL)
|
||||||
THD_TABLE_ENTRY("hello", Thread3, NULL, waThread3, sizeof(waThread3))
|
THD_TABLE_ENTRY(waThread3, "hello", Thread3, NULL)
|
||||||
THD_TABLE_END
|
THD_TABLE_END
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -59,15 +59,18 @@
|
||||||
*
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(NIL_CFG_USE_EVENTS) || defined(__DOXYGEN__)
|
|
||||||
#define NIL_CFG_USE_EVENTS TRUE
|
#define NIL_CFG_USE_EVENTS TRUE
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief System assertions.
|
* @brief System assertions.
|
||||||
*/
|
*/
|
||||||
#define NIL_CFG_ENABLE_ASSERTS FALSE
|
#define NIL_CFG_ENABLE_ASSERTS FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stack check.
|
||||||
|
*/
|
||||||
|
#define NIL_CFG_ENABLE_STACK_CHECK FALSE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Threads descriptor structure extension.
|
* @brief Threads descriptor structure extension.
|
||||||
* @details User fields added to the end of the @p thread_t structure.
|
* @details User fields added to the end of the @p thread_t structure.
|
||||||
|
|
|
@ -30,8 +30,11 @@
|
||||||
#ifndef _NIL_H_
|
#ifndef _NIL_H_
|
||||||
#define _NIL_H_
|
#define _NIL_H_
|
||||||
|
|
||||||
|
typedef struct nil_thread thread_t;
|
||||||
|
|
||||||
#include "nilconf.h"
|
#include "nilconf.h"
|
||||||
#include "niltypes.h"
|
#include "niltypes.h"
|
||||||
|
#include "nilcore.h"
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module constants. */
|
/* Module constants. */
|
||||||
|
@ -197,9 +200,21 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if NIL_CFG_ENABLE_ASSERTS
|
#if NIL_CFG_ENABLE_ASSERTS
|
||||||
#define CH_DBG_ENABLED TRUE
|
#define NIL_DBG_ENABLED TRUE
|
||||||
#else
|
#else
|
||||||
#define CH_DBG_ENABLED FALSE
|
#define NIL_DBG_ENABLED FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Boundaries of the idle thread boundaries, only required if stack checking
|
||||||
|
is enabled.*/
|
||||||
|
#if NIL_CFG_ENABLE_STACK_CHECK
|
||||||
|
extern stkalign_t __main_thread_stack_base__, __main_thread_stack_end__;
|
||||||
|
|
||||||
|
#define THD_IDLE_BASE (&__main_thread_stack_base__)
|
||||||
|
#define THD_IDLE_END (&__main_thread_stack_end__)
|
||||||
|
#else
|
||||||
|
#define THD_IDLE_BASE NULL
|
||||||
|
#define THD_IDLE_END NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -237,11 +252,11 @@ typedef struct nil_thread thread_t;
|
||||||
* @brief Structure representing a thread static configuration.
|
* @brief Structure representing a thread static configuration.
|
||||||
*/
|
*/
|
||||||
struct nil_thread_cfg {
|
struct nil_thread_cfg {
|
||||||
|
stkalign_t *wbase; /**< @brief Thread working area base. */
|
||||||
|
stkalign_t *wend; /**< @brief Thread working area end. */
|
||||||
const char *namep; /**< @brief Thread name, for debugging. */
|
const char *namep; /**< @brief Thread name, for debugging. */
|
||||||
tfunc_t funcp; /**< @brief Thread function. */
|
tfunc_t funcp; /**< @brief Thread function. */
|
||||||
void *arg; /**< @brief Thread function argument. */
|
void *arg; /**< @brief Thread function argument. */
|
||||||
void *wap; /**< @brief Thread working area base. */
|
|
||||||
size_t size; /**< @brief Thread working area size. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -270,6 +285,9 @@ struct nil_thread {
|
||||||
if disabled. */
|
if disabled. */
|
||||||
#if NIL_CFG_USE_EVENTS
|
#if NIL_CFG_USE_EVENTS
|
||||||
eventmask_t epmask; /**< @brief Pending events mask. */
|
eventmask_t epmask; /**< @brief Pending events mask. */
|
||||||
|
#endif
|
||||||
|
#if NIL_CFG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
|
||||||
|
stkalign_t *stklim;/**< @brief Thread stack boundary. */
|
||||||
#endif
|
#endif
|
||||||
/* Optional extra fields.*/
|
/* Optional extra fields.*/
|
||||||
NIL_CFG_THREAD_EXT_FIELDS
|
NIL_CFG_THREAD_EXT_FIELDS
|
||||||
|
@ -311,7 +329,7 @@ typedef struct {
|
||||||
* @brief Thread structures for all the defined threads.
|
* @brief Thread structures for all the defined threads.
|
||||||
*/
|
*/
|
||||||
thread_t threads[NIL_CFG_NUM_THREADS + 1];
|
thread_t threads[NIL_CFG_NUM_THREADS + 1];
|
||||||
#if CH_DBG_ENABLED || defined(__DOXYGEN__)
|
#if NIL_DBG_ENABLED || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Panic message.
|
* @brief Panic message.
|
||||||
* @note This field is only present if some debug options have been
|
* @note This field is only present if some debug options have been
|
||||||
|
@ -343,14 +361,14 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Entry of user threads table
|
* @brief Entry of user threads table
|
||||||
*/
|
*/
|
||||||
#define THD_TABLE_ENTRY(name, funcp, arg, wap, size) \
|
#define THD_TABLE_ENTRY(wap, name, funcp, arg) \
|
||||||
{name, funcp, arg, wap, size},
|
{wap, (wap) + sizeof (wap), name, funcp, arg},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief End of user threads table.
|
* @brief End of user threads table.
|
||||||
*/
|
*/
|
||||||
#define THD_TABLE_END \
|
#define THD_TABLE_END \
|
||||||
{"idle", 0, NULL, NULL, 0} \
|
{THD_IDLE_BASE, THD_IDLE_END, "idle", 0, NULL} \
|
||||||
};
|
};
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
@ -754,10 +772,6 @@ extern "C" {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Late inclusion, this is done in order to let the port layer access
|
|
||||||
the OS services like assertions.*/
|
|
||||||
#include "nilcore.h"
|
|
||||||
|
|
||||||
#endif /* _NIL_H_ */
|
#endif /* _NIL_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -246,7 +246,7 @@ typedef struct {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
#define osalDbgCheck(c) /*chDbgCheck(c)*/
|
#define osalDbgCheck(c) chDbgAssert(c, "parameter check")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I-Class state check.
|
* @brief I-Class state check.
|
||||||
|
|
|
@ -192,9 +192,8 @@ struct port_intctx {
|
||||||
* @details This code usually setup the context switching frame represented
|
* @details This code usually setup the context switching frame represented
|
||||||
* by an @p port_intctx structure.
|
* by an @p port_intctx structure.
|
||||||
*/
|
*/
|
||||||
#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \
|
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \
|
||||||
(tp)->ctxp = (struct port_intctx *)((uint8_t *)workspace + \
|
(tp)->ctxp = (struct port_intctx *)(((uint8_t *)(wend)) - \
|
||||||
(size_t)wsize - \
|
|
||||||
sizeof(struct port_intctx)); \
|
sizeof(struct port_intctx)); \
|
||||||
(tp)->ctxp->r4 = (regarm_t)(pf); \
|
(tp)->ctxp->r4 = (regarm_t)(pf); \
|
||||||
(tp)->ctxp->r5 = (regarm_t)(arg); \
|
(tp)->ctxp->r5 = (regarm_t)(arg); \
|
||||||
|
@ -254,7 +253,7 @@ struct port_intctx {
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
||||||
if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
|
if ((stkalign_t *)(r13 - 1) < (otp)->stklim) \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,9 +291,8 @@ struct port_intctx {
|
||||||
* @details This code usually setup the context switching frame represented
|
* @details This code usually setup the context switching frame represented
|
||||||
* by an @p port_intctx structure.
|
* by an @p port_intctx structure.
|
||||||
*/
|
*/
|
||||||
#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \
|
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \
|
||||||
(tp)->ctxp = (struct port_intctx *)((uint8_t *)workspace + \
|
(tp)->ctxp = (struct port_intctx *)(((uint8_t *)(wend)) - \
|
||||||
(size_t)wsize - \
|
|
||||||
sizeof(struct port_intctx)); \
|
sizeof(struct port_intctx)); \
|
||||||
(tp)->ctxp->r4 = (regarm_t)(pf); \
|
(tp)->ctxp->r4 = (regarm_t)(pf); \
|
||||||
(tp)->ctxp->r5 = (regarm_t)(arg); \
|
(tp)->ctxp->r5 = (regarm_t)(arg); \
|
||||||
|
@ -351,7 +350,7 @@ struct port_intctx {
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
||||||
if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
|
if ((stkalign_t *)(r13 - 1) < (otp)->stklim) \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,9 @@ nil_system_t nil;
|
||||||
* @details Initializes the kernel structures, the current instructions flow
|
* @details Initializes the kernel structures, the current instructions flow
|
||||||
* becomes the idle thread upon return. The idle thread must not
|
* becomes the idle thread upon return. The idle thread must not
|
||||||
* invoke any kernel primitive able to change state to not runnable.
|
* invoke any kernel primitive able to change state to not runnable.
|
||||||
|
* @note This function assumes that the @p nil global variable has been
|
||||||
|
* zeroed by the runtime environment. If this is not the case then
|
||||||
|
* make sure to clear it before calling this function.
|
||||||
*
|
*
|
||||||
* @special
|
* @special
|
||||||
*/
|
*/
|
||||||
|
@ -73,28 +76,34 @@ void chSysInit(void) {
|
||||||
port_init();
|
port_init();
|
||||||
|
|
||||||
/* Iterates through the list of defined threads.*/
|
/* Iterates through the list of defined threads.*/
|
||||||
for (tp = &nil.threads[0], tcp = nil_thd_configs;
|
tp = &nil.threads[0];
|
||||||
tp < &nil.threads[NIL_CFG_NUM_THREADS];
|
tcp = nil_thd_configs;
|
||||||
tp++, tcp++) {
|
while (tp < &nil.threads[NIL_CFG_NUM_THREADS]) {
|
||||||
tp->state = NIL_STATE_READY;
|
#if NIL_CFG_ENABLE_STACK_CHECK
|
||||||
tp->timeout = 0;
|
tp->stklim = (stkalign_t *)tcp->wbase;
|
||||||
#if NIL_CFG_USE_EVENTS
|
|
||||||
tp->epmask = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Port dependent thread initialization.*/
|
/* Port dependent thread initialization.*/
|
||||||
PORT_SETUP_CONTEXT(tp, tcp->wap, tcp->size, tcp->funcp, tcp->arg);
|
PORT_SETUP_CONTEXT(tp, tcp->wend, tcp->funcp, tcp->arg);
|
||||||
|
|
||||||
/* Initialization hook.*/
|
/* Initialization hook.*/
|
||||||
#if defined(NIL_CFG_THREAD_EXT_INIT_HOOK)
|
#if defined(NIL_CFG_THREAD_EXT_INIT_HOOK)
|
||||||
NIL_CFG_THREAD_EXT_INIT_HOOK(tp);
|
NIL_CFG_THREAD_EXT_INIT_HOOK(tp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
tp++, tcp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NIL_CFG_ENABLE_STACK_CHECK
|
||||||
|
/* The idle thread is a special case because its stack is set up by the
|
||||||
|
runtime environment.*/
|
||||||
|
tp->stklim = THD_IDLE_BASE;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Runs the highest priority thread, the current one becomes the null
|
/* Runs the highest priority thread, the current one becomes the null
|
||||||
thread.*/
|
thread.*/
|
||||||
nil.current = nil.next = nil.threads;
|
nil.current = nil.next = nil.threads;
|
||||||
port_switch(nil.threads, &nil.threads[NIL_CFG_NUM_THREADS]);
|
port_switch(nil.current, tp);
|
||||||
|
|
||||||
/* Interrupts enabled for the idle thread.*/
|
/* Interrupts enabled for the idle thread.*/
|
||||||
chSysEnable();
|
chSysEnable();
|
||||||
|
|
|
@ -264,7 +264,7 @@ struct context {
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
||||||
if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
|
if ((stkalign_t *)(r13 - 1) < (otp)->p_stklimit) \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,7 +361,7 @@ struct context {
|
||||||
#else
|
#else
|
||||||
#define port_switch(ntp, otp) { \
|
#define port_switch(ntp, otp) { \
|
||||||
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
||||||
if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
|
if ((stkalign_t *)(r13 - 1) < (otp)->p_stklimit) \
|
||||||
chSysHalt("stack overflow"); \
|
chSysHalt("stack overflow"); \
|
||||||
_port_switch(ntp, otp); \
|
_port_switch(ntp, otp); \
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue