From c570ba9095c7ee8a019f2fbba42414c2ae9d8918 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Fri, 26 Apr 2024 17:35:20 +0800 Subject: [PATCH] Add vPortGenerateSimulatedInterruptFromNative in MSVC port * vPortGenerateSimulatedInterruptFromNative enables native windows thread to notify FreeRTOS task when certain task is done. --- portable/MSVC-MingW/port.c | 49 ++++++++++++++++++--------------- portable/MSVC-MingW/portmacro.h | 13 +++++++-- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/portable/MSVC-MingW/port.c b/portable/MSVC-MingW/port.c index d489746f57..cdec17e864 100644 --- a/portable/MSVC-MingW/port.c +++ b/portable/MSVC-MingW/port.c @@ -177,28 +177,7 @@ static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter ) Sleep( portTICK_PERIOD_MS ); } - if( xPortRunning == pdTRUE ) - { - configASSERT( xPortRunning ); - - /* Can't proceed if in a critical section as pvInterruptEventMutex won't - * be available. */ - WaitForSingleObject( pvInterruptEventMutex, INFINITE ); - - /* The timer has expired, generate the simulated tick event. */ - ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK ); - - /* The interrupt is now pending - notify the simulated interrupt - * handler thread. Must be outside of a critical section to get here so - * the handler thread can execute immediately pvInterruptEventMutex is - * released. */ - configASSERT( ulCriticalNesting == 0UL ); - SetEvent( pvInterruptEvent ); - - /* Give back the mutex so the simulated interrupt handler unblocks - * and can access the interrupt handler variables. */ - ReleaseMutex( pvInterruptEventMutex ); - } + vPortGenerateSimulatedInterruptFromNative( portINTERRUPT_TICK ); } return 0; @@ -636,6 +615,32 @@ void vPortGenerateSimulatedInterrupt( uint32_t ulInterruptNumber ) } /*-----------------------------------------------------------*/ +void vPortGenerateSimulatedInterruptFromNative( uint32_t ulInterruptNumber ) +{ + if( xPortRunning == pdTRUE ) + { + /* Can't proceed if in a critical section as pvInterruptEventMutex won't + * be available. */ + WaitForSingleObject( pvInterruptEventMutex, INFINITE ); + + /* Pending a user defined interrupt to be handled in simulated interrupt + * handler thread. */ + ulPendingInterrupts |= ( 1 << ulInterruptNumber ); + + /* The interrupt is now pending - notify the simulated interrupt + * handler thread. Must be outside of a critical section to get here so + * the handler thread can execute immediately pvInterruptEventMutex is + * released. */ + configASSERT( ulCriticalNesting == 0UL ); + SetEvent( pvInterruptEvent ); + + /* Give back the mutex so the simulated interrupt handler unblocks + * and can access the interrupt handler variables. */ + ReleaseMutex( pvInterruptEventMutex ); + } +} +/*-----------------------------------------------------------*/ + void vPortSetInterruptHandler( uint32_t ulInterruptNumber, uint32_t ( * pvHandler )( void ) ) { diff --git a/portable/MSVC-MingW/portmacro.h b/portable/MSVC-MingW/portmacro.h index c2b07fa191..9340742698 100644 --- a/portable/MSVC-MingW/portmacro.h +++ b/portable/MSVC-MingW/portmacro.h @@ -184,8 +184,9 @@ void vPortExitCritical( void ); #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) -#define portINTERRUPT_YIELD ( 0UL ) -#define portINTERRUPT_TICK ( 1UL ) +#define portINTERRUPT_YIELD ( 0UL ) +#define portINTERRUPT_TICK ( 1UL ) +#define portINTERRUPT_APPLICATION_DEFINED_START ( 2UL ) /* * Raise a simulated interrupt represented by the bit mask in ulInterruptMask. @@ -194,6 +195,14 @@ void vPortExitCritical( void ); */ void vPortGenerateSimulatedInterrupt( uint32_t ulInterruptNumber ); +/* + * Raise a simulated interrupt represented by the bit mask in ulInterruptMask. + * Each bit can be used to represent an individual interrupt - with the first + * two bits being used for the Yield and Tick interrupts respectively. This function + * can be called in a native windows thread. + */ +void vPortGenerateSimulatedInterruptFromNative( uint32_t ulInterruptNumber ); + /* * Install an interrupt handler to be called by the simulated interrupt handler * thread. The interrupt number must be above any used by the kernel itself