aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/ARMCM3-STM32F103/ch.ld18
-rw-r--r--demos/ARMCM3-STM32F103/chconf.h2
-rw-r--r--os/kernel/include/chschd.h4
-rw-r--r--os/kernel/include/chthreads.h30
-rw-r--r--os/kernel/src/chsys.c6
-rw-r--r--os/kernel/src/chthreads.c3
-rw-r--r--os/ports/GCC/ARMCMx/LPC11xx/vectors.c4
-rw-r--r--os/ports/GCC/ARMCMx/LPC13xx/vectors.c4
-rw-r--r--os/ports/GCC/ARMCMx/STM32/port.mk3
-rw-r--r--os/ports/GCC/ARMCMx/STM32/vectors.c4
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v6m.h4
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v7m.c10
-rw-r--r--os/ports/GCC/ARMCMx/chcore_v7m.h23
-rw-r--r--os/ports/GCC/ARMCMx/crt0.c25
-rw-r--r--readme.txt12
15 files changed, 95 insertions, 57 deletions
diff --git a/demos/ARMCM3-STM32F103/ch.ld b/demos/ARMCM3-STM32F103/ch.ld
index 4d97e7682..f929c0832 100644
--- a/demos/ARMCM3-STM32F103/ch.ld
+++ b/demos/ARMCM3-STM32F103/ch.ld
@@ -23,7 +23,6 @@
*/
__main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0400;
-__stacks_total_size__ = __main_stack_size__ + __process_stack_size__;
MEMORY
{
@@ -98,6 +97,21 @@ SECTIONS
_etext = .;
_textdata = _etext;
+ .stacks :
+ {
+ . = ALIGN(8);
+ __main_stack_base__ = .;
+ . += __main_stack_size__;
+ . = ALIGN(8);
+ __main_stack_end__ = .;
+ __process_stack_base__ = .;
+ __main_thread_stack_base__ = .;
+ . += __process_stack_size__;
+ . = ALIGN(8);
+ __process_stack_end__ = .;
+ __main_thread_stack_end__ = .;
+ } > ram
+
.data :
{
PROVIDE(_data = .);
@@ -127,4 +141,4 @@ PROVIDE(end = .);
_end = .;
__heap_base__ = _end;
-__heap_end__ = __ram_end__ - __stacks_total_size__;
+__heap_end__ = __ram_end__;
diff --git a/demos/ARMCM3-STM32F103/chconf.h b/demos/ARMCM3-STM32F103/chconf.h
index c9c4c286a..cdf4ee616 100644
--- a/demos/ARMCM3-STM32F103/chconf.h
+++ b/demos/ARMCM3-STM32F103/chconf.h
@@ -395,7 +395,7 @@
* @p panic_msg variable set to @p NULL.
*/
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
-#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#define CH_DBG_ENABLE_STACK_CHECK TRUE
#endif
/**
diff --git a/os/kernel/include/chschd.h b/os/kernel/include/chschd.h
index e154da863..cd545a05e 100644
--- a/os/kernel/include/chschd.h
+++ b/os/kernel/include/chschd.h
@@ -76,12 +76,12 @@ typedef struct {
initialized to zero. */
struct context r_ctx; /**< @brief Not used, present because
offsets. */
-#if CH_USE_REGISTRY
+#if CH_USE_REGISTRY || defined(__DOXYGEN__)
Thread *r_newer; /**< @brief Newer registry element. */
Thread *r_older; /**< @brief Older registry element. */
#endif
/* End of the fields shared with the Thread structure.*/
-#if CH_TIME_QUANTUM > 0
+#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
cnt_t r_preempt; /**< @brief Round robin counter. */
#endif
Thread *r_current; /**< @brief The currently running
diff --git a/os/kernel/include/chthreads.h b/os/kernel/include/chthreads.h
index e0f1b3e95..b02960bd4 100644
--- a/os/kernel/include/chthreads.h
+++ b/os/kernel/include/chthreads.h
@@ -44,17 +44,23 @@ struct Thread {
/* End of the fields shared with the ThreadsQueue structure. */
tprio_t p_prio; /**< @brief Thread priority. */
struct context p_ctx; /**< @brief Processor context. */
-#if CH_USE_REGISTRY
+#if CH_USE_REGISTRY || defined(__DOXYGEN__)
Thread *p_newer; /**< @brief Newer registry element. */
Thread *p_older; /**< @brief Older registry element. */
#endif
/* End of the fields shared with the ReadyList structure. */
-#if CH_USE_REGISTRY
+#if CH_USE_REGISTRY || defined(__DOXYGEN__)
/**
* @brief Thread name or @p NULL.
*/
const char *p_name;
#endif
+#if CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
+ /**
+ * @brief Thread stack boundary.
+ */
+ stkalign_t *p_stklimit;
+#endif
/**
* @brief Current thread state.
*/
@@ -63,19 +69,19 @@ struct Thread {
* @brief Various thread flags.
*/
tmode_t p_flags;
-#if CH_USE_DYNAMIC
+#if CH_USE_DYNAMIC || defined(__DOXYGEN__)
/**
* @brief References to this thread.
*/
trefs_t p_refs;
#endif
-#if CH_USE_NESTED_LOCKS
+#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__)
/**
* @brief Number of nested locks.
*/
cnt_t p_locks;
#endif
-#if CH_DBG_THREADS_PROFILING
+#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__)
/**
* @brief Thread consumed time in ticks.
* @note This field can overflow.
@@ -109,22 +115,22 @@ struct Thread {
* states.
*/
void *wtobjp;
-#if CH_USE_EVENTS
+#if CH_USE_EVENTS || defined(__DOXYGEN__)
/**
* @brief Enabled events mask.
- * @note This field is only valied while the thread is in the
+ * @note This field is only valid while the thread is in the
* @p THD_STATE_WTOREVT or @p THD_STATE_WTANDEVT states.
*/
eventmask_t ewmask;
#endif
} p_u;
-#if CH_USE_WAITEXIT
+#if CH_USE_WAITEXIT || defined(__DOXYGEN__)
/**
* @brief Termination waiting list.
*/
ThreadsList p_waiting;
#endif
-#if CH_USE_MESSAGES
+#if CH_USE_MESSAGES || defined(__DOXYGEN__)
/**
* @brief Messages queue.
*/
@@ -134,13 +140,13 @@ struct Thread {
*/
msg_t p_msg;
#endif
-#if CH_USE_EVENTS
+#if CH_USE_EVENTS || defined(__DOXYGEN__)
/**
* @brief Pending events mask.
*/
eventmask_t p_epending;
#endif
-#if CH_USE_MUTEXES
+#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief List of the mutexes owned by this thread.
* @note The list is terminated by a @p NULL in this field.
@@ -151,7 +157,7 @@ struct Thread {
*/
tprio_t p_realprio;
#endif
-#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS
+#if (CH_USE_DYNAMIC && CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
/**
* @brief Memory Pool where the thread workspace is returned.
*/
diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c
index 8d9ce4905..4c8cd708d 100644
--- a/os/kernel/src/chsys.c
+++ b/os/kernel/src/chsys.c
@@ -77,6 +77,9 @@ void _idle_thread(void *p) {
*/
void chSysInit(void) {
static Thread mainthread;
+#if CH_DBG_ENABLE_STACK_CHECK
+ extern stkalign_t __main_thread_stack_base__;
+#endif
port_init();
_scheduler_init();
@@ -94,6 +97,9 @@ void chSysInit(void) {
/* Now this instructions flow becomes the main thread.*/
setcurrp(_thread_init(&mainthread, NORMALPRIO));
currp->p_state = THD_STATE_CURRENT;
+#if CH_DBG_ENABLE_STACK_CHECK
+ currp->p_stklimit = &__main_thread_stack_base__;
+#endif
chSysEnable();
chRegSetThreadName("main");
diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c
index b68263a7b..182de7673 100644
--- a/os/kernel/src/chthreads.c
+++ b/os/kernel/src/chthreads.c
@@ -99,6 +99,9 @@ Thread *_thread_init(Thread *tp, tprio_t prio) {
#if CH_USE_MESSAGES
queue_init(&tp->p_msgqueue);
#endif
+#if CH_DBG_ENABLE_STACK_CHECK
+ tp->p_stklimit = (stkalign_t *)(tp + 1);
+#endif
#if defined(THREAD_EXT_INIT_HOOK)
THREAD_EXT_INIT_HOOK(tp);
#endif
diff --git a/os/ports/GCC/ARMCMx/LPC11xx/vectors.c b/os/ports/GCC/ARMCMx/LPC11xx/vectors.c
index 63b343ea2..527d82836 100644
--- a/os/ports/GCC/ARMCMx/LPC11xx/vectors.c
+++ b/os/ports/GCC/ARMCMx/LPC11xx/vectors.c
@@ -31,7 +31,7 @@
#include "ch.h"
#if !defined(__DOXYGEN__)
-extern void __ram_end__(void);
+extern void __main_stack_end__(void);
extern void ResetHandler(void);
extern void NMIVector(void);
extern void HardFaultVector(void);
@@ -88,7 +88,7 @@ extern void VectorBC(void);
__attribute__ ((section("vectors")))
#endif
void (*_vectors[])(void) = {
- __ram_end__, ResetHandler, NMIVector, HardFaultVector,
+ __main_stack_end__, ResetHandler, NMIVector, HardFaultVector,
MemManageVector, BusFaultVector, UsageFaultVector, Vector1C,
Vector20, Vector24, Vector28, SVCallVector,
DebugMonitorVector, Vector34, PendSVVector, SysTickVector,
diff --git a/os/ports/GCC/ARMCMx/LPC13xx/vectors.c b/os/ports/GCC/ARMCMx/LPC13xx/vectors.c
index 1e27c4fc8..14bc798dd 100644
--- a/os/ports/GCC/ARMCMx/LPC13xx/vectors.c
+++ b/os/ports/GCC/ARMCMx/LPC13xx/vectors.c
@@ -31,7 +31,7 @@
#include "ch.h"
#if !defined(__DOXYGEN__)
-extern void __ram_end__(void);
+extern void __main_stack_end__(void);
extern void ResetHandler(void);
extern void NMIVector(void);
extern void HardFaultVector(void);
@@ -112,7 +112,7 @@ extern void Vector11C(void);
__attribute__ ((section("vectors")))
#endif
void (*_vectors[])(void) = {
- __ram_end__, ResetHandler, NMIVector, HardFaultVector,
+ __main_stack_end__, ResetHandler, NMIVector, HardFaultVector,
MemManageVector, BusFaultVector, UsageFaultVector, Vector1C,
Vector20, Vector24, Vector28, SVCallVector,
DebugMonitorVector, Vector34, PendSVVector, SysTickVector,
diff --git a/os/ports/GCC/ARMCMx/STM32/port.mk b/os/ports/GCC/ARMCMx/STM32/port.mk
index 104b22e42..1e5a51a8d 100644
--- a/os/ports/GCC/ARMCMx/STM32/port.mk
+++ b/os/ports/GCC/ARMCMx/STM32/port.mk
@@ -9,3 +9,6 @@ PORTASM =
PORTINC = ${CHIBIOS}/os/ports/GCC/ARMCMx \
${CHIBIOS}/os/ports/GCC/ARMCMx/STM32
+
+PORTLD = ${CHIBIOS}/os/ports/GCC/ARMCMx/STM32/ld
+
diff --git a/os/ports/GCC/ARMCMx/STM32/vectors.c b/os/ports/GCC/ARMCMx/STM32/vectors.c
index f12e2e867..e4d1bcb28 100644
--- a/os/ports/GCC/ARMCMx/STM32/vectors.c
+++ b/os/ports/GCC/ARMCMx/STM32/vectors.c
@@ -38,7 +38,7 @@
#endif
#if !defined(__DOXYGEN__)
-extern void __ram_end__(void);
+extern void __main_stack_end__(void);
extern void ResetHandler(void);
extern void NMIVector(void);
extern void HardFaultVector(void);
@@ -138,7 +138,7 @@ extern void Vector14C(void);
__attribute__ ((section("vectors")))
#endif
void (*_vectors[])(void) = {
- __ram_end__, ResetHandler, NMIVector, HardFaultVector,
+ __main_stack_end__, ResetHandler, NMIVector, HardFaultVector,
MemManageVector, BusFaultVector, UsageFaultVector, Vector1C,
Vector20, Vector24, Vector28, SVCallVector,
DebugMonitorVector, Vector34, PendSVVector, SysTickVector,
diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h
index 2141ee468..bb6e6083b 100644
--- a/os/ports/GCC/ARMCMx/chcore_v6m.h
+++ b/os/ports/GCC/ARMCMx/chcore_v6m.h
@@ -242,8 +242,8 @@ struct intctx {
#define port_switch(ntp, otp) _port_switch(ntp, otp)
#else
#define port_switch(ntp, otp) { \
- register struct intctx *r13 asm ("r13"); \
- if ((void *)(r13 - 1) < (void *)(otp + 1)) \
+ register struct intctx *r13 asm ("r13"); \
+ if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
chDbgPanic("stack overflow"); \
_port_switch(ntp, otp); \
}
diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c
index 897c90a96..39711ce79 100644
--- a/os/ports/GCC/ARMCMx/chcore_v7m.c
+++ b/os/ports/GCC/ARMCMx/chcore_v7m.c
@@ -166,15 +166,7 @@ void _port_switch_from_isr(void) {
#if !defined(__DOXYGEN__)
__attribute__((naked))
#endif
-void port_switch(Thread *ntp, Thread *otp) {
-
-#if CH_DBG_ENABLE_STACK_CHECK
- /* Stack overflow check, if enabled.*/
- register struct intctx *r13 asm ("r13");
- if ((void *)(r13 - 1) < (void *)(otp + 1))
- asm volatile ("movs r0, #0 \n\t"
- "b chDbgPanic");
-#endif /* CH_DBG_ENABLE_STACK_CHECK */
+void _port_switch(Thread *ntp, Thread *otp) {
PUSH_CONTEXT();
diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h
index 297bd4e54..afb3ac21d 100644
--- a/os/ports/GCC/ARMCMx/chcore_v7m.h
+++ b/os/ports/GCC/ARMCMx/chcore_v7m.h
@@ -314,11 +314,32 @@ struct intctx {
#define port_wait_for_interrupt()
#endif
+/**
+ * @brief Performs a context switch between two threads.
+ * @details This is the most critical code in any port, this function
+ * is responsible for the context switch between 2 threads.
+ * @note The implementation of this code affects <b>directly</b> the context
+ * switch performance so optimize here as much as you can.
+ *
+ * @param[in] ntp the thread to be switched in
+ * @param[in] otp the thread to be switched out
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
+#define port_switch(ntp, otp) _port_switch(ntp, otp)
+#else
+#define port_switch(ntp, otp) { \
+ register struct intctx *r13 asm ("r13"); \
+ if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
+ chDbgPanic("stack overflow"); \
+ _port_switch(ntp, otp); \
+}
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
void port_halt(void);
- void port_switch(Thread *ntp, Thread *otp);
+ void _port_switch(Thread *ntp, Thread *otp);
void _port_irq_epilogue(void);
void _port_switch_from_isr(void);
void _port_thread_start(void);
diff --git a/os/ports/GCC/ARMCMx/crt0.c b/os/ports/GCC/ARMCMx/crt0.c
index 0bb88dd83..73dca119e 100644
--- a/os/ports/GCC/ARMCMx/crt0.c
+++ b/os/ports/GCC/ARMCMx/crt0.c
@@ -73,28 +73,11 @@ typedef funcp_t * funcpp_t;
#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
/**
- * @brief Ram end.
+ * @brief Main thread stack initial position.
* @details This symbol must be exported by the linker script and represents
- * the location after the last RAM location.
+ * the main thread stack initial position.
*/
-extern uint8_t __ram_end__;
-
-/**
- * @brief Main stack size.
- * @details This symbol must be exported by the linker script and represents
- * the main stack size.
- * @note The main stack is the stack where interrupts and exceptions are
- * processed.
- */
-extern uint8_t __main_stack_size__;
-
-/**
- * @brief Process stack size.
- * @details This symbol must be exported by the linker script and represents
- * the process stack size.
- * @note The process stack is the stack used by the @p main() function.
- */
-extern uint8_t __process_stack_size__;
+extern uint8_t __process_stack_end__;
/**
* @brief ROM image of the data segment start.
@@ -206,7 +189,7 @@ void ResetHandler(void) {
main stack is assumed to be allocated starting from @p __ram_end__
extending downward.*/
asm volatile ("cpsid i");
- psp = SYMVAL(__ram_end__) - SYMVAL(__main_stack_size__);
+ psp = SYMVAL(__process_stack_end__);
asm volatile ("msr PSP, %0" : : "r" (psp));
ctl = CRT0_CONTROL_INIT;
diff --git a/readme.txt b/readme.txt
index 3578a38aa..8a8bbac1b 100644
--- a/readme.txt
+++ b/readme.txt
@@ -87,6 +87,15 @@
(backported to 2.2.4).
- FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420)
(backported to 2.2.4).
+- NEW: Improved stack checking and reorganized memory map for the Cortex-Mx
+ demos. Now stacks are allocated at the start of the RAM, an overflow of the
+ exception stack now triggers an exception (it could went unnoticed before).
+ The process stack is organized to be checked on context switch like other
+ threads. Now all threads have an explicit stack boundary pointer.
+ (to be completed, most demos have to be edited)
+ (documentation to be updated)
+ (change to be ported to IAR and Keil ports)
+ (change to be ported to ARM and other ports)
- NEW: Added debug plugin for Eclipse under ./tools/eclipse (backported to
2.2.7).
- NEW: The debug macros chDbgCheck() and chDbgAssert() now can be externally
@@ -96,6 +105,7 @@
- NEW: Added provisional support for STM32L1xx and STM32F2xx. Because of this
some directories related to the STM32 have been renamed, your makefiles may
require adjustments.
+ (change to be ported to IAR and Keil build files)
- NEW: Added a custom rule to the various rules.mk files, now it is possible
to add an user rule into the Makefiles.
- NEW: Improvements to the trace buffer, now it stores a full thread pointer
@@ -450,7 +460,7 @@
(backported to 2.0.6).
- FIX: Incorrect AT91SAM7X initialization, thanks Leszek (bug 3075354)
(backported to 2.0.5).
-- FIX: Fixed race condition in function chSchGoSleepTimeoutS(), thanks Balázs
+- FIX: Fixed race condition in function chSchGoSleepTimeoutS(), thanks Bal�zs
(bug 3074984)(backported to 2.0.5).
- FIX: Fixed race condition in threads creation (bug 3069854)(backported
to 2.0.5).