From 6518cb153df20a72947f9b9110fa3d09feecc2d3 Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Mon, 20 May 2024 16:15:02 +0800 Subject: [PATCH] Update cellular comm interface to generate interrupt from windows thread (#1221) * Make use of vPortGenerateSimulatedInterruptFromWindowsThread to generate interrupt from windows thread --- .../Common/comm_if_windows.c | 311 ++---------------- FreeRTOS/Source | 2 +- manifest.yml | 2 +- 3 files changed, 38 insertions(+), 277 deletions(-) diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/comm_if_windows.c b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/comm_if_windows.c index 4412df1d9d..f3f6b691c5 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/comm_if_windows.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/comm_if_windows.c @@ -48,37 +48,23 @@ #ifndef CELLULAR_COMM_INTERFACE_PORT #error "Define CELLULAR_COMM_INTERFACE_PORT in cellular_config.h" #endif -#define CELLULAR_COMM_PATH "\\\\.\\"CELLULAR_COMM_INTERFACE_PORT +#define CELLULAR_COMM_PATH "\\\\.\\"CELLULAR_COMM_INTERFACE_PORT /* Define the simulated UART interrupt number. */ -#define portINTERRUPT_UART ( 2UL ) +#define appINTERRUPT_UART portINTERRUPT_APPLICATION_DEFINED_START /* Define the read write buffer size. */ -#define COMM_TX_BUFFER_SIZE ( 8192 ) -#define COMM_RX_BUFFER_SIZE ( 8192 ) +#define COMM_TX_BUFFER_SIZE ( 8192 ) +#define COMM_RX_BUFFER_SIZE ( 8192 ) /* Receive thread timeout in ms. */ -#define COMM_RECV_THREAD_TIMEOUT ( 5000 ) +#define COMM_RECV_THREAD_TIMEOUT ( 5000 ) /* Write operation timeout in ms. */ -#define COMM_WRITE_OPERATION_TIMEOUT ( 500 ) +#define COMM_WRITE_OPERATION_TIMEOUT ( 500 ) /* Comm status. */ -#define CELLULAR_COMM_OPEN_BIT ( 0x01U ) - -/* Comm task event. */ -#define COMMTASK_EVT_MASK_STARTED ( 0x0001UL ) -#define COMMTASK_EVT_MASK_ABORT ( 0x0002UL ) -#define COMMTASK_EVT_MASK_ABORTED ( 0x0004UL ) -#define COMMTASK_EVT_MASK_ALL_EVENTS \ - ( COMMTASK_EVT_MASK_STARTED \ - | COMMTASK_EVT_MASK_ABORT \ - | COMMTASK_EVT_MASK_ABORTED ) -#define COMMTASK_POLLING_TIME_MS ( 1UL ) - -/* Platform thread stack size and priority. */ -#define COMM_IF_THREAD_DEFAULT_STACK_SIZE ( 2048U ) -#define COMM_IF_THREAD_DEFAULT_PRIORITY ( tskIDLE_PRIORITY + 5U ) +#define CELLULAR_COMM_OPEN_BIT ( 0x01U ) /*-----------------------------------------------------------*/ @@ -91,7 +77,6 @@ typedef struct cellularCommContext HANDLE commFileHandle; CellularCommInterface_t * pCommInterface; bool commTaskThreadStarted; - EventGroupHandle_t pCommTaskEvent; } cellularCommContext_t; /*-----------------------------------------------------------*/ @@ -126,14 +111,6 @@ static CellularCommInterfaceError_t prvCommIntfReceive( CellularCommInterfaceHan */ static CellularCommInterfaceError_t prvCommIntfClose( CellularCommInterfaceHandle_t commInterfaceHandle ); -/** - * @brief Get default comm interface context. - * - * @return On success, SOCKETS_ERROR_NONE is returned. If an error occurred, error code defined - * in sockets_wrapper.h is returned. - */ -static cellularCommContext_t * prvGetCellularCommContext( void ); - /** * @brief UART interrupt handler. * @@ -168,34 +145,7 @@ static CellularCommInterfaceError_t prvSetupCommTimeout( HANDLE hComm ); * @return On success, IOT_COMM_INTERFACE_SUCCESS is returned. If an error occurred, error code defined * in CellularCommInterfaceError_t is returned. */ -static CellularCommInterfaceError_t prvSetupCommSettings( HANDLE hComm ); - -/** - * @brief Thread routine to generate simulated interrupt. - * - * @param[in] pUserData Pointer to cellularCommContext_t allocated in comm interface open. - */ -static void prvCommTaskThread( void * pUserData ); - -/** - * @brief Helper function to setup and create commTaskThread. - * - * @param[in] pCellularCommContext Cellular comm interface context allocated in open. - * - * @return On success, IOT_COMM_INTERFACE_SUCCESS is returned. If an error occurred, error code defined - * in CellularCommInterfaceError_t is returned. - */ -static CellularCommInterfaceError_t prvSetupCommTaskThread( cellularCommContext_t * pCellularCommContext ); - -/** - * @brief Helper function to clean commTaskThread. - * - * @param[in] pCellularCommContext Cellular comm interface context allocated in open. - * - * @return On success, IOT_COMM_INTERFACE_SUCCESS is returned. If an error occurred, error code defined - * in CellularCommInterfaceError_t is returned. - */ -static CellularCommInterfaceError_t prvCleanCommTaskThread( cellularCommContext_t * pCellularCommContext ); +static CellularCommInterfaceError_t prvSetupCommState( HANDLE hComm ); /*-----------------------------------------------------------*/ @@ -215,28 +165,14 @@ static cellularCommContext_t uxCellularCommContext = .commFileHandle = NULL, .pUserData = NULL, .commStatus = 0U, - .commTaskThreadStarted = false, - .pCommTaskEvent = NULL + .commTaskThreadStarted = false }; -/* Mutex used to protect rxEvent variables that are accessed by multiple threads. */ -static void * pvRxEventMutex = NULL; - -/* Indicate RX event is received in comm driver. */ -static bool rxEvent = false; - -/*-----------------------------------------------------------*/ - -static cellularCommContext_t * prvGetCellularCommContext( void ) -{ - return &uxCellularCommContext; -} - /*-----------------------------------------------------------*/ static uint32_t prvProcessUartInt( void ) { - cellularCommContext_t * pCellularCommContext = prvGetCellularCommContext(); + cellularCommContext_t * pCellularCommContext = &uxCellularCommContext; CellularCommInterfaceError_t callbackRet = IOT_COMM_INTERFACE_FAILURE; uint32_t retUartInt = pdTRUE; @@ -271,35 +207,35 @@ static DWORD WINAPI prvCellularCommReceiveCBThreadFunc( LPVOID pArgument ) { retValue = ERROR_INVALID_HANDLE; } - - while( retValue == 0 ) + else { - retWait = WaitCommEvent( hComm, &dwCommStatus, NULL ); - - if( ( retWait != FALSE ) && ( ( dwCommStatus & EV_RXCHAR ) != 0 ) ) - { - if( ( dwCommStatus & EV_RXCHAR ) != 0 ) - { - WaitForSingleObject( pvRxEventMutex, INFINITE ); - rxEvent = true; - ReleaseMutex( pvRxEventMutex ); - } - } - else + for( ; ; ) { - if( ( GetLastError() == ERROR_INVALID_HANDLE ) || ( GetLastError() == ERROR_OPERATION_ABORTED ) ) + retWait = WaitCommEvent( hComm, &dwCommStatus, NULL ); + + if( ( retWait != FALSE ) && ( ( dwCommStatus & EV_RXCHAR ) != 0 ) ) { - /* COM port closed. */ - LogInfo( ( "Cellular COM port %p closed", hComm ) ); + /* Generate a simulated interrupt when data is received in the input buffer in driver. + * The interrupt handler prvProcessUartInt() will be called in prvProcessSimulatedInterrupts(). + * This ensures no other task or ISR is running. */ + vPortGenerateSimulatedInterruptFromWindowsThread( appINTERRUPT_UART ); } else { - LogInfo( ( "Cellular receiver thread wait comm error %p %d", hComm, GetLastError() ) ); - } + retValue = GetLastError(); - retValue = GetLastError(); + if( ( retValue == ERROR_INVALID_HANDLE ) || ( retValue == ERROR_OPERATION_ABORTED ) ) + { + /* COM port closed. */ + LogInfo( ( "Cellular COM port %p closed", hComm ) ); + } + else + { + LogInfo( ( "Cellular receiver thread wait comm error %p %d", hComm, retValue ) ); + } - break; + break; + } } } @@ -335,7 +271,7 @@ static CellularCommInterfaceError_t prvSetupCommTimeout( HANDLE hComm ) /*-----------------------------------------------------------*/ -static CellularCommInterfaceError_t prvSetupCommSettings( HANDLE hComm ) +static CellularCommInterfaceError_t prvSetupCommState( HANDLE hComm ) { CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; DCB dcbSerialParams = { 0 }; @@ -367,146 +303,6 @@ static CellularCommInterfaceError_t prvSetupCommSettings( HANDLE hComm ) /*-----------------------------------------------------------*/ -static void prvCommTaskThread( void * pUserData ) -{ - cellularCommContext_t * pCellularCommContext = ( cellularCommContext_t * ) pUserData; - EventBits_t uxBits = 0; - - /* Inform thread ready. */ - LogInfo( ( "Cellular commTaskThread started" ) ); - - if( pCellularCommContext != NULL ) - { - ( void ) xEventGroupSetBits( pCellularCommContext->pCommTaskEvent, - COMMTASK_EVT_MASK_STARTED ); - } - - while( true ) - { - /* Wait for notification from eventqueue. */ - uxBits = xEventGroupWaitBits( ( pCellularCommContext->pCommTaskEvent ), - ( ( EventBits_t ) COMMTASK_EVT_MASK_ABORT ), - pdTRUE, - pdFALSE, - pdMS_TO_TICKS( COMMTASK_POLLING_TIME_MS ) ); - - if( ( uxBits & ( EventBits_t ) COMMTASK_EVT_MASK_ABORT ) != 0U ) - { - LogDebug( ( "Abort received, cleaning up!" ) ); - break; - } - else - { - /* Polling the global share variable to trigger the interrupt. */ - if( rxEvent == true ) - { - WaitForSingleObject( pvRxEventMutex, INFINITE ); - rxEvent = false; - ReleaseMutex( pvRxEventMutex ); - - vPortGenerateSimulatedInterrupt( portINTERRUPT_UART ); - } - } - } - - /* Inform thread ready. */ - if( pCellularCommContext != NULL ) - { - ( void ) xEventGroupSetBits( pCellularCommContext->pCommTaskEvent, COMMTASK_EVT_MASK_ABORTED ); - } - - LogInfo( ( "Cellular commTaskThread exit" ) ); -} - -/*-----------------------------------------------------------*/ - -static CellularCommInterfaceError_t prvSetupCommTaskThread( cellularCommContext_t * pCellularCommContext ) -{ - BOOL Status = TRUE; - EventBits_t uxBits = 0; - CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; - - pCellularCommContext->pCommTaskEvent = xEventGroupCreate(); - - if( pCellularCommContext->pCommTaskEvent != NULL ) - { - /* Create the FreeRTOS thread to generate the simulated interrupt. */ - Status = Platform_CreateDetachedThread( prvCommTaskThread, - ( void * ) pCellularCommContext, - COMM_IF_THREAD_DEFAULT_PRIORITY, - COMM_IF_THREAD_DEFAULT_STACK_SIZE ); - - if( Status != true ) - { - commIntRet = IOT_COMM_INTERFACE_FAILURE; - } - } - else - { - commIntRet = IOT_COMM_INTERFACE_FAILURE; - } - - if( commIntRet == IOT_COMM_INTERFACE_SUCCESS ) - { - uxBits = xEventGroupWaitBits( ( pCellularCommContext->pCommTaskEvent ), - ( ( EventBits_t ) COMMTASK_EVT_MASK_STARTED | ( EventBits_t ) COMMTASK_EVT_MASK_ABORTED ), - pdTRUE, - pdFALSE, - portMAX_DELAY ); - - if( ( uxBits & ( EventBits_t ) COMMTASK_EVT_MASK_STARTED ) == COMMTASK_EVT_MASK_STARTED ) - { - pCellularCommContext->commTaskThreadStarted = true; - } - else - { - commIntRet = IOT_COMM_INTERFACE_FAILURE; - pCellularCommContext->commTaskThreadStarted = false; - } - } - - return commIntRet; -} - -/*-----------------------------------------------------------*/ - -static CellularCommInterfaceError_t prvCleanCommTaskThread( cellularCommContext_t * pCellularCommContext ) -{ - EventBits_t uxBits = 0; - CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; - - /* Wait for the commTaskThreadStarted exit. */ - if( ( pCellularCommContext->commTaskThreadStarted == true ) && ( pCellularCommContext->pCommTaskEvent != NULL ) ) - { - ( void ) xEventGroupSetBits( pCellularCommContext->pCommTaskEvent, - COMMTASK_EVT_MASK_ABORT ); - uxBits = xEventGroupWaitBits( ( pCellularCommContext->pCommTaskEvent ), - ( ( EventBits_t ) COMMTASK_EVT_MASK_ABORTED ), - pdTRUE, - pdFALSE, - portMAX_DELAY ); - - if( ( uxBits & ( EventBits_t ) COMMTASK_EVT_MASK_ABORTED ) != COMMTASK_EVT_MASK_ABORTED ) - { - LogDebug( ( "Cellular close wait commTaskThread fail" ) ); - commIntRet = IOT_COMM_INTERFACE_FAILURE; - } - - pCellularCommContext->commTaskThreadStarted = false; - } - - /* Clean the event group. */ - if( pCellularCommContext->pCommTaskEvent != NULL ) - { - vEventGroupDelete( pCellularCommContext->pCommTaskEvent ); - pCellularCommContext->pCommTaskEvent = NULL; - } - - return commIntRet; -} - -/*-----------------------------------------------------------*/ - static CellularCommInterfaceError_t prvCommIntfOpen( CellularCommInterfaceReceiveCallback_t receiveCallback, void * pUserData, CellularCommInterfaceHandle_t * pCommInterfaceHandle ) @@ -514,7 +310,7 @@ static CellularCommInterfaceError_t prvCommIntfOpen( CellularCommInterfaceReceiv CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; HANDLE hComm = ( HANDLE ) INVALID_HANDLE_VALUE; BOOL Status = TRUE; - cellularCommContext_t * pCellularCommContext = prvGetCellularCommContext(); + cellularCommContext_t * pCellularCommContext = &uxCellularCommContext; DWORD dwRes = 0; if( pCellularCommContext == NULL ) @@ -543,7 +339,7 @@ static CellularCommInterfaceError_t prvCommIntfOpen( CellularCommInterfaceReceiv } /* Comm port is just closed. Wait 1 second and retry. */ - if( ( hComm == ( HANDLE ) INVALID_HANDLE_VALUE ) && ( GetLastError() == 5 ) ) + if( ( hComm == ( HANDLE ) INVALID_HANDLE_VALUE ) && ( GetLastError() == ERROR_ACCESS_DENIED ) ) { vTaskDelay( pdMS_TO_TICKS( 1000UL ) ); hComm = CreateFile( TEXT( CELLULAR_COMM_PATH ), @@ -578,7 +374,7 @@ static CellularCommInterfaceError_t prvCommIntfOpen( CellularCommInterfaceReceiv if( commIntRet == IOT_COMM_INTERFACE_SUCCESS ) { - commIntRet = prvSetupCommSettings( hComm ); + commIntRet = prvSetupCommState( hComm ); } if( commIntRet == IOT_COMM_INTERFACE_SUCCESS ) @@ -592,26 +388,11 @@ static CellularCommInterfaceError_t prvCommIntfOpen( CellularCommInterfaceReceiv } } - /* Create RX event mutex to protect rxEvent. */ - if( commIntRet == IOT_COMM_INTERFACE_SUCCESS ) - { - pvRxEventMutex = CreateMutex( NULL, FALSE, NULL ); - - if( pvRxEventMutex == NULL ) - { - commIntRet = IOT_COMM_INTERFACE_FAILURE; - } - } - if( commIntRet == IOT_COMM_INTERFACE_SUCCESS ) { pCellularCommContext->commReceiveCallback = receiveCallback; - commIntRet = prvSetupCommTaskThread( pCellularCommContext ); - } - if( commIntRet == IOT_COMM_INTERFACE_SUCCESS ) - { - vPortSetInterruptHandler( portINTERRUPT_UART, prvProcessUartInt ); + vPortSetInterruptHandler( appINTERRUPT_UART, prvProcessUartInt ); pCellularCommContext->commReceiveCallbackThread = CreateThread( NULL, 0, prvCellularCommReceiveCBThreadFunc, hComm, 0, NULL ); @@ -653,16 +434,6 @@ static CellularCommInterfaceError_t prvCommIntfOpen( CellularCommInterfaceReceiv } pCellularCommContext->commReceiveCallbackThread = NULL; - - /* Wait for the commTaskThreadStarted exit. */ - ( void ) prvCleanCommTaskThread( pCellularCommContext ); - - /* Clean the rxEvent mutex. */ - if( pvRxEventMutex != NULL ) - { - CloseHandle( pvRxEventMutex ); - pvRxEventMutex = NULL; - } } return commIntRet; @@ -731,16 +502,6 @@ static CellularCommInterfaceError_t prvCommIntfClose( CellularCommInterfaceHandl pCellularCommContext->commReceiveCallbackThread = NULL; - /* Clean the commTaskThread. */ - ( void ) prvCleanCommTaskThread( pCellularCommContext ); - - /* Clean the rxEvent mutex. */ - if( pvRxEventMutex != NULL ) - { - CloseHandle( pvRxEventMutex ); - pvRxEventMutex = NULL; - } - /* clean the data structure. */ pCellularCommContext->commStatus &= ~( CELLULAR_COMM_OPEN_BIT ); } diff --git a/FreeRTOS/Source b/FreeRTOS/Source index 4d4f8d0d50..29b202a41e 160000 --- a/FreeRTOS/Source +++ b/FreeRTOS/Source @@ -1 +1 @@ -Subproject commit 4d4f8d0d50bedc37e1d07c96aded7d2bc20f0d6c +Subproject commit 29b202a41e0e2810272b5765805d9fa4af247736 diff --git a/manifest.yml b/manifest.yml index 931b1b0691..78a8807efd 100644 --- a/manifest.yml +++ b/manifest.yml @@ -5,7 +5,7 @@ license: "MIT" dependencies: - name: "FreeRTOS-Kernel" - version: "4d4f8d0d5" + version: "29b202a41" repository: type: "git" url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"