示例#1
0
/*! \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 ) );
}
示例#2
0
//!
//! This function initializes mutex and navigators.
//!
bool b_fsaccess_init(void)
{
    nav_reset();
#ifdef FREERTOS_USED
    if (xFs_Access == NULL)
    {
        vSemaphoreCreateBinary( xFs_Access );
        if( xFs_Access == NULL )
            return( false );
        else
            return( true );
    }
#endif
    return( true );
}
示例#3
0
//!
//! @brief Synchronize the contents of two drives (limited to files).
//!
//! @param sync_direction   uint8_t: DEVICE_TO_HOST, HOST_TO_DEVICE or FULL_SYNC
//!
//! @return bool: true on success
//!
//! @todo Do recursive directory copy...
//!
bool host_mass_storage_task_sync_drives(uint8_t sync_direction)
{
  Fs_index local_index;
  Fs_index sav_local_index;
  Fs_index usb_index;
  Fs_index sav_usb_index;

  // First, check the host controller is in full operating mode with the
  // B-device attached and enumerated
  if (!Is_host_ready()) return false;

  nav_reset();

  // Try to mount local drive
  nav_drive_set(LUN_ID_AT45DBX_MEM);
  if (!nav_partition_mount()) return false;
  local_index = nav_getindex();
  sav_local_index = nav_getindex();

  // Try to mount first USB device drive
  nav_drive_set(LUN_ID_MEM_USB);
  if (!nav_partition_mount()) return false;
  usb_index = nav_getindex();
  sav_usb_index = nav_getindex();

  // First synchronization: USB/OUT -> Local/IN
  if (sync_direction & DEVICE_TO_HOST)
  {
    if (!host_mass_storage_task_sync_dir(&local_index, DIR_LOCAL_IN_NAME, &usb_index, DIR_USB_OUT_NAME))
      return false;
  }

  // Restore positions
  nav_gotoindex(&sav_local_index);
  local_index = nav_getindex();
  nav_gotoindex(&sav_usb_index);
  usb_index = nav_getindex();
  nav_gotoindex(&local_index);

  // Second synchronization: Local/OUT -> USB/IN
  if (sync_direction & HOST_TO_DEVICE)
  {
    if (!host_mass_storage_task_sync_dir(&usb_index, DIR_USB_IN_NAME, &local_index, DIR_LOCAL_OUT_NAME))
      return false;
  }

  return true;
}
示例#4
0
//! @brief This function initializes the hardware/software resources required for ushell task.
//!
void ushell_task_init(uint32_t pba_hz)
{
  uint8_t u8_i;

  //** Initialize the USART used by uShell with the configured parameters
  static const gpio_map_t SHL_USART_GPIO_MAP =
  {
    {SHL_USART_RX_PIN, SHL_USART_RX_FUNCTION},
    {SHL_USART_TX_PIN, SHL_USART_TX_FUNCTION}
  };
#if (defined __GNUC__)
  set_usart_base((void *)SHL_USART);
  gpio_enable_module(SHL_USART_GPIO_MAP,
                     sizeof(SHL_USART_GPIO_MAP) / sizeof(SHL_USART_GPIO_MAP[0]));
  usart_init(SHL_USART_BAUDRATE);
#elif (defined __ICCAVR32__)
  static const usart_options_t SHL_USART_OPTIONS =
  {
    .baudrate = SHL_USART_BAUDRATE,
    .charlength = 8,
    .paritytype = USART_NO_PARITY,
    .stopbits = USART_1_STOPBIT,
    .channelmode = USART_NORMAL_CHMODE
  };

  extern volatile avr32_usart_t *volatile stdio_usart_base;
  stdio_usart_base = SHL_USART;
  gpio_enable_module(SHL_USART_GPIO_MAP,
                     sizeof(SHL_USART_GPIO_MAP) / sizeof(SHL_USART_GPIO_MAP[0]));
  usart_init_rs232(SHL_USART, &SHL_USART_OPTIONS, pba_hz);
#endif


  //** Configure standard I/O streams as unbuffered.
#if (defined __GNUC__)
  setbuf(stdin, NULL);
#endif
  setbuf(stdout, NULL);

  // Set default state of ushell
  g_b_ushell_task_run = false;
  for( u8_i=0; u8_i<USHELL_HISTORY; u8_i++ ) {
     g_s_cmd_his[u8_i][0] = 0;  // Set end of line for all cmd line history
  }

  fputs(MSG_EXIT, stdout );

  g_u32_ushell_pba_hz = pba_hz;  // Save value to manage a time counter during perform command

#ifdef FREERTOS_USED
  xTaskCreate(ushell_task,
              configTSK_USHELL_NAME,
              configTSK_USHELL_STACK_SIZE,
              NULL,
              configTSK_USHELL_PRIORITY,
              NULL);
#endif  // FREERTOS_USED
}


#ifdef FREERTOS_USED
/*! \brief Entry point of the explorer task management.
 *
 * This function performs uShell decoding to access file-system functions.
 *
 * \param pvParameters Unused.
 */
