From 9d18dafd72085b5deefd39422312787673a07497 Mon Sep 17 00:00:00 2001 From: Natie van Rooyen Date: Tue, 23 Oct 2012 17:45:25 +0200 Subject: [PATCH] Atomvm SWI functionality added. --- ports/atomvm/atomport.c | 4 +-- ports/atomvm/atomport.h | 4 +-- ports/atomvm/atomvm.c | 64 ++++++++++++++++++++++++++++++++++++---- ports/atomvm/atomvm.h | 5 ++-- ports/atomvm/msvc/main.c | 6 ++-- 5 files changed, 68 insertions(+), 15 deletions(-) diff --git a/ports/atomvm/atomport.c b/ports/atomvm/atomport.c index a9bc46f..55d6d69 100644 --- a/ports/atomvm/atomport.c +++ b/ports/atomvm/atomport.c @@ -51,7 +51,7 @@ static HANDLE cntrl_thread ; * */ void -atomvmRun () +atomvmRun (void) { atomvmCtrlCreate (&the_atomvm) ; cntrl_thread = CreateThread (NULL, 0, cntrl_thread_proc, (uint32_t*)the_atomvm, CREATE_SUSPENDED, NULL) ; @@ -147,7 +147,7 @@ archContextSwitch (ATOM_TCB * p_sp_old, ATOM_TCB * p_sp_new) * System timer tick interrupt handler. * */ -void archTimerTickIrqHandler () +void archTimerTickIrqHandler (void) { atomIntEnter(); diff --git a/ports/atomvm/atomport.h b/ports/atomvm/atomport.h index 84edb64..0edbf3b 100644 --- a/ports/atomvm/atomport.h +++ b/ports/atomvm/atomport.h @@ -53,8 +53,8 @@ #define ATOM_TLS HATOMVM_CONTEXT context ; /* Function prototypes */ -extern void atomvmRun () ; -extern void archTimerTickIrqHandler () ; +extern void atomvmRun (void) ; +extern void archTimerTickIrqHandler (void) ; /* The instance of the atomvm for this port */ extern HATOMVM the_atomvm ; diff --git a/ports/atomvm/atomvm.c b/ports/atomvm/atomvm.c index b48363f..960b13e 100644 --- a/ports/atomvm/atomvm.c +++ b/ports/atomvm/atomvm.c @@ -119,6 +119,18 @@ typedef struct ATOMVM_CALLBACK_CONTEXT_SWITCH_S { } ATOMVM_CALLBACK_CONTEXT_SWITCH, *PATOMVM_CALLBACK_CONTEXT_SWITCH ; +/* ATOMVM_CALLBACK_INT_REQUEST is the parameter for a ATOMVM_CALLBACK_F call +that take as parameter a pointer to to the function that will be called in +an interrupt context */ +typedef struct ATOMVM_CALLBACK_INT_REQUEST_S { + + ATOMVM_CALLBACK callback ; + + /* Function pointer the callback will call */ + void (*isr) (void) ; + +} ATOMVM_CALLBACK_INT_REQUEST, *PATOMVM_CALLBACK_INT_REQUEST ; + /* ATOMVM_CONTEXT saves the state of a context created by atomvmContextCreate() and sheduled by atomvmContextSwitch(). */ typedef struct ATOMVM_CONTEXT_S { @@ -194,7 +206,6 @@ uint32_t atomvmCtrlCreate (HATOMVM *atomvm) { PATOMVM patomvm = 0 ; - int32_t i ; patomvm = (PATOMVM) malloc (sizeof(struct ATOMVM_S)) ; @@ -494,12 +505,12 @@ atomvmInterruptMask (uint32_t mask) * @return None */ void -atomvmCtrlIntRequest (HATOMVM atomvm, uint32_t isr) +atomvmCtrlIntRequest (HATOMVM atomvm, void (*isr) (void)) { PATOMVM patomvm = (PATOMVM) atomvm ; WaitForSingleObject (patomvm->atomvm_int_complete, INFINITE) ; - while (InterlockedCompareExchange ((volatile uint32_t *)&patomvm->isr, isr, 0) != 0) { + while (InterlockedCompareExchange ((volatile uint32_t *)&patomvm->isr, (uint32_t)isr, 0) != 0) { SwitchToThread() ; } SetEvent (patomvm->atomvm_int) ; @@ -720,7 +731,7 @@ atomvmGetVmId (void) * @return Zero on failure, try to call GetLastError(). */ uint32_t -callbackInterruptWait (PATOMVM patomvm, PATOMVM_CALLBACK callback) +callbackIntWait (PATOMVM patomvm, PATOMVM_CALLBACK callback) { WaitForSingleObject (patomvm->atomvm_int_complete, INFINITE) ; return WaitForSingleObject (patomvm->atomvm_int, INFINITE) == WAIT_OBJECT_0 ; @@ -739,12 +750,53 @@ callbackInterruptWait (PATOMVM patomvm, PATOMVM_CALLBACK callback) * @return void. */ void -atomvmInterruptWait (void) +atomvmIntWait (void) { PATOMVM patomvm = getAtomvm () ; ATOMVM_CALLBACK callback ; - invokeCallback (patomvm, callbackInterruptWait, (PATOMVM_CALLBACK)&callback) ; + invokeCallback (patomvm, callbackIntWait, (PATOMVM_CALLBACK)&callback) ; +} + +/** +* \b callbackIntRequest +* +* This function is invoked from the controll thread after a call to atomvmIntRequest(). +* +* The atom virtual machine is suspended while this function is called. +* +* @param[in] patomvm Pointer to the virtual machine created by atomvmCtrlCreate. +* @param[in] callback Callback parameter. +* +* @return Zero on failure, try to call GetLastError(). +*/ +uint32_t +callbackIntRequest (PATOMVM patomvm, PATOMVM_CALLBACK callback) +{ + PATOMVM_CALLBACK_INT_REQUEST int_request = (PATOMVM_CALLBACK_INT_REQUEST)callback ; + + int_request->isr () ; + return 1 ; +} + +/** +* \ingroup atomvm +* \b atomvmIntRequest +* +* This function is to be used by the atom virtual machine. +* +* @param[in] isr Function that will be called from the controll thread. +* +* @return void. +*/ +void +atomvmIntRequest (void (*isr) (void)) +{ + PATOMVM patomvm = getAtomvm () ; + ATOMVM_CALLBACK_INT_REQUEST callback ; + + callback.isr = isr ; + invokeCallback (patomvm, callbackIntRequest, (PATOMVM_CALLBACK)&callback) ; } diff --git a/ports/atomvm/atomvm.h b/ports/atomvm/atomvm.h index 24e2a99..b4ae55d 100644 --- a/ports/atomvm/atomvm.h +++ b/ports/atomvm/atomvm.h @@ -80,7 +80,7 @@ typedef struct ATOMVM_CONTEXT* HATOMVM_CONTEXT ; /* Function prototypes used for controlling the atom virtual machine */ extern uint32_t atomvmCtrlCreate (HATOMVM* atomvm) ; extern void atomvmCtrlRun (HATOMVM atomvm, uint32_t flags) ; -extern void atomvmCtrlIntRequest (HATOMVM atomvm, uintptr_t isr) ; +extern void atomvmCtrlIntRequest (HATOMVM atomvm, void (*isr) (void)) ; extern void atomvmCtrlClose (HATOMVM atomvm) ; /* Function prototypes for use by the atom virtual machine from within the @@ -91,7 +91,8 @@ extern uint32_t atomvmContextSwitch (HATOMVM_CONTEXT old_context, HATOMV extern void atomvmContextDesrtroy (HATOMVM_CONTEXT context) ; extern void atomvmWriteThreadId (uint32_t thread_id) ; extern uint32_t atomvmReadThreadId (void) ; -extern void atomvmInterruptWait (void) ; +extern void atomvmIntWait (void) ; +extern void atomvmIntRequest (void (*isr) (void)) ; extern uint32_t atomvmGetVmId (void) ; diff --git a/ports/atomvm/msvc/main.c b/ports/atomvm/msvc/main.c index 28f78a8..7d0b4bf 100644 --- a/ports/atomvm/msvc/main.c +++ b/ports/atomvm/msvc/main.c @@ -213,7 +213,7 @@ __atomvmClose () void -test_isr () +test_isr (void) { static int i = 0 ; test_isr_count++ ; @@ -232,7 +232,7 @@ isr_thread_proc (LPVOID lpParameter) int x ; int y = rand() % 100 ; while (1) { - atomvmCtrlIntRequest (the_atomvm, (uintptr_t)test_isr) ; + atomvmCtrlIntRequest (the_atomvm, test_isr) ; if (i++==y) { x = rand() % 50 ; Sleep (x) ; @@ -264,7 +264,7 @@ main () while (1) { Sleep(1) ; - atomvmCtrlIntRequest (the_atomvm, (uintptr_t)archTimerTickIrqHandler) ; + atomvmCtrlIntRequest (the_atomvm, archTimerTickIrqHandler) ; } }