/*! * \brief Print a string directly to the output stream of a module. * * \param xModId Input. The module associated with the target output stream. * \param pcStringToDisplay Input. The string to print. * */ void v_shell_Print_String_To_Requester_Stream( eModId xModId, const signed portCHAR *pcStringToDisplay ) { switch( xModId ) { case SYS_MODID_COM1SHELL: vcom1shell_PrintMsg(pcStringToDisplay); break; case SYS_MODID_USB: TRACE_COM2((char *)"Unimplemented stream redirection (from fscmds to USB)"); break; default: // SHOULD NEVER HAPPEN TRACE_COM2((char *) "Unexpected stream redirection"); break; } }
/*! \brief Release a system mutex. * * \param xSemaphore A handle to the semaphore being released. * * \return pdTRUE if the semaphore was released. pdFALSE if an error occurred. */ portBASE_TYPE x_supervisor_SemaphoreGive( xSemaphoreHandle xSemaphore ) { #ifdef USB_ENABLE #if USB_DEVICE_FEATURE == true if( ( 0 != u8IsMaintenanceRequired ) && ( false == bOutOfMaintenance ) ) { // If we have to enter in the maintenance mode, do not release the mutex. // => this mutex is now the property of the supervisor. u8IsMaintenanceRequired++; // If all mutexes have been acquired, switch to maintenance mode. if( ( SUPERVISOR_MAINTENANCE_NBMUTEX_TOTAKE +1 ) == u8IsMaintenanceRequired ) { fat_cache_flush(); // Flush the FAT cache. nav_reset(); // Reset all file system navigators. We will mount // the com1shell default drive when we'll leave the // maintenance mode. // Switch to maintenance mode. xSemaphoreGive( xUSBMutex ); // If the USB clock is frozen, unfreeze it so that we can write in the // USB registers. The USB clock is frozen if a "Device Suspend" event // occurred (no more USB activity detected) (cf. usb_general_interrupt()). if(true == Is_usb_clock_frozen()) { Usb_unfreeze_clock(); } // If it is not already detached, physically detach the USB device. if(false == Is_usb_detached()) { Usb_detach(); } vTaskDelay(500); // Wait 500ms Usb_attach(); // Reconnect the device. bIsInMaintenance = true; u8IsMaintenanceRequired = 0; TRACE_COM2( "Entering maintenance mode"); #ifdef MMILCD_ENABLE vMMI_SetUserMenuMode( eUserMenuWaitHost, pdTRUE ); #endif } return( pdTRUE ); } else #endif #endif return( xSemaphoreGive( xSemaphore ) ); }
/*! * \brief Release the semaphores and change the MMI user menu mode. * */ static void prv_v_common_leave_UsbDevice_mode( void ) { // Take the USB mutex. xSemaphoreGive( xUSBMutex ); // Release it in case the USB module didn't // Then take it back. // NOTE: we have to use xSemaphoreTake() rather than x_supervisor_xSemaphoreTake() // or we'll get a rejection(cf x_supervisor_xSemaphoreTake() implementation). if( pdFALSE == xSemaphoreTake( xUSBMutex, 0 ) ) { // SHOULD NEVER HAPPEN!!! TRACE_COM2( "Unexpected SemaphoreTake( xUSBMutex ) failure!!!" ); } // Release all system mutexes except the xUSBMutex. xSemaphoreGive( xLOGMutex ); xSemaphoreGive( xSHELLFSMutex ); xSemaphoreGive( xCFGMutex ); #if NW_INTEGRATED_IN_CONTROL_PANEL xSemaphoreGive( xWEBMutex ); #endif #ifdef MMILCD_ENABLE vMMI_SetUserMenuMode(eUserMenuIdle, pdTRUE); #endif }
/*! \brief WEB server main task * check for incoming connection and process it * */ portTASK_FUNCTION( vBasicWEBServer, pvParameters ) { struct netconn *pxHTTPListener, *pxNewConnection; portCHAR token[6]; portSHORT TaskIdx; portLONG err_count; /* initialize current nb connection */ sCurrentNbHTTPConn = 0; vSemaphoreCreateBinary( xMutexNbHTTPConn ); x_default_page_len = strlen( pcDefaultPage ); /* HTTP configuration. */ // Get the xCFGMutex. if( pdFALSE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) ) { // Failed to get the CFG mutex, use the default HTTP config. webHttpPort = webHTTP_PORT; } // Mutex has been taken else { // get the field value for port number if (config_file_get_value(HTTP_CONFIG_FILE, "port" , token) >= 0) { sscanf(token, "%u", &webHttpPort); } // if it does not exist, use the default value else { webHttpPort = webHTTP_PORT; } // Release the xCFGMutex. x_supervisor_SemaphoreGive( xCFGMutex ); } // Create a new tcp connection handle pxHTTPListener = netconn_new( NETCONN_TCP ); netconn_bind(pxHTTPListener, NULL, webHttpPort ); netconn_listen( pxHTTPListener ); // Loop forever for( ;; ) { #if ( (LWIP_VERSION) == ((1U << 24) | (3U << 16) | (2U << 8) | (LWIP_VERSION_RC)) ) /* Wait for a first connection. */ pxNewConnection = netconn_accept(pxHTTPListener); #else while(netconn_accept(pxHTTPListener, &pxNewConnection) != ERR_OK) { vTaskDelay( webSHORT_DELAY ); } #endif if(pxNewConnection != NULL) { /* read the nb of connection, no need to use Mutex */ while( webHTTP_NB_CONN == sCurrentNbHTTPConn ) { vTaskDelay( webSHORT_DELAY ); } // Take the xWEBMutex if there are no active connections. if( 0 == sCurrentNbHTTPConn ) { if( pdFALSE == x_supervisor_SemaphoreTake( xWEBMutex, 0 ) ) { prvweb_SendErrorPage( pxNewConnection, 503, "", "AVR32 UC3 Web server under maintenance." ); // Close the connection. vTaskDelay( 50 ); err_count = 4; while( netconn_close( pxNewConnection ) != ERR_OK ) { if (--err_count == 0) break; vTaskDelay( webSHORT_DELAY ); } err_count = 4; while( netconn_delete( pxNewConnection ) != ERR_OK ) { if (--err_count == 0) break; vTaskDelay( webSHORT_DELAY ); } continue; } } // Find an available spot in the tTaskHandle[] array. // We're sure to find one because sCurrentNbHTTPConn < webHTTP_NB_CONN. TaskIdx = 0; while( NULL != tTaskHandle[TaskIdx] ) TaskIdx++; while( xSemaphoreTake(xMutexNbHTTPConn , portMAX_DELAY ) != pdTRUE ); sCurrentNbHTTPConn++; // Release the mutex. xSemaphoreGive( xMutexNbHTTPConn ); // TRACE_COM2( "nb http conn:%d",sCurrentNbHTTPConn ); if( xTaskCreate( prvweb_ProcessSingleConnection, ( signed portCHAR * )"WCONN", webHTTP_CONNECTION_STACK_SIZE, pxNewConnection, webHTTP_CONNECTION_PRIORITY, &tTaskHandle[TaskIdx] ) != pdPASS) { TRACE_COM2( "xTaskCreate() alloc error" ); /* delete connection */ err_count = 4; while( netconn_close( pxNewConnection ) != ERR_OK ) { if (--err_count == 0) break; vTaskDelay( webSHORT_DELAY ); } err_count = 4; while( netconn_delete( pxNewConnection ) != ERR_OK ) { if (--err_count == 0) break; vTaskDelay( webSHORT_DELAY ); } while( xSemaphoreTake(xMutexNbHTTPConn , portMAX_DELAY ) != pdTRUE ); sCurrentNbHTTPConn--; // Release the xWEBMutex if there are no active connections. if( 0 == sCurrentNbHTTPConn ) { x_supervisor_SemaphoreGive( xWEBMutex ); } // Release the mutex. xSemaphoreGive( xMutexNbHTTPConn ); }// end if task not created }// end if new connection }// end infinite loop }
/*! * \brief The switch-to-maintenance-mode command: initiate the process to \n * switch to maintenance mode. * Format: maintain * * \note This function must be of the type pfShellCmd defined by the shell module. * * \param xModId Input. The module that is calling this function. * \param FsNavId Ignored. * \param ac Ignored. * \param av Ignored. * \param ppcStringReply Input/Output. The response string. * If Input is NULL, no response string will be output. * Else a malloc for the response string is performed here; * the caller must free this string. * * \return the status of the command execution. */ eExecStatus e_supervisor_switch_to_maintenance_mode( eModId xModId, signed short FsNavId, int ac, signed portCHAR *av[], signed portCHAR **ppcStringReply ) { if( NULL != ppcStringReply ) *ppcStringReply = NULL; #ifdef USB_ENABLE #if USB_DEVICE_FEATURE == true if( ( false == bIsInMaintenance ) && ( 0 == u8IsMaintenanceRequired ) ) { // We're not in maintenance mode. // Initiate the process of switching to maintenance mode. if( 0 == u8IsMaintenanceRequired ) u8IsMaintenanceRequired++; // Take all maintenance mutex except the USB mutex. if( true == x_supervisor_SemaphoreTake( xLOGMutex, 0 ) ) u8IsMaintenanceRequired++; #if NW_INTEGRATED_IN_CONTROL_PANEL if( true == x_supervisor_SemaphoreTake( xWEBMutex, 0 ) ) u8IsMaintenanceRequired++; #endif if( true == x_supervisor_SemaphoreTake( xSHELLFSMutex, 0 ) ) u8IsMaintenanceRequired++; if( true == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) ) u8IsMaintenanceRequired++; // If all mutexes have been acquired, switch to maintenance mode. if( ( SUPERVISOR_MAINTENANCE_NBMUTEX_TOTAKE +1 ) == u8IsMaintenanceRequired ) { fat_cache_flush(); // flush the FAT cache. nav_reset(); // Reset all file system navigators. We will mount // the com1shell default drive when we'll leave the // maintenance mode. // Switch to maintenance mode. xSemaphoreGive( xUSBMutex ); // If the USB clock is frozen, unfreeze it so that we can write in the // USB registers. if(true == Is_usb_clock_frozen()) { Usb_unfreeze_clock(); } // If it is not akready detached, physically detach the USB device. if(false == Is_usb_detached()) { Usb_detach(); } vTaskDelay(500); // Wait 500ms Usb_attach(); // Reconnect the device. bIsInMaintenance = true; u8IsMaintenanceRequired = 0; TRACE_COM2( "Entering maintenance mode"); #ifdef MMILCD_ENABLE vMMI_SetUserMenuMode( eUserMenuWaitHost, pdTRUE ); #endif } // ELSE: we'll switch to maintenance mode in x_supervisor_SemaphoreGive() // (when the mutex(es) that we couldn't get will be released). } else { NAKED_TRACE_COM2( "Won't go to maintenance mode:"CRLF"bIsInMaintenance=%d u8CurrentUsbRole=%d u8IsMaintenanceRequired=%d", bIsInMaintenance, u8CurrentUsbRole, u8IsMaintenanceRequired ); } #endif #endif return( SHELL_EXECSTATUS_OK ); }