void ushell_task(void *pvParameters)
#else
/*! \brief Entry point of the explorer task management.
 *
 * This function performs uShell decoding to access file-system functions.
 */
void ushell_task(void)
#endif
{

#ifdef FREERTOS_USED
   //** Inifinite loop for RTOS because it is a RTOS task
   portTickType xLastWakeTime;

   xLastWakeTime = xTaskGetTickCount();
   while (true)
   {
      vTaskDelayUntil(&xLastWakeTime, configTSK_USHELL_PERIOD);
#else
   //** No loop with the basic scheduler
   {
#endif  // FREERTOS_USED


   //** Check the USB mode and authorize/unauthorize ushell
   if(!g_b_ushell_task_run)
   {
      if( Is_usb_id_device() )
#ifdef FREERTOS_USED
         continue;   // Continue in the RTOS task
#else
         return;     // Exit of the task scheduled
#endif
      g_b_ushell_task_run = true;
      // Display shell startup
      fputs(MSG_WELCOME, stdout);
      ushell_cmd_nb_drive();
      fputs(MSG_PROMPT, stdout);

      // Reset the embedded FS on ushell navigator and on first drive
      nav_reset();
      nav_select( FS_NAV_ID_USHELL_CMD );
      nav_drive_set( 0 );
   }else{
      if( Is_usb_id_device() )
      {
         g_b_ushell_task_run = false;
         fputs(MSG_EXIT, stdout );
         nav_exit();
#ifdef FREERTOS_USED
         continue;   // Continue in the RTOS task
#else
         return;     // Exit of the task scheduled
#endif
      }
   }

   //** Scan shell command
   if( !ushell_cmd_scan() )
#ifdef FREERTOS_USED
      continue;   // Continue in the RTOS task
#else
      return;     // Exit of the task scheduled
#endif

   //** Command ready then decode and execute this one
   switch( ushell_cmd_decode() )
   {
      // Displays number of  drives
      case CMD_NB_DRIVE:
      ushell_cmd_nb_drive();
      break;

      // Displays free space information for all connected drives
      case CMD_DF:
      ushell_cmd_free_space();
      break;

      // Formats disk
      case CMD_FORMAT:
      ushell_cmd_format();
      break;

      // Mounts a drive (e.g. "b:")
      case CMD_MOUNT:
      ushell_cmd_mount();
      break;

      // Displays the space information for current drive
      case CMD_SPACE:
      ushell_cmd_space();
      break;

      // Lists the files present in current directory (e.g. "ls")
      case CMD_LS:
      ushell_cmd_ls(false);
      break;
      case CMD_LS_MORE:
      ushell_cmd_ls(true);
      break;

      // Enters in a directory (e.g. "cd folder_toto")
      case CMD_CD:
      ushell_cmd_cd();
      break;

      // Enters in parent directory ("cd..")
      case CMD_UP:
      ushell_cmd_gotoparent();
      break;

      // Displays a text file
      case CMD_CAT:
      ushell_cmd_cat(false);
      break;
      case CMD_CAT_MORE:
      ushell_cmd_cat(true);
      break;

      // Displays the help
      case CMD_HELP:
      ushell_cmd_help();
      break;

      // Creates directory
      case CMD_MKDIR:
      ushell_cmd_mkdir();
      break;

      // Creates file
      case CMD_TOUCH:
      ushell_cmd_touch();
      break;

      // Deletes files or directories
      case CMD_RM:
      ushell_cmd_rm();
      break;

      // Appends char to selected file
      case CMD_APPEND:
      ushell_cmd_append_file();
      break;

      // Index routines (= specific shortcut from ATMEL FileSystem)
      case CMD_SET_ID:
      g_mark_index = nav_getindex();
      break;
      case CMD_GOTO_ID:
      nav_gotoindex( &g_mark_index );
      break;

      // Copies file to other location
      case CMD_CP:
      ushell_cmd_copy();
      break;

      // Renames file
      case CMD_MV:
      ushell_cmd_rename();
      break;

      // Synchronize folders
      case CMD_SYNC:
      ushell_cmd_sync();
      break;

      case CMD_PERFORM:
      ushell_cmd_perform();
      break;

      // USB commands
#if USB_HOST_FEATURE == true
      case CMD_LS_USB:
      ushell_cmdusb_ls();
      break;
      case CMD_USB_SUSPEND:
      ushell_cmdusb_suspend();
      break;
      case CMD_USB_RESUME:
      ushell_cmdusb_resume();
      break;
#endif

      case CMD_NONE:
      break;

      // Unknown command
      default:
      fputs(MSG_ER_CMD_NOT_FOUND, stdout);
      break;
   }

   fputs(MSG_PROMPT, stdout);

   }
}


//! @brief Get the full command line to be interpreted.
//!
//! @return true, if a command is ready
//!
bool ushell_cmd_scan(void)
{
   int c_key;

   // Something new of the UART ?
   if (usart_read_char(SHL_USART, &c_key) != USART_SUCCESS)
   {
      usart_reset_status(SHL_USART);
      return false;
   }

   if( 0 != g_u8_escape_sequence )
   {
      //** Decode escape sequence
      if( 1 == g_u8_escape_sequence )
      {
         if( 0x5B != c_key )
         {
            g_u8_escape_sequence=0;
            return false;  // Escape sequence cancel
         }
         g_u8_escape_sequence=2;
      }
      else
      {
         // Decode value of the sequence
         switch (c_key)
         {
/*
Note: OVERRUN error on USART with an RTOS and USART without interrupt management
If you want support "Escape sequence", then you have to implement USART interrupt management
            case 0x41:     // UP command
            ushell_clean_cmd_line();
            ushell_history_up();
            ushell_history_display();
            break;
            case 0x42:     // DOWN command
            ushell_clean_cmd_line();
            ushell_history_down();
            ushell_history_display();
            break;
*/
            default:       // Ignore other command
            break;
         }
         g_u8_escape_sequence=0; // End of Escape sequence
      }
      return false;
   }

   //** Normal sequence
   switch (c_key)
   {
      //** Command validation
      case ASCII_CR:
      putchar(ASCII_CR);         // Echo
      putchar(ASCII_LF);         // Add new line flag
      g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size]=0;  // Add NULL terminator at the end of command line
      return true;

      //** Enter in escape sequence
      case ASCII_ESCAPE:
      g_u8_escape_sequence=1;
      break;

      //** backspace
      case ASCII_BKSPACE:
      if(g_u8_cmd_size>0)        // Beginning of line ?
      {
         // Remove the last character on terminal
         putchar(ASCII_BKSPACE); // Send a backspace to go in previous character
         putchar(' ');           // Send a space to erase previous character
         putchar(ASCII_BKSPACE); // Send a backspace to go in new end position (=previous character position)
         // Remove the last character on cmd line buffer
         g_u8_cmd_size--;
      }
      break;

      // History management
      case '!':
      ushell_clean_cmd_line();
      ushell_history_up();
      ushell_history_display();
      break;
      case '$':
      ushell_clean_cmd_line();
      ushell_history_down();
      ushell_history_display();
      break;

      //** Other char
      default:
      if( (0x1F<c_key) && (c_key<0x7F) && (USHELL_SIZE_CMD_LINE!=g_u8_cmd_size) )
      {
         // Accept char
         putchar(c_key);                                          // Echo
         g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size++] = c_key;  // append to cmd line
      }
      break;
   }
   return false;
}
示例#5
0
/*!
 *  \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 );
}
示例#6
0
文件: main.c 项目: scarecrowli/asf
/*! \brief Main function. Execution starts here.
 */
