Update cellular comm interface to generate interrupt from windows thread ()

* Make use of vPortGenerateSimulatedInterruptFromWindowsThread to generate interrupt from windows thread
pull/1224/head
chinglee-iot committed by GitHub
parent a3f42a78e7
commit 6518cb153d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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 );
}

@ -1 +1 @@
Subproject commit 4d4f8d0d50bedc37e1d07c96aded7d2bc20f0d6c
Subproject commit 29b202a41e0e2810272b5765805d9fa4af247736

@ -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"

Loading…
Cancel
Save