diff --git a/demos/Win32-MinGW/chcore.c b/demos/Win32-MinGW/chcore.c
index 9e9aba3fd..1d1a134b7 100644
--- a/demos/Win32-MinGW/chcore.c
+++ b/demos/Win32-MinGW/chcore.c
@@ -17,91 +17,76 @@
along with this program. If not, see .
*/
-/*
- * Core file for MingGW32 demo project.
+/**
+ * @addtogroup WIN32SIM_CORE
+ * @{
*/
-#include
-#include
-
-#undef CDECL
-
#include
-static LARGE_INTEGER nextcnt;
-static LARGE_INTEGER slice;
-
-void InitSimCom1(void);
-void InitSimCom2(void);
-BOOL Com1ConnInterruptSimCom(void);
-BOOL Com2ConnInterruptSimCom(void);
-BOOL Com1InInterruptSimCom(void);
-BOOL Com2InInterruptSimCom(void);
-BOOL Com1OutInterruptSimCom(void);
-BOOL Com2OutInterruptSimCom(void);
-
/*
- * Simulated HW initialization.
+ * This file is a template of the system driver functions provided by a port.
+ * Some of the following functions may be implemented as macros in chcore.h if
+ * the implementer decides that there is an advantage in doing so, as example
+ * because performance concerns.
*/
-void InitCore(void) {
- WSADATA wsaData;
- // Initialization.
- if (WSAStartup(2, &wsaData) != 0) {
- printf("Unable to locate a winsock DLL\n");
- exit(1);
- }
-
- printf("Win32 ChibiOS/RT simulator\n\n");
- printf("Thread structure %d bytes\n", sizeof(Thread));
- if (!QueryPerformanceFrequency(&slice)) {
- printf("QueryPerformanceFrequency() error");
- exit(1);
- }
- printf("Core Frequency %u Hz\n", (int)slice.LowPart);
- slice.QuadPart /= CH_FREQUENCY;
- QueryPerformanceCounter(&nextcnt);
- nextcnt.QuadPart += slice.QuadPart;
-
- InitSimCom1();
- InitSimCom2();
- fflush(stdout);
-}
-
-/*
- * Interrupt simulation.
+/**
+ * Prints a message on the system console.
+ * @param msg pointer to the message
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
*/
-void ChkIntSources(void) {
- LARGE_INTEGER n;
-
- if (Com1InInterruptSimCom() || Com2InInterruptSimCom() ||
- Com1OutInterruptSimCom() || Com2OutInterruptSimCom() ||
- Com1ConnInterruptSimCom() || Com2ConnInterruptSimCom()) {
- if (chSchRescRequiredI())
- chSchDoRescheduleI();
- return;
- }
-
- // Interrupt Timer simulation (10ms interval).
- QueryPerformanceCounter(&n);
- if (n.QuadPart > nextcnt.QuadPart) {
- nextcnt.QuadPart += slice.QuadPart;
- chSysTimerHandlerI();
- if (chSchRescRequiredI())
- chSchDoRescheduleI();
- }
+__attribute__((weak))
+void sys_puts(char *msg) {
}
-msg_t _idle(void *p) {
+/**
+ * Performs a context switch between two threads.
+ * @param otp the thread to be switched out
+ * @param ntp the thread to be switched in
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+__attribute__((naked, weak))
+void sys_switch(Thread *otp, Thread *ntp) {
+ register struct intctx *esp asm("esp");
- while (TRUE) {
-
- ChkIntSources();
- Sleep(0);
- }
+ asm volatile ("push %ebp \n\t" \
+ "push %esi \n\t" \
+ "push %edi \n\t" \
+ "push %ebx");
+ otp->p_ctx.esp = esp;
+ esp = ntp->p_ctx.esp;
+ asm volatile ("pop %ebx \n\t" \
+ "pop %edi \n\t" \
+ "pop %esi \n\t" \
+ "pop %ebp \n\t" \
+ "ret" : : "r" (esp));
}
-__attribute__((fastcall)) void chSysHalt(void) {
+/**
+ * Halts the system. In this implementation it just exits the simulation.
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+__attribute__((weak))
+void sys_halt(void) {
exit(2);
}
+
+/**
+ * Threads return point, it just invokes @p chThdExit().
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+__attribute__((naked, weak))
+void threadexit(void) {
+
+ asm volatile ("push %eax \n\t" \
+ "call _chThdExit");
+}
+
+}
+/** @} */
diff --git a/demos/Win32-MinGW/chcore.h b/demos/Win32-MinGW/chcore.h
index d1f209a68..6c9bf1f7e 100644
--- a/demos/Win32-MinGW/chcore.h
+++ b/demos/Win32-MinGW/chcore.h
@@ -17,27 +17,40 @@
along with this program. If not, see .
*/
-/*
- * Core file for MingGW32 demo project.
+/**
+ * @addtogroup WIN32SIM_CORE
+ * @{
*/
#ifndef _CHCORE_H_
#define _CHCORE_H_
-/*
- * Unique macro for the implemented architecture.
+/**
+ * Macro defining the a simulated architecture into Win32.
*/
#define CH_ARCHITECTURE_WIN32SIM
-/*
- * Base type for stack alignment.
+/**
+ * 32 bit stack alignment.
*/
typedef uint32_t stkalign_t;
+/**
+ * Generic x86 register.
+ */
typedef void *regx86;
-/*
- * Stack saved context.
+/**
+ * Interrupt saved context.
+ * This structure represents the stack frame saved during a preemption-capable
+ * interrupt handler.
+ */
+struct extctx {
+};
+
+/**
+ * System saved context.
+ * @note In this demo the floating point registers are not saved.
*/
struct intctx {
regx86 ebx;
@@ -47,17 +60,26 @@ struct intctx {
regx86 eip;
};
+/**
+ * Platform dependent part of the @p Thread structure.
+ * This structure usually contains just the saved stack pointer defined as a
+ * pointer to a @p intctx structure.
+ */
typedef struct {
struct intctx *esp;
} Context;
#define APUSH(p, a) (p) -= sizeof(void *), *(void **)(p) = (void*)(a)
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) \
-{ \
+/**
+ * Platform dependent part of the @p chThdInit() API.
+ * This code usually setup the context switching frame represented by a
+ * @p intctx structure.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
uint8_t *esp = (uint8_t *)workspace + wsize; \
APUSH(esp, arg); \
- APUSH(esp, threadstart); \
+ APUSH(esp, threadexit); \
esp -= sizeof(struct intctx); \
((struct intctx *)esp)->eip = pf; \
((struct intctx *)esp)->ebx = 0; \
@@ -67,33 +89,96 @@ typedef struct {
tp->p_ctx.esp = (struct intctx *)esp; \
}
-#define chSysLock()
-#define chSysUnlock()
-#define chSysEnable()
-#define chSysPuts(msg) {}
-#define chSysIRQEnterI()
-#define chSysIRQExitI()
+/**
+ * Stack size for the system idle thread.
+ */
+#ifndef IDLE_THREAD_STACK_SIZE
+#define IDLE_THREAD_STACK_SIZE 256
+#endif
-#define INT_REQUIRED_STACK 0
+/**
+ * Per-thread stack overhead for interrupts servicing, it is used in the
+ * calculation of the correct working area size.
+ * It requires stack space because the simulated "interrupt handlers" invoke
+ * Win32 APIs inside so it better have a lot of space.
+ */
+#ifndef INT_REQUIRED_STACK
+#define INT_REQUIRED_STACK 16384
+#endif
+/**
+ * Enforces a correct alignment for a stack area size value.
+ */
#define STACK_ALIGN(n) ((((n) - 1) | sizeof(stkalign_t)) + 1)
+ /**
+ * Computes the thread working area global size.
+ */
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(void *) * 2 + \
sizeof(struct intctx) + \
- (n) + \
- INT_REQUIRED_STACK)
+ sizeof(struct extctx) + \
+ (n) + (INT_REQUIRED_STACK))
+/**
+ * Macro used to allocate a thread working area aligned as both position and
+ * size.
+ */
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)];
-/*
- * Stack size for the system idle thread.
+/**
+ * IRQ prologue code, inserted at the start of all IRQ handlers enabled to
+ * invoke system APIs.
*/
-#define IDLE_THREAD_STACK_SIZE 16384
+#define SYS_IRQ_PROLOGUE()
-msg_t _idle(void *p);
-__attribute__((fastcall)) void chSysHalt(void);
-__attribute__((fastcall)) void chSysSwitchI(Thread *otp, Thread *ntp);
-__attribute__((fastcall)) void threadstart(void);
+/**
+ * IRQ epilogue code, inserted at the end of all IRQ handlers enabled to
+ * invoke system APIs.
+ */
+#define SYS_IRQ_EPILOGUE()
+
+/**
+ * Does nothing in this simulator.
+ */
+#define sys_disable()
+
+/**
+ * Does nothing in this simulator.
+ */
+#define sys_enable()
+
+/**
+ * Does nothing in this simulator.
+ */
+#define sys_disable_from_isr()
+
+/**
+ * Does nothing in this simulator.
+ */
+#define sys_enable_from_isr()
+
+/**
+ * Does nothing in this simulator.
+ */
+#define sys_wait_for_interrupt()
+
+/**
+ * IRQ handler function modifier.
+ */
+#define SYS_IRQ_HANDLER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ __attribute__((fastcall)) void sys_puts(char *msg);
+ __attribute__((fastcall)) void sys_switch(Thread *otp, Thread *ntp);
+ __attribute__((fastcall)) void sys_halt(void);
+ void threadexit(void);
+#ifdef __cplusplus
+}
+#endif
#endif /* _CHCORE_H_ */
+
+/** @} */
diff --git a/ports/AVR/chcore.h b/ports/AVR/chcore.h
index e41ec673f..90755cb4e 100644
--- a/ports/AVR/chcore.h
+++ b/ports/AVR/chcore.h
@@ -28,7 +28,6 @@
#include
#include
-
/*
* Port-related configuration parameters.
*/
@@ -226,6 +225,7 @@ extern "C" {
void sys_puts(char *msg);
void sys_switch(Thread *otp, Thread *ntp);
void sys_halt(void);
+ void threadstart(void);
#ifdef __cplusplus
}
#endif
diff --git a/ports/MSP430/chcore.h b/ports/MSP430/chcore.h
index 42f0c2f71..8510aa76c 100644
--- a/ports/MSP430/chcore.h
+++ b/ports/MSP430/chcore.h
@@ -193,6 +193,7 @@ extern "C" {
void sys_puts(char *msg);
void sys_switch(Thread *otp, Thread *ntp);
void sys_halt(void);
+ void threadstart(void);
#ifdef __cplusplus
}
#endif