int main(void)
{
	sysclk_init();
	irq_initialize_vectors();
	cpu_irq_enable();

	// Initialize the sleep manager
	sleepmgr_init();

	board_init();
	ui_init();

	// Reset File System
	nav_reset();

	// Start USB host stack
	uhc_start();

	// The USB management is entirely managed by interrupts.
	// As a consequence, the user application does only have :
	// - to play with the power modes
	// - to create a file on each new LUN connected
	while (true) {
		sleepmgr_enter_sleep();
		if (main_usb_sof_counter > 2000) {
			main_usb_sof_counter = 0;
			uint8_t lun;

			for (lun = 0; (lun < uhi_msc_mem_get_lun()) && (lun < 8); lun++) {
				// Mount drive
				nav_drive_set(lun);
				if (!nav_partition_mount()) {
					if (fs_g_status == FS_ERR_HW_NO_PRESENT) {
						// The test can not be done, if LUN is not present
						lun_state &= ~(1 << lun); // LUN test reseted
						continue;
					}
					lun_state |= (1 << lun); // LUN test is done.
					ui_test_finish(false); // Test fail
					continue;
				}

				// Check if LUN has been already tested
				if (lun_state & (1 << lun)) {
					continue;
				}

				// Create a test file on the disk
				if (!nav_file_create((FS_STRING) "uhi_msc_test.txt")) {
					if (fs_g_status != FS_ERR_FILE_EXIST) {
						if (fs_g_status == FS_LUN_WP) {
							// Test can be done only on no write protected device
							continue;
						}
						lun_state |= (1 << lun); // LUN test is done.
						ui_test_finish(false); // Test fail
						continue;
					}
				}
				if (!file_open(FOPEN_MODE_APPEND)) {
					if (fs_g_status == FS_LUN_WP) {
						// Test can be done only on no write protected device
						continue;
					}
					lun_state |= (1 << lun); // LUN test is done.
					ui_test_finish(false); // Test fail
					continue;
				}
				if (!file_write_buf((uint8_t*)MSG_TEST, sizeof(MSG_TEST))) {
					lun_state |= (1 << lun); // LUN test is done.
					ui_test_finish(false); // Test fail
					continue;
				}
				file_close();
				lun_state |= (1 << lun); // LUN test is done.
				ui_test_finish(true); // Test pass
			}
			if ((lun == 0) || (lun_state == 0)) {
				ui_test_flag_reset();
			}
		}
	}
}