aboutsummaryrefslogtreecommitdiffstats
path: root/os/ports/RC/STM8
diff options
context:
space:
mode:
Diffstat (limited to 'os/ports/RC/STM8')
-rw-r--r--os/ports/RC/STM8/chcore.c32
-rw-r--r--os/ports/RC/STM8/chcore.h25
2 files changed, 48 insertions, 9 deletions
diff --git a/os/ports/RC/STM8/chcore.c b/os/ports/RC/STM8/chcore.c
index bccfc454a..af890f6b9 100644
--- a/os/ports/RC/STM8/chcore.c
+++ b/os/ports/RC/STM8/chcore.c
@@ -24,10 +24,42 @@
* @addtogroup STM8_CORE
* @{
*/
+#pragma SRC("tmp.asm")
#include "ch.h"
/**
+ * @brief Performs a context switch between two threads.
+ *
+ * @param otp the thread to be switched out
+ */
+void _port_switch(Thread *otp) {
+
+ (void)otp;
+ /* Asm because unoptimal code would generated by using _getSP_().*/
+#pragma ASM
+ EXTRN PAGE0(rlist)
+
+ LDW Y,SP ; old context pointer
+ LDW (005H,X),Y ; SP saved in otp->p_ctx.sp
+ LDW X,rlist + 0DH ; r_current (currp) field
+ LDW X,(005H,X) ; currp->p_ctx.sp
+ LDW SP,X ; new context pointer
+#pragma ENDASM
+}
+
+/**
+ * @brief Thread start code.
+ */
+void _port_thread_start(void) {
+
+#pragma ASM
+ RIM
+ POPW X
+#pragma ENDASM
+}
+
+/**
* @brief Halts the system.
* @details This function is invoked by the operating system when an
* unrecoverable error is detected (as example because a programming
diff --git a/os/ports/RC/STM8/chcore.h b/os/ports/RC/STM8/chcore.h
index f652a858b..6df8c5a61 100644
--- a/os/ports/RC/STM8/chcore.h
+++ b/os/ports/RC/STM8/chcore.h
@@ -47,6 +47,13 @@
typedef uint8_t stkalign_t;
/**
+ * @brief Generic STM8 function pointer.
+ * @note It is used to allocate the proper size for return addresses in
+ * context-related structures.
+ */
+typedef void (*stm8func_t)(void);
+
+/**
* @brief Interrupt saved context.
* @details This structure represents the stack frame saved during a
* preemption-capable interrupt handler.
@@ -75,7 +82,7 @@ struct extctx {
*/
struct intctx {
uint8_t _next;
- uint16_t pc;
+ stm8func_t pc; /* Function pointer sized return address. */
};
/**
@@ -85,10 +92,10 @@ struct intctx {
*/
struct startctx {
uint8_t _next;
- uint16_t ts; /* Trampoline address. */
- uint16_t arg; /* Thread argument. */
- uint16_t pc; /* Thread function address. */
- uint16_t ret; /* chThdExit() address. */
+ stm8func_t ts; /* Trampoline address. */
+ void *arg; /* Thread argument. */
+ stm8func_t pc; /* Thread function address. */
+ stm8func_t ret; /* chThdExit() address. */
};
/**
@@ -109,10 +116,10 @@ struct context {
struct startctx *scp; \
scp = (struct startctx *)((uint8_t *)workspace + wsize - \
sizeof(struct startctx)); \
- scp->ts = (uint16_t)_port_thread_start; \
- scp->arg = (uint16_t)arg; \
- scp->pc = (uint16_t)pf; \
- scp->ret = (uint16_t)chThdExit; \
+ scp->ts = _port_thread_start; \
+ scp->arg = arg; \
+ scp->pc = (stm8func_t)pf; \
+ scp->ret = (stm8func_t)chThdExit; \
tp->p_ctx.sp = (struct intctx *)scp; \
}