- Main Page
- Modules
- Data Structures
- Files
- Related Pages

# ushell_task.c

Go to the documentation of this file.

    00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
    00013
    00014 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
    00015  *
    00016  * Redistribution and use in source and binary forms, with or without
    00017  * modification, are permitted provided that the following conditions are met:
    00018  *
    00019  * 1. Redistributions of source code must retain the above copyright notice,
    00020  * this list of conditions and the following disclaimer.
    00021  *
    00022  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00023  * this list of conditions and the following disclaimer in the documentation
    00024  * and/or other materials provided with the distribution.
    00025  *
    00026  * 3. The name of ATMEL may not be used to endorse or promote products derived
    00027  * from this software without specific prior written permission.
    00028  *
    00029  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
    00030  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00031  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
    00032  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
    00033  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00034  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00035  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00036  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00037  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    00038  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00039  */
    00040
    00041 //_____  I N C L U D E S ___________________________________________________
    00042
    00043 #include "config.h"
    00044 #include "ushell_task.h"
    00045 #include <stdio.h>
    00046 #include "lib_mem/df/df_mem.h"
    00047 #include "lib_mcu/wdt/wdt_drv.h"
    00048 #include "lib_mcu/uart/uart_lib.h"
    00049 #include "lib_mcu/usb/usb_drv.h"
    00050 #include "lib_mcu/timer/timer16_drv.h"
    00051 #if (TARGET_BOARD==SPIDER)
    00052 #include "lib_board/spider/spider_drv.h"
    00053 #include "lib_board/intermcu_spi/intermcu_spi_drv.h"
    00054 #endif
    00055 #include "modules/file_system/fat.h"
    00056 #include "modules/file_system/fs_com.h"
    00057 #include "modules/file_system/navigation.h"
    00058 #include "modules/file_system/file.h"
    00059 #include "modules/file_system/nav_utils.h"
    00060 #include "modules/usb/device_chap9/usb_standard_request.h"
    00061 #include "modules/control_access/ctrl_access.h"
    00062
    00063 #ifndef USHELL_RF
    00064    #define USHELL_RF DISABLE
    00065    #define ushell_putchar  uart_putchar
    00066    #define ushell_test_hit uart_test_hit
    00067    #define ushell_get_char uart_getchar
    00068 #endif
    00069
    00070 #if (USHELL_RF==ENABLE)
    00071    #include "rf_task.h"
    00072    void rf_task_init(void);
    00073 #endif
    00074
    00075
    00076 #if (USHELL_DFU==ENABLE)
    00077 #include "modules/usb/host_chap9/usb_host_task.h"
    00078 #include "modules/usb/host_chap9/usb_host_enum.h"
    00079 #include "host_dfu_task.h"
    00080 #endif
    00081
    00082 #if (USHELL_USB==ENABLE)
    00083 #include "conf_usb.h"
    00084 #include "modules/usb/host_chap9/usb_host_task.h"
    00085 #include "modules/usb/host_chap9/usb_host_enum.h"
    00086 #include "modules/usb/device_chap9/usb_standard_request.h"
    00087 #  if(USB_HUB_SUPPORT==ENABLE)
    00088 #include "modules/usb/host_chap9/usb_host_hub.h"
    00089 #  endif
    00090 #endif
    00091
    00092 #if (USHELL_HID==ENABLE)
    00093 #include "host_hid_task.h"
    00094 #endif
    00095
    00096
    00097 //_____ M A C R O S ________________________________________________________
    00098
    00099 #ifndef USHELL_DFU
    00100 #warning USHELL_DFU is not defined as ENABLE or DISABLE, using DISABLE by default...
    00101 #define  USHELL_DFU DISABLE
    00102 #endif
    00103
    00104 #ifndef USHELL_USB
    00105 #warning USHELL_USB is not defined as ENABLE or DISABLE, using DISABLE by default...
    00106 #define  USHELL_USB DISABLE
    00107 #endif
    00108
    00109 #ifndef USHELL_HID
    00110 #warning USHELL_HID is not defined as ENABLE or DISABLE, using DISABLE by default...
    00111 #define  USHELL_HID DISABLE
    00112 #endif
    00113
    00114 #ifndef USHELL_HISTORY
    00115 #warning USHELL_HISTORY value is not defined using 10 as default value
    00116 #define  USHELL_HISTORY 10
    00117 #endif
    00118
    00119 #ifndef USHELL_NB_LINE
    00120 #warning USHELL_NB_LINE value is not defined using 20 as default value
    00121 #define USHELL_NB_LINE  20
    00122 #endif
    00123
    00124 #ifndef USHELL_NB_COL
    00125 #warning USHELL_NB_COL value is not defined using 80 as default value
    00126 #define USHELL_NB_COL  80
    00127 #endif
    00128
    00129
    00130 #define USHELL_SIZE_CMD_LINE  70
    00131 #define USHELL_MAX_NB_ARG     2
    00132
    00133 //_____ D E C L A R A T I O N S ____________________________________________
    00134
    00135
    00136 // Manage task
    00137 static Bool g_b_ushell_task_run = FALSE;
    00138
    00139 // To manage command line
    00140 static U8   g_u8_escape_sequence=0;
    00141 static U8   g_u8_cmd_size=0;
    00142 static U8   g_u8_history_pos=0;
    00143 static U8   g_u8_history_pos_search=0;
    00144 static char g_s_cmd_his[USHELL_HISTORY][USHELL_SIZE_CMD_LINE];
    00145 static char g_s_cmd[USHELL_SIZE_CMD_LINE];
    00146 static char g_s_arg[USHELL_MAX_NB_ARG][USHELL_SIZE_CMD_LINE];
    00147
    00148 // To manage a file system shortcut
    00149 static Fs_index g_mark_index;
    00150
    00151
    00152 //* To store all shell messages
    00153 U8 code str_cd[]=STR_CD;
    00154 U8 code str_mount[]=STR_MOUNT;
    00155 U8 code str_cp[]=STR_CP;
    00156 U8 code str_ls[]=STR_LS;
    00157 U8 code str_ls_more[]=STR_LS_MORE;
    00158 U8 code str_rm[]=STR_RM;
    00159 U8 code str_df[]=STR_DF;
    00160 U8 code str_space[]=STR_SPACE;
    00161 U8 code str_mkdir[]=STR_MKDIR;
    00162 U8 code str_touch[]=STR_TOUCH;
    00163 U8 code str_append[]=STR_APPEND;
    00164 U8 code str_cat[]=STR_CAT;
    00165 U8 code str_cat_more[]=STR_CAT_MORE;
    00166 U8 code str_up[]=STR_UP;
    00167 U8 code str_disk[]=STR_DISK;
    00168 U8 code str_mark[]=STR_MARK;
    00169 U8 code str_goto[]=STR_GOTO;
    00170 U8 code str_mv[]=STR_MV;
    00171 U8 code str_help[]=STR_HELP;
    00172 U8 code str_format[]=STR_FORMAT;
    00173 U8 code str_sync[]=STR_SYNC;
    00174 U8 code str_perform[]=STR_PERFORM;
    00175 U8 code str_reboot[]=STR_REBOOT;
    00176 #if (USHELL_USB==ENABLE)
    00177 U8 code str_ls_usb[]=STR_LS_USB;
    00178 U8 code str_usb_suspend[]=STR_USB_SUSPEND;
    00179 U8 code str_usb_resume[]=STR_USB_RESUME;
    00180 U8 code str_usb_force_enum[]=STR_USB_FORCE_ENUM;
    00181 #endif
    00182 #if (USHELL_DFU==ENABLE)
    00183 U8 code str_dfu_erase[]=STR_DFU_ERASE;
    00184 U8 code str_dfu_load[]=STR_DFU_LOAD;
    00185 U8 code str_dfu_start[]=STR_DFU_START;
    00186 #endif
    00187 #if (USHELL_HID==ENABLE)
    00188 U8 code str_hid_enter_dfu[]=STR_HID_ENTER_DFU;
    00189 U8 code str_hid_get_info[]=STR_HID_GET_INFO;
    00190 #endif
    00191 U8 code msg_paste_fail[]=MSG_ER_PASTE;
    00192 U8 code msg_prompt[]=MSG_PROMPT;
    00193 U8 code msg_welcome[]=MSG_WELCOME;
    00194 U8 code msg_exit[]=MSG_EXIT;
    00195 U8 code msg_er_mount[]=MSG_ER_MOUNT;
    00196 U8 code msg_er_drive[]=MSG_ER_DRIVE;
    00197 U8 code msg_er_rm[]=MSG_ER_RM;
    00198 U8 code msg_er_unknown_file[]=MSG_ER_UNKNOWN_FILE;
    00199 U8 code msg_er_cmd_not_found[]=MSG_ER_CMD_NOT_FOUND;
    00200 U8 code msg_er_format[]=MSG_ER_FORMAT;
    00201 U8 code msg_append_welcome[]=MSG_APPEND_WELCOME;
    00202 U8 code msg_help[]=MSG_HELP;
    00203 U8 code msg_no_device[]=MSG_NO_DEVICE;
    00204 U8 code msg_ok[]=MSG_OK;
    00205 U8 code msg_ko[]=MSG_KO;
    00206 #if (USHELL_USB==ENABLE)
    00207 U8 code msg_remote_wake_up_ok[]=MSG_REMOTE_WAKEUP_OK;
    00208 U8 code msg_remote_wake_up_ko[]=MSG_REMOTE_WAKEUP_KO;
    00209 U8 code msg_device_self_powered[]=MSG_SELF_POWERED;
    00210 U8 code msg_device_bus_powered[]=MSG_BUS_POWERED;
    00211 U8 code msg_usb_suspended[]=MSG_USB_SUSPENDED;
    00212 U8 code msg_device_full_speed[]=MSG_DEVICE_FULL_SPEED;
    00213 U8 code msg_device_low_speed[]=MSG_DEVICE_LOW_SPEED;
    00214 #endif
    00215
    00216
    00217 // Internal sub routines
    00218 Bool  ushell_cmd_scan         ( void );
    00219 U8    ushell_cmd_decode       ( void );
    00220 void  ushell_clean_cmd_line   ( void );
    00221 void  ushell_history_up       ( void );
    00222 void  ushell_history_down     ( void );
    00223 void  ushell_history_display  ( void );
    00224 #ifdef __GNUC__
    00225    U8    mystrncmp      (char *str1,U8 *str2,U8 i);
    00226    void  print_msg      (U8 *str);
    00227 #else
    00228    U8    mystrncmp      (char *str1,U8 code *str2,U8 i);
    00229    void  print_msg      (U8 code *str);
    00230 #endif
    00231 Bool  ushell_more_wait        ( void );
    00232 // Internal sub routines for file system commands
    00233 void  ushell_cmd_nb_drive     ( void );
    00234 void  ushell_cmd_free_space   ( void );
    00235 void  ushell_cmd_format       ( void );
    00236 void  ushell_cmd_mount        ( void );
    00237 void  ushell_cmd_space        ( void );
    00238 void  ushell_cmd_ls           ( Bool b_more );
    00239 void  ushell_cmd_cd           ( void );
    00240 void  ushell_cmd_gotoparent   ( void );
    00241 void  ushell_cmd_cat          ( Bool b_more);
    00242 void  ushell_cmd_help         ( void );
    00243 void  ushell_cmd_mkdir        ( void );
    00244 void  ushell_cmd_touch        ( void );
    00245 void  ushell_cmd_rm           ( void );
    00246 void  ushell_cmd_append_file  ( void );
    00247 void  ushell_cmd_copy         ( void );
    00248 void  ushell_cmd_rename       ( void );
    00249 void  ushell_cmd_reboot       ( void );
    00250 Bool  ushell_cmd_sync         ( void );
    00251 void  ushell_cmd_perform      ( void );
    00252 void  ushell_path_valid_syntac( char *path );
    00253 // Internal sub routines for USB commands
    00254 void  ushell_cmdusb_ls        ( void );
    00255 void  ushell_cmdusb_suspend   ( void );
    00256 void  ushell_cmdusb_resume    ( void );
    00257 void  ushell_cmdusb_force_enum( void );
    00258 // Internal sub routines for USB DFU commands
    00259 void  ushell_cmddfu_erase     ( void );
    00260 void  ushell_cmddfu_load      ( void );
    00261 void  ushell_cmddfu_start     ( void );
    00262 // Internal sub routines for USB HID commands
    00263 void  ushell_cmdhid_enter_dfu ( void );
    00264 void  ushell_cmdhid_getinfo   ( void );
    00265
    00266
    00267
    00270 void ushell_task_init(void)
    00271 {
    00272    U8 u8_i;
    00273 #if (USHELL_RF==ENABLE)
    00274    rf_task_init();
    00275 #else
    00276    uart_init();
    00277 #endif
    00278
    00279 #ifdef __GNUC__
    00280    fdevopen((int (*)(char, FILE*))(ushell_putchar),(int (*)(FILE*))ushell_get_char); //for printf redirection
    00281 #endif
    00282    g_b_ushell_task_run = FALSE;
    00283    for( u8_i=0; u8_i<USHELL_HISTORY; u8_i++ ) {
    00284       g_s_cmd_his[u8_i][0] = 0;  // Set end of line for all cmd line history
    00285    }
    00286
    00287 }
    00288
    00289
    00294 void ushell_task(void)
    00295 {
    00296    //** Check the USB mode and autorize/unautorize ushell
    00297    if(!g_b_ushell_task_run)
    00298    {
    00299       if( Is_usb_id_device() )
    00300          return;
    00301       g_b_ushell_task_run = TRUE;
    00302       print_msg((U8 code *)msg_welcome);
    00303       ushell_cmd_nb_drive();
    00304       print_msg((U8 code *)msg_prompt);
    00305       // Reset the embedded FS on ushell navigator and on first drive
    00306       nav_reset();
    00307       nav_select( FS_NAV_ID_USHELL_CMD );
    00308    }else{
    00309       if( Is_usb_id_device() )
    00310       {
    00311          g_b_ushell_task_run = FALSE;
    00312          print_msg((U8 code *)msg_exit);
    00313          nav_exit();
    00314          return;
    00315       }
    00316    }
    00317
    00318    if( !ushell_cmd_scan() )
    00319       return;
    00320
    00321    //** Command ready then decode and execute this one
    00322    switch( ushell_cmd_decode() )
    00323    {
    00324       // Displays number of  drives
    00325       case CMD_NB_DRIVE:
    00326       ushell_cmd_nb_drive();
    00327       break;
    00328
    00329       // Displays free space information for all connected drives
    00330       case CMD_DF:
    00331       ushell_cmd_free_space();
    00332       break;
    00333
    00334       // Formats disk
    00335       case CMD_FORMAT:
    00336       ushell_cmd_format();
    00337       break;
    00338
    00339       // Mounts a drive (e.g. "b:")
    00340       case CMD_MOUNT:
    00341       ushell_cmd_mount();
    00342       break;
    00343
    00344       // Displays the space information for current drive
    00345       case CMD_SPACE:
    00346       ushell_cmd_space();
    00347       break;
    00348
    00349       // Lists the files present in current directory (e.g. "ls")
    00350       case CMD_LS:
    00351       ushell_cmd_ls(FALSE);
    00352       break;
    00353       case CMD_LS_MORE:
    00354       ushell_cmd_ls(TRUE);
    00355       break;
    00356
    00357       // Enters in a directory (e.g. "cd folder_toto")
    00358       case CMD_CD:
    00359       ushell_cmd_cd();
    00360       break;
    00361
    00362       // Enters in parent directory ("cd..")
    00363       case CMD_UP:
    00364       ushell_cmd_gotoparent();
    00365       break;
    00366
    00367       // Displays a text file
    00368       case CMD_CAT:
    00369       ushell_cmd_cat(FALSE);
    00370       break;
    00371       case CMD_CAT_MORE:
    00372       ushell_cmd_cat(TRUE);
    00373       break;
    00374
    00375       // Displays the help
    00376       case CMD_HELP:
    00377       ushell_cmd_help();
    00378       break;
    00379
    00380       // Creates directory
    00381       case CMD_MKDIR:
    00382       ushell_cmd_mkdir();
    00383       break;
    00384
    00385       // Creates file
    00386       case CMD_TOUCH:
    00387       ushell_cmd_touch();
    00388       break;
    00389
    00390       // Deletes files or directories
    00391       case CMD_RM:
    00392       ushell_cmd_rm();
    00393       break;
    00394
    00395       // Appends char to selected file
    00396       case CMD_APPEND:
    00397       ushell_cmd_append_file();
    00398       break;
    00399
    00400       // Index routines (= specific shortcut from ATMEL FileSystem)
    00401       case CMD_SET_ID:
    00402       g_mark_index = nav_getindex();
    00403       break;
    00404       case CMD_GOTO_ID:
    00405       nav_gotoindex( &g_mark_index );
    00406       break;
    00407
    00408       // Copys file to other location
    00409       case CMD_CP:
    00410       ushell_cmd_copy();
    00411       break;
    00412
    00413       // Renames file
    00414       case CMD_MV:
    00415       ushell_cmd_rename();
    00416       break;
    00417
    00418       // Synchronize folders
    00419       case CMD_SYNC:
    00420       ushell_cmd_sync();
    00421       break;
    00422
    00423       // Perform transfer
    00424       case CMD_PERFORM:
    00425       ushell_cmd_perform();
    00426       break;
    00427
    00428       // Reboot target
    00429       case CMD_REBOOT:
    00430       ushell_cmd_reboot();
    00431       break;
    00432
    00433       // USB commands
    00434 #if (USHELL_USB==ENABLE)
    00435       case CMD_LS_USB:
    00436       ushell_cmdusb_ls();
    00437       break;
    00438       case CMD_USB_SUSPEND:
    00439       ushell_cmdusb_suspend();
    00440       break;
    00441       case CMD_USB_RESUME:
    00442       ushell_cmdusb_resume();
    00443       break;
    00444       case CMD_USB_FORCE_ENUM:
    00445       ushell_cmdusb_force_enum();
    00446       break;
    00447 #endif
    00448
    00449       // DFU commands
    00450 #if (USHELL_DFU==ENABLE)
    00451       case CMD_DFU_ERASE:
    00452       ushell_cmddfu_erase();
    00453       break;
    00454       case CMD_DFU_LOAD:
    00455       ushell_cmddfu_load();
    00456       break;
    00457       case CMD_DFU_START:
    00458       ushell_cmddfu_start();
    00459       break;
    00460 #endif
    00461
    00462       // HID commands
    00463 #if (USHELL_HID==ENABLE)
    00464       case CMD_HID_ENTER_DFU:
    00465       ushell_cmdhid_enter_dfu();
    00466       break;
    00467       case CMD_HID_GET_INFO:
    00468       ushell_cmdhid_getinfo();
    00469       break;
    00470 #endif
    00471
    00472       // Unknown command
    00473       default:
    00474       print_msg((U8 code *)msg_er_cmd_not_found);
    00475       break;
    00476    }
    00477
    00478    print_msg((U8 code *)msg_prompt);
    00479 }
    00480
    00481
    00486 Bool ushell_cmd_scan(void)
    00487 {
    00488    char c_key;
    00489
    00490    // Something new of the UART ?
    00491    if(!ushell_test_hit())
    00492       return FALSE;
    00493
    00494    c_key=ushell_get_char();
    00495
    00496    if( 0 != g_u8_escape_sequence )
    00497    {
    00498       //** Decode escape sequence
    00499       if( 1 == g_u8_escape_sequence )
    00500       {
    00501          if( 0x5B != c_key )
    00502          {
    00503             g_u8_escape_sequence=0;
    00504             return FALSE;  // Escape sequence cancel
    00505          }
    00506          g_u8_escape_sequence=2;
    00507       }
    00508       else
    00509       {
    00510          // Decode value of the sequence
    00511          switch (c_key)
    00512          {
    00513 /*
    00514 Note: OVERRUN error on USART with an RTOS and USART without interrupt management
    00515 If you want support "Escape sequence", then you have to implement USART interrupt management
    00516             case 0x41:     // UP command
    00517             ushell_clean_cmd_line();
    00518             ushell_history_up();
    00519             ushell_history_display();
    00520             break;
    00521             case 0x42:     // DOWN command
    00522             ushell_clean_cmd_line();
    00523             ushell_history_down();
    00524             ushell_history_display();
    00525             break;
    00526 */
    00527             default:       // Ignore other command
    00528             break;
    00529          }
    00530          g_u8_escape_sequence=0; // End of Escape sequence
    00531       }
    00532       return FALSE;
    00533    }
    00534
    00535    //** Normal sequence
    00536    switch (c_key)
    00537    {
    00538       //** Command validation
    00539       case ASCII_CR:
    00540       ushell_putchar(ASCII_CR);     // Echo
    00541       ushell_putchar(ASCII_LF);     // Add new line flag
    00542       g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size]=0;  // Add NULL terminator at the end of command line
    00543       return TRUE;
    00544
    00545       //** Enter in escape sequence
    00546       case ASCII_ESCAPE:
    00547       g_u8_escape_sequence=1;
    00548       break;
    00549
    00550       //** backspace
    00551       case ASCII_BKSPACE:
    00552       if(g_u8_cmd_size>0)        // Beginning of line ?
    00553       {
    00554          // Remove the last character on terminal
    00555          ushell_putchar(ASCII_BKSPACE);   // Send a backspace to go in previous character
    00556          ushell_putchar(' ');             // Send a space to erase previous character
    00557          ushell_putchar(ASCII_BKSPACE);   // Send a backspace to go in new end position (=previous character position)
    00558          // Remove the last character on cmd line buffer
    00559          g_u8_cmd_size--;
    00560       }
    00561       break;
    00562
    00563       // History management
    00564       case '!':
    00565       ushell_clean_cmd_line();
    00566       ushell_history_up();
    00567       ushell_history_display();
    00568       break;
    00569       case '$':
    00570       ushell_clean_cmd_line();
    00571       ushell_history_down();
    00572       ushell_history_display();
    00573       break;
    00574
    00575       //** Other char
    00576       default:
    00577       if( (0x1F<c_key) && (c_key<0x7F) && (USHELL_SIZE_CMD_LINE!=g_u8_cmd_size) )
    00578       {
    00579          // Accept char
    00580          ushell_putchar(c_key);                                   // Echo
    00581          g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size++] = c_key;  // append to cmd line
    00582       }
    00583       break;
    00584    }
    00585    return FALSE;
    00586 }
    00587
    00588
    00598 U8 ushell_cmd_decode( void )
    00599 {
    00600    U8 cmd_type;
    00601    U8 u8_i,u8_j,u8_k;
    00602    U8 u8_cmd_size;
    00603    Bool b_arg_include_space;
    00604
    00605    if(0==g_u8_cmd_size)
    00606    {
    00607       // Command line empty
    00608       print_msg((U8 code *)msg_prompt);
    00609       return CMD_NONE;
    00610    }
    00611
    00612    // Get command string and Change command to lower case
    00613    for( u8_i=0; (g_s_cmd_his[g_u8_history_pos][u8_i]!=' ') && (u8_i<=g_u8_cmd_size); u8_i++)
    00614    {
    00615       g_s_cmd[u8_i] = g_s_cmd_his[g_u8_history_pos][u8_i];
    00616       if( ('A'<=g_s_cmd[u8_i]) && (g_s_cmd[u8_i]<='Z') )
    00617          g_s_cmd[u8_i] += ('a'-'A');
    00618    }
    00619    g_s_cmd[u8_i]=0;
    00620    u8_cmd_size = u8_i-1;
    00621
    00622    // Get arguments strings
    00623    for( u8_j=0; u8_j<USHELL_MAX_NB_ARG; u8_j++ )
    00624    {
    00625       u8_i++;     // Jump space character
    00626       // Check "
    00627       b_arg_include_space = ( g_s_cmd_his[g_u8_history_pos][u8_i] == '"' );
    00628       if( b_arg_include_space ) {
    00629         u8_i++;
    00630       }
    00631       for( u8_k=0;
    00632            (b_arg_include_space || (g_s_cmd_his[g_u8_history_pos][u8_i] != ' '))
    00633            && ((!b_arg_include_space) || (g_s_cmd_his[g_u8_history_pos][u8_i] != '"'))
    00634            && (u8_i<=g_u8_cmd_size);
    00635            u8_i++, u8_k++ )
    00636       {
    00637          g_s_arg[u8_j][u8_k] = g_s_cmd_his[g_u8_history_pos][u8_i];
    00638       }
    00639       if( b_arg_include_space ) {
    00640         u8_i++;   // Jump last "
    00641       }
    00642       g_s_arg[u8_j][u8_k] = 0;
    00643    }
    00644
    00645    // Reset command size and update history
    00646    g_u8_cmd_size=0;
    00647    g_u8_history_pos++;
    00648    if( g_u8_history_pos == USHELL_HISTORY)
    00649       g_u8_history_pos = 0;
    00650    g_u8_history_pos_search = g_u8_history_pos;
    00651
    00652    // Decode command type
    00653    if ( mystrncmp(g_s_cmd,(U8 code *)str_disk,u8_cmd_size))
    00654    {  cmd_type=CMD_NB_DRIVE; }
    00655    else if ( mystrncmp(g_s_cmd,(U8 code *)str_df,u8_cmd_size))
    00656    {  cmd_type=CMD_DF; }
    00657    else if ( mystrncmp(g_s_cmd,(U8 code *)str_format,u8_cmd_size))
    00658    {  cmd_type=CMD_FORMAT; }
    00659    else if ( mystrncmp(g_s_cmd,(U8 code *)str_mount,u8_cmd_size))
    00660    {  cmd_type=CMD_MOUNT; }
    00661    else if ( g_s_cmd[1]==':' )
    00662    {  cmd_type=CMD_MOUNT; g_s_arg[0][0]=g_s_cmd[0];g_s_arg[0][1]='0'; }
    00663    else if ( mystrncmp(g_s_cmd,(U8 code *)str_space,u8_cmd_size))
    00664    {  cmd_type=CMD_SPACE; }
    00665    else if ( mystrncmp(g_s_cmd,(U8 code *)str_ls,u8_cmd_size))
    00666    {  cmd_type=CMD_LS; }
    00667    else if ( mystrncmp(g_s_cmd,(U8 code *)str_ls_more,u8_cmd_size))
    00668    {  cmd_type=CMD_LS_MORE; }
    00669    else if (mystrncmp(g_s_cmd,(U8 code *)str_cd,u8_cmd_size))
    00670    {  cmd_type=CMD_CD; }
    00671    else if ( mystrncmp(g_s_cmd,(U8 code *)str_up,u8_cmd_size))
    00672    {  cmd_type=CMD_UP; }
    00673    else if ( mystrncmp(g_s_cmd,(U8 code *)str_cat,u8_cmd_size))
    00674    {  cmd_type=CMD_CAT; }
    00675    else if ( mystrncmp(g_s_cmd,(U8 code *)str_cat_more,u8_cmd_size))
    00676    {  cmd_type=CMD_CAT_MORE; }
    00677    else if ( mystrncmp(g_s_cmd,(U8 code *)str_help,u8_cmd_size))
    00678    {  cmd_type=CMD_HELP; }
    00679    else if ( mystrncmp(g_s_cmd,(U8 code *)str_mkdir,u8_cmd_size))
    00680    {  cmd_type=CMD_MKDIR; }
    00681    else if ( mystrncmp(g_s_cmd,(U8 code *)str_touch,u8_cmd_size))
    00682    {  cmd_type=CMD_TOUCH; }
    00683    else if ( mystrncmp(g_s_cmd,(U8 code *)str_rm,u8_cmd_size))
    00684    {  cmd_type=CMD_RM; }
    00685    else if ( mystrncmp(g_s_cmd,(U8 code *)str_append,u8_cmd_size))
    00686    {  cmd_type=CMD_APPEND; }
    00687    else if ( mystrncmp(g_s_cmd,(U8 code *)str_mark,u8_cmd_size))
    00688    {  cmd_type=CMD_SET_ID; }
    00689    else if ( mystrncmp(g_s_cmd,(U8 code *)str_goto,u8_cmd_size))
    00690    {  cmd_type=CMD_GOTO_ID; }
    00691    else if ( mystrncmp(g_s_cmd,(U8 code *)str_cp,u8_cmd_size))
    00692    {  cmd_type=CMD_CP; }
    00693    else if ( mystrncmp(g_s_cmd,(U8 code *)str_mv,u8_cmd_size))
    00694    {  cmd_type=CMD_MV; }
    00695    else if ( mystrncmp(g_s_cmd,(U8 code *)str_sync,u8_cmd_size))
    00696    {  cmd_type=CMD_SYNC; }
    00697    else if ( mystrncmp(g_s_cmd,(U8 code *)str_perform,u8_cmd_size))
    00698    {  cmd_type=CMD_PERFORM; }
    00699    else if ( mystrncmp(g_s_cmd,(U8 code *)str_reboot,u8_cmd_size))
    00700    {  cmd_type=CMD_REBOOT; }
    00701 #if (USHELL_USB==ENABLE)
    00702    else if ( mystrncmp(g_s_cmd,(U8 code *)str_ls_usb,u8_cmd_size))
    00703    {  cmd_type=CMD_LS_USB; }
    00704    else if ( mystrncmp(g_s_cmd,(U8 code *)str_usb_suspend,u8_cmd_size))
    00705    {  cmd_type=CMD_USB_SUSPEND; }
    00706    else if ( mystrncmp(g_s_cmd,(U8 code *)str_usb_resume,u8_cmd_size))
    00707    {  cmd_type=CMD_USB_RESUME; }
    00708    else if ( mystrncmp(g_s_cmd,(U8 code *)str_usb_force_enum,u8_cmd_size))
    00709    {  cmd_type=CMD_USB_FORCE_ENUM; }
    00710 #endif
    00711 #if (USHELL_DFU==ENABLE)
    00712    else if ( mystrncmp(g_s_cmd,(U8 code *)str_dfu_erase,u8_cmd_size))
    00713    {  cmd_type=CMD_DFU_ERASE; }
    00714    else if ( mystrncmp(g_s_cmd,(U8 code *)str_dfu_load,u8_cmd_size))
    00715    {  cmd_type=CMD_DFU_LOAD; }
    00716    else if ( mystrncmp(g_s_cmd,(U8 code *)str_dfu_start,u8_cmd_size))
    00717    {  cmd_type=CMD_DFU_START; }
    00718 #endif
    00719 #if (USHELL_HID==ENABLE)
    00720    else if ( mystrncmp(g_s_cmd,(U8 code *)str_hid_enter_dfu,u8_cmd_size))
    00721    {  cmd_type=CMD_HID_ENTER_DFU; }
    00722    else if ( mystrncmp(g_s_cmd,(U8 code *)str_hid_get_info,u8_cmd_size))
    00723    {  cmd_type=CMD_HID_GET_INFO; }
    00724 #endif
    00725    else
    00726    {
    00727       print_msg((U8 code *)msg_er_cmd_not_found);
    00728       print_msg((U8 code *)msg_prompt);
    00729       return CMD_NONE;
    00730    }
    00731    return cmd_type;
    00732 }
    00733
    00734
    00737 void ushell_clean_cmd_line( void )
    00738 {
    00739    // Clean command line display
    00740    while( 0 != g_u8_cmd_size )
    00741    {
    00742       // Remove the last character on cmd line buffer
    00743       putchar(ASCII_BKSPACE); // Send a backspace to go in previous character
    00744       putchar(' ');           // Send a space to erase previous character
    00745       putchar(ASCII_BKSPACE); // Send a backspace to go in new end position (=previous character position)
    00746       g_u8_cmd_size--;
    00747    }
    00748 }
    00749
    00750
    00753 void ushell_history_up( void )
    00754 {
    00755    if( g_u8_history_pos_search == 0 )
    00756    {
    00757       if( (USHELL_HISTORY-1) == g_u8_history_pos )
    00758          return;  // End of history list
    00759       g_u8_history_pos_search = USHELL_HISTORY-1;
    00760    }else{
    00761       if( (g_u8_history_pos_search-1) == g_u8_history_pos )
    00762          return;  // End of history list
    00763       g_u8_history_pos_search--;
    00764    }
    00765    if( 0 == g_s_cmd_his[g_u8_history_pos_search][0] )
    00766    {
    00767       // History empty then go to previous selection
    00768       ushell_history_down();
    00769    }
    00770 }
    00771
    00772
    00775 void ushell_history_down( void )
    00776 {
    00777    if( g_u8_history_pos_search == g_u8_history_pos )
    00778       return;  // End of history list
    00779    if( g_u8_history_pos == 0 )
    00780    {
    00781       if( (USHELL_HISTORY-1) == g_u8_history_pos_search )
    00782          return;  // End of history list
    00783       g_u8_history_pos_search++;
    00784    }else{
    00785       if( (g_u8_history_pos_search+1) == g_u8_history_pos )
    00786          return;  // End of history list
    00787    }
    00788    g_u8_history_pos_search++;
    00789    if( USHELL_HISTORY == g_u8_history_pos_search )
    00790       g_u8_history_pos_search = 0;
    00791 }
    00792
    00793
    00796 void ushell_history_display( void )
    00797 {
    00798    g_u8_cmd_size=0;
    00799    while( g_s_cmd_his[g_u8_history_pos_search][g_u8_cmd_size] != 0 )
    00800    {
    00801       putchar( g_s_cmd_his[g_u8_history_pos_search][g_u8_cmd_size] );
    00802       g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size] = g_s_cmd_his[g_u8_history_pos_search][g_u8_cmd_size];
    00803       g_u8_cmd_size++;
    00804    }
    00805    g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size] = 0;
    00806 }
    00807
    00808
    00809
    00816 #ifdef __GNUC__
    00817 U8 mystrncmp(char *str1,U8 *str2,U8 u8_i)
    00818 #else
    00819 U8 mystrncmp(char *str1,U8 code *str2,U8 u8_i)
    00820 #endif
    00821 {
    00822    U8 j;
    00823    for(j=0;j<=u8_i;j++)
    00824    {
    00825 #ifndef __GNUC__
    00826       if(*str1!=*str2)
    00827 #else
    00828       if( *str1 != pgm_read_byte_near((unsigned int)str2))
    00829 #endif
    00830       {
    00831          return FALSE;
    00832       }
    00833       str1++;str2++;
    00834    }
    00835    return TRUE;
    00836 }
    00837
    00838
    00843 #ifdef __GNUC__
    00844 void print_msg(U8 *str)
    00845 #else
    00846 void print_msg(U8 code *str)
    00847 #endif
    00848 {
    00849    char c;
    00850 #ifndef __GNUC__
    00851    c=*str++;
    00852    while(c!=0)
    00853    {
    00854       ushell_putchar(c);
    00855       c=*str++;
    00856    }
    00857 #else    // AVRGCC does not support point to PGM space
    00858    c=pgm_read_byte_near((unsigned int)str++);
    00859    while(c!=0)
    00860    {
    00861       ushell_putchar(c);
    00862       c=pgm_read_byte_near((unsigned int)str++);
    00863    }
    00864 #endif
    00865
    00866 }
    00867
    00868
    00873 Bool ushell_more_wait( void )
    00874 {
    00875    char c_key;
    00876    printf("\n\r-- space for more--");
    00877    c_key=0;
    00878    while( (c_key!='q') && (c_key!=' ') )
    00879    {
    00880      c_key=ushell_get_char();
    00881    }
    00882    printf("\r                 \r");
    00883    return (c_key==' ');
    00884 }
    00885
    00886
    00889 void ushell_cmd_nb_drive( void )
    00890 {
    00891    U8 u8_tmp;
    00892
    00893    printf("Memory interface available:\r\n");
    00894    for( u8_tmp=0; u8_tmp<nav_drive_nb(); u8_tmp++ )
    00895    {
    00896       // Display drive letter name (a, b...)
    00897       ushell_putchar(u8_tmp+'a');
    00898       ushell_putchar(':');
    00899       ushell_putchar(' ');
    00900       print_msg((U8 code *)mem_name(u8_tmp));
    00901       ushell_putchar(ASCII_CR); ushell_putchar(ASCII_LF);
    00902    }
    00903 }
    00904
    00905
    00908 void ushell_cmd_free_space( void )
    00909 {
    00910    U8 u8_tmp;
    00911    Fs_index sav_index = nav_getindex();      // Save current position
    00912    for( u8_tmp=0; u8_tmp<nav_drive_nb(); u8_tmp++ )
    00913    {
    00914       nav_drive_set( u8_tmp );      // Select drive
    00915       if( !nav_partition_mount() )  // Mount drive
    00916          continue;
    00917
    00918       // Display drive letter name (a, b...)
    00919       ushell_putchar( u8_tmp+'a' );
    00920       ushell_putchar(':');
    00921       ushell_putchar(' ');
    00922       print_msg((U8 code *)mem_name(u8_tmp));
    00923       printf("\n\r");
    00924
    00925       if( g_s_arg[0][0]=='l' )        // Choose command option
    00926       {
    00927          // Long and exact fonction
    00928          printf("Free space: %llu Bytes / %llu Bytes\n\r",
    00929                    (double)(nav_partition_freespace() << FS_SHIFT_B_TO_SECTOR),
    00930                    (double)(nav_partition_space() << FS_SHIFT_B_TO_SECTOR));
    00931       }
    00932       else
    00933       {
    00934          // Otherwise use fast command
    00935          printf("Free space: %u %%\n\r", nav_partition_freespace_percent() );
    00936       }
    00937    }
    00938    nav_gotoindex(&sav_index);       // Restore position
    00939 }
    00940
    00941
    00944 void ushell_cmd_format( void )
    00945 {
    00946    if( g_s_arg[0][0] == 0 )
    00947       return;
    00948
    00949    // Select drive to format
    00950    nav_drive_set( g_s_arg[0][0]-'a');
    00951    if( !nav_drive_format(FS_FORMAT_DEFAULT) )
    00952    {
    00953       print_msg((U8 code *)msg_er_format);
    00954       return;
    00955    }
    00956 }
    00957
    00958
    00961 void ushell_cmd_mount( void )
    00962 {
    00963    U8 u8_drive_lun;
    00964    Fs_index sav_index;
    00965
    00966    if( g_s_arg[0][0] == 0 )
    00967       return;
    00968
    00969    // Compute the logical unit number of drive
    00970    u8_drive_lun=g_s_arg[0][0]-'a';
    00971    // Check lun number
    00972    if( u8_drive_lun >= nav_drive_nb() )
    00973    {
    00974       print_msg((U8 code *)msg_er_drive);
    00975       return;
    00976    }
    00977
    00978    // Mount drive
    00979    sav_index = nav_getindex();      // Save previous position
    00980    if( nav_drive_set(u8_drive_lun))
    00981    {
    00982       if( nav_partition_mount() )
    00983          return;                    // Here, drive mounted
    00984    }
    00985    print_msg((U8 code *)msg_er_mount);
    00986    nav_gotoindex(&sav_index);       // Restore previous position
    00987 }
    00988
    00989
    00992 void ushell_cmd_space( void )
    00993 {
    00994    U32 u32_space;
    00995    // Display drive letter name (a, b...)
    00996    print_msg((U8 code *)mem_name(nav_drive_get()));
    00997    ushell_putchar(' ');
    00998    ushell_putchar( nav_drive_get()+'a');
    00999    // Otherwise use fast command
    01000    u32_space = nav_partition_space();
    01001    if( 1024 >(u32_space % (2*1024)) )
    01002    {
    01003       u32_space = u32_space/(2*1024);
    01004    }else{
    01005       u32_space = (u32_space/(2*1024))+1;
    01006    }
    01007    printf(": space: %luMB \n\r", u32_space );
    01008 }
    01009
    01010
    01015 void ushell_cmd_ls( Bool b_more )
    01016 {
    01017    U8 str_char[MAX_FILE_LENGHT];
    01018    U16 u16_i,u16_nb_file,u16_nb_dir,last_i;
    01019    U8 ext_filter=FALSE;
    01020
    01021    //** Print drive name
    01022    printf("%c: volume is ", 'a'+nav_drive_get() );
    01023    print_msg((U8 code *)mem_name(nav_drive_get()));
    01024    printf("\n\rDrive uses ");
    01025    switch (nav_partition_type())
    01026    {
    01027       case FS_TYPE_FAT_12:
    01028       printf("FAT12\n\r");
    01029       break;
    01030
    01031       case FS_TYPE_FAT_16:
    01032       printf("FAT16\n\r");
    01033       break;
    01034
    01035       case FS_TYPE_FAT_32:
    01036       printf("FAT32\n\r");
    01037       break;
    01038
    01039       default:
    01040       printf("an unknown partition type\r\n");
    01041       return;
    01042    }
    01043
    01044    //** Print directory name
    01045    if( !nav_dir_name( (FS_STRING)str_char, MAX_FILE_LENGHT ) )
    01046    {
    01047       printf("ROOT directory\n\r");
    01048    }else{
    01049       printf("Dir name is %s\n\r",str_char);
    01050    }
    01051
    01052    //** Check extension filter in extra parameters
    01053    if(g_s_arg[0][0]!=0)
    01054    {
    01055       if(g_s_arg[0][0] == '*' && g_s_arg[0][1]=='.')
    01056       {
    01057          ext_filter=TRUE;
    01058          for(u16_i=2; u16_i<USHELL_SIZE_CMD_LINE; u16_i++)
    01059          {
    01060             g_s_arg[0][u16_i-2]=g_s_arg[0][u16_i];
    01061          }
    01062       }
    01063    }
    01064
    01065    //** Print files list
    01066    printf("          Size  Name\n\r");
    01067    // Init loop at the begining of directory
    01068    nav_filelist_reset();
    01069    u16_nb_file=0;
    01070    u16_nb_dir=0;
    01071    last_i=0;
    01072    // For each file in list
    01073    while( nav_filelist_set(0,FS_FIND_NEXT) )
    01074    {
    01075       if(!ext_filter)
    01076       {
    01077          // No extension filter
    01078          if( nav_file_isdir() )
    01079          {
    01080             printf("Dir ");
    01081             u16_nb_dir++;              // count the number of directory
    01082          }else{
    01083             printf("    ");
    01084          }
    01085       }
    01086       else
    01087       {
    01088          // If extension filter then ignore directories
    01089          if(nav_file_isdir())
    01090             continue;
    01091          // Check extension
    01092          if(!nav_file_checkext((FS_STRING)g_s_arg[0]))
    01093             continue;
    01094       }
    01095       u16_nb_file++;                   // count the total of files (directories and files)
    01096
    01097       // Check 'more' step
    01098       if( b_more && ((u16_nb_file%USHELL_NB_LINE)==0) && (u16_nb_file!=0) && (last_i != u16_nb_file) )
    01099       {
    01100          last_i=u16_nb_file;
    01101          if( !ushell_more_wait() )
    01102             return;  // Exit LS command
    01103       }
    01104
    01105       // Display file
    01106       nav_file_name((FS_STRING)str_char, MAX_FILE_LENGHT, FS_NAME_GET, TRUE);
    01107       printf("%10lu  %s\n\r", nav_file_lgt(), str_char);
    01108    }
    01109    // Display total number
    01110    printf(" %4i Files\r\n", u16_nb_file-u16_nb_dir );
    01111    printf(" %4i Dir\r\n", u16_nb_dir );
    01112 }
    01113
    01114
    01117 void ushell_cmd_cd( void )
    01118 {
    01119    if( g_s_arg[0][0] == 0 )
    01120       return;
    01121
    01122    // Add '\' at the end of path, else the nav_setcwd select the directory but don't enter into.
    01123    ushell_path_valid_syntac( g_s_arg[0] );
    01124
    01125    // Call file system routine
    01126    if( nav_setcwd((FS_STRING)g_s_arg[0],TRUE,FALSE) == FALSE )
    01127    {
    01128       print_msg((U8 code *)msg_er_unknown_file);
    01129    }
    01130 }
    01131
    01132
    01135 void ushell_cmd_gotoparent( void )
    01136 {
    01137    nav_dir_gotoparent();
    01138 }
    01139
    01140
    01147 void ushell_cmd_cat( Bool b_more)
    01148 {
    01149    char c_file_character;
    01150    U8 n_line=0;
    01151
    01152    if( g_s_arg[0][0] == 0 )
    01153       return;
    01154
    01155    // Select file
    01156    if( !nav_setcwd((FS_STRING)g_s_arg[0],TRUE,FALSE) )
    01157    {
    01158       print_msg((U8 code *)msg_er_unknown_file);
    01159       return;
    01160    }
    01161
    01162    // Open file
    01163    file_open(FOPEN_MODE_R);
    01164    while (file_eof()==FALSE)
    01165    {
    01166       // Check 'more' option
    01167       if( b_more && (n_line >= USHELL_NB_LINE))
    01168       {
    01169          n_line = 0;
    01170          if( !ushell_more_wait() )
    01171             break;   // Stop cat command
    01172       }
    01173
    01174       // Display a character
    01175       c_file_character = file_getc();
    01176       ushell_putchar( c_file_character );
    01177
    01178       // Count the line number
    01179       if (c_file_character==ASCII_LF)
    01180          n_line++;
    01181    }
    01182    file_close();
    01183
    01184    // Jump in a new line
    01185    ushell_putchar(ASCII_CR);ushell_putchar(ASCII_LF);
    01186 }
    01187
    01188
    01191 void ushell_cmd_help( void )
    01192 {
    01193    print_msg((U8 code *)msg_help);
    01194 }
    01195
    01196
    01199 void ushell_cmd_mkdir( void )
    01200 {
    01201    if( g_s_arg[0][0] == 0 )
    01202       return;
    01203
    01204    if( !nav_dir_make((FS_STRING)g_s_arg[0]) )
    01205       print_msg((U8 code *)msg_ko);
    01206 }
    01207
    01208
    01211 void ushell_cmd_touch( void )
    01212 {
    01213    if( g_s_arg[0][0] == 0 )
    01214       return;
    01215
    01216    nav_file_create((FS_STRING)g_s_arg[0]);
    01217 }
    01218
    01219
    01222 void ushell_cmd_rm( void )
    01223 {
    01224    U8 u8_i = 0;
    01225    Fs_index sav_index;
    01226
    01227    if( g_s_arg[0][0] == 0 )
    01228       return;
    01229
    01230    // Save the position
    01231    sav_index = nav_getindex();
    01232
    01233    while( 1 )
    01234    {
    01235       // Restore the position
    01236       nav_gotoindex(&sav_index);
    01237       // Select file or directory
    01238       if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
    01239          break;
    01240       // Delete file or directory
    01241       if( !nav_file_del( FALSE ) )
    01242       {
    01243          print_msg((U8 code *)msg_ko);
    01244          break;
    01245       }
    01246       u8_i++;
    01247    }
    01248    printf( "%u file(s) deleted\n\r", u8_i );
    01249 }
    01250
    01251
    01258 void ushell_cmd_append_file( void )
    01259 {
    01260    char c_key;
    01261
    01262    if( g_s_arg[0][0] == 0 )
    01263       return;
    01264
    01265    // Select file or directory
    01266    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
    01267    {
    01268       print_msg((U8 code *)msg_er_unknown_file);
    01269       return;
    01270    }
    01271    // Open file
    01272    if( !file_open(FOPEN_MODE_APPEND) )
    01273    {
    01274       print_msg((U8 code *)msg_ko);
    01275       return;
    01276    }
    01277
    01278    // Append file
    01279    print_msg((U8 code *)msg_append_welcome);
    01280    while( 1 )
    01281    {
    01282       c_key = ushell_get_char();
    01283
    01284       if( c_key == ASCII_CTRL_Q )
    01285          break;   // ^q to quit
    01286
    01287       ushell_putchar( c_key );
    01288       file_putc( c_key );
    01289       if( c_key == ASCII_CR )
    01290       {
    01291          ushell_putchar(ASCII_LF);
    01292          file_putc(ASCII_LF);
    01293       }
    01294    }
    01295
    01296    // Close file
    01297    file_close();
    01298    ushell_putchar(ASCII_CR); ushell_putchar(ASCII_LF);
    01299 }
    01300
    01301
    01304 void ushell_cmd_copy( void )
    01305 {
    01306    Fs_index sav_index;
    01307    U8 u8_status_copy;
    01308
    01309    if( g_s_arg[0][0] == 0 )
    01310       return;
    01311
    01312    // Save the position
    01313    sav_index = nav_getindex();
    01314
    01315    // Select source file
    01316    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
    01317    {
    01318       print_msg((U8 code *)msg_er_unknown_file);
    01319       return;
    01320    }
    01321    // Get name of source to be used as same destination name
    01322    nav_file_name( (FS_STRING)g_s_arg[0], MAX_FILE_LENGHT, FS_NAME_GET, TRUE );
    01323    // Mark this selected file like source file
    01324    if( !nav_file_copy())
    01325    {
    01326       print_msg((U8 code *)msg_ko);
    01327       goto cp_end;
    01328    }
    01329
    01330    // Select destination
    01331    if( g_s_arg[1][0]==0 )
    01332    {
    01333       // g_s_arg[1] is NULL, using mark
    01334       if( !nav_gotoindex(&g_mark_index) )
    01335          goto cp_end;
    01336    }
    01337    else
    01338    {
    01339       // g_s_arg[1] exists, then go to this destination
    01340       if( !nav_setcwd( (FS_STRING)g_s_arg[1], TRUE, FALSE ) )
    01341       {
    01342          print_msg((U8 code *)msg_er_unknown_file);
    01343          goto cp_end;
    01344       }
    01345    }
    01346
    01347    // Set the name destination and start paste
    01348    if( !nav_file_paste_start((FS_STRING)g_s_arg[0]) )
    01349    {
    01350       print_msg((U8 code *)msg_paste_fail);
    01351       goto cp_end;
    01352    }
    01353
    01354    // Performs copy
    01355    do
    01356    {
    01357       u8_status_copy = nav_file_paste_state( FALSE );
    01358    }while( u8_status_copy == COPY_BUSY );
    01359
    01360    // Check status of copy action
    01361    if( u8_status_copy == COPY_FAIL )
    01362    {
    01363       print_msg((U8 code *)msg_paste_fail);
    01364       goto cp_end;
    01365    }
    01366
    01367 cp_end:
    01368    // Restore the position
    01369    nav_gotoindex(&sav_index);
    01370 }
    01371
    01372
    01375 void ushell_cmd_rename( void )
    01376 {
    01377    if( g_s_arg[0][0] == 0 )
    01378       return;
    01379    if( g_s_arg[1][0] == 0 )
    01380       return;
    01381
    01382    // Select source file
    01383    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
    01384    {
    01385       print_msg((U8 code *)msg_er_unknown_file);
    01386       return;
    01387    }
    01388    // Rename file or directory
    01389    if( !nav_file_rename( (FS_STRING)g_s_arg[1] ) )
    01390    {
    01391       print_msg((U8 code *)msg_ko);
    01392       return;
    01393    }
    01394 }
    01395
    01396
    01401 Bool ushell_cmd_sync( void )
    01402 {
    01403    Fs_index sav_index;
    01404    U8 u8_folder_level = 0;
    01405
    01406    if( g_s_arg[0][0] == 0 )
    01407       return FALSE;
    01408    if( g_s_arg[1][0] == 0 )
    01409       return FALSE;
    01410    // Add '\' at the end of path, else the nav_setcwd select the directory but don't enter into.
    01411    ushell_path_valid_syntac( g_s_arg[0] );
    01412    ushell_path_valid_syntac( g_s_arg[1] );
    01413
    01414    printf("Synchronize folders:\n\r");
    01415    sav_index = nav_getindex();   // Save the position
    01416
    01417    // Select source directory in COPYFILE navigator handle
    01418    nav_select( FS_NAV_ID_COPYFILE );
    01419    printf("Select source directory\n\r");
    01420    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
    01421       goto ushell_cmd_sync_error;
    01422    nav_filelist_reset();
    01423
    01424    // Select destination directory in USHELL navigator handle
    01425    nav_select( FS_NAV_ID_USHELL_CMD );
    01426    printf("Select destination directory\n\r");
    01427    if( !nav_setcwd( (FS_STRING)g_s_arg[1], TRUE, TRUE ) )
    01428       goto ushell_cmd_sync_error;
    01429    nav_filelist_reset();
    01430
    01431    // loop to scan and create ALL folders and files
    01432    while(1)
    01433    {
    01434       while(1)
    01435       {
    01436          // Loop to Search files or directories
    01437          // Reselect Source
    01438          nav_select( FS_NAV_ID_COPYFILE );
    01439          if( nav_filelist_set( 0 , FS_FIND_NEXT ) )
    01440             break;   // a next file and directory is found
    01441
    01442          // No other dir or file in current dir then go to parent dir on Source and Destination disk
    01443          if( 0 == u8_folder_level )
    01444          {
    01445             // end of update folder
    01446             //********* END OF COPY **************
    01447             goto ushell_cmd_sync_finish;
    01448          }
    01449
    01450          printf("Go to parent\n\r");
    01451          // Remark, nav_dir_gotoparent() routine go to in parent dir and select the children dir in list
    01452          u8_folder_level--;
    01453          if( !nav_dir_gotoparent() )
    01454             goto ushell_cmd_sync_error;
    01455          // Select Destination navigator and go to the same dir of Source
    01456          nav_select( FS_NAV_ID_USHELL_CMD );
    01457          if( !nav_dir_gotoparent() )
    01458             goto ushell_cmd_sync_error;
    01459       } // end of while (1)
    01460
    01461       if( nav_file_isdir())
    01462       {
    01463          printf("Dir found - create dir: ");
    01464          //** here, a new directory is found and is selected
    01465          // Get name of current selection (= dir name on Source)
    01466          if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, FALSE ))
    01467             goto ushell_cmd_sync_error;
    01468          // Enter in dir (on Source)
    01469          if( !nav_dir_cd())
    01470             goto ushell_cmd_sync_error;
    01471          u8_folder_level++;
    01472          // Select Destination disk
    01473          nav_select( FS_NAV_ID_USHELL_CMD );
    01474          // Create folder in Destination disk
    01475          printf((char*)g_s_arg[0]);
    01476          printf("\n\r");
    01477          if( !nav_dir_make( (FS_STRING )g_s_arg[0] ))
    01478          {
    01479             if( FS_ERR_FILE_EXIST != fs_g_status )
    01480                goto ushell_cmd_sync_error;
    01481             // here, error the name exist
    01482          }
    01483          // Here the navigator have selected the folder on Destination
    01484          if( !nav_dir_cd())
    01485          {
    01486             if( FS_ERR_NO_DIR == fs_g_status )
    01487             {
    01488                // FYC -> Copy impossible, because a file have the same name of folder
    01489             }
    01490             goto ushell_cmd_sync_error;
    01491          }
    01492          // here, the folder is created and the navigatorS is entered in this dir
    01493       }
    01494       else
    01495       {
    01496          printf("File found - copy file: ");
    01497          //** here, a new file is found and is selected
    01498          // Get name of current selection (= file name on Source)
    01499          if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, FALSE ))
    01500             goto ushell_cmd_sync_error;
    01501          printf((char*)g_s_arg[0]);
    01502          printf("\n\r");
    01503          if( !nav_file_copy())
    01504             goto ushell_cmd_sync_error;
    01505
    01506          // Paste file in current dir of Destination disk
    01507          nav_select( FS_NAV_ID_USHELL_CMD );
    01508          while( !nav_file_paste_start( (FS_STRING)g_s_arg[0] ) )
    01509          {
    01510             // Error
    01511             if( fs_g_status != FS_ERR_FILE_EXIST )
    01512                goto ushell_cmd_sync_error;
    01513             // File exists then deletes this one
    01514             printf("File exists then deletes this one.\n\r");
    01515             if( !nav_file_del( TRUE ) )
    01516                goto ushell_cmd_sync_error;
    01517             // here, retry PASTE
    01518          }
    01519          // Copy running
    01520          {
    01521          U8 status;
    01522          do{
    01523             status = nav_file_paste_state(FALSE);
    01524          }while( COPY_BUSY == status );
    01525
    01526          if( COPY_FINISH != status )
    01527             goto ushell_cmd_sync_error;
    01528          }
    01529       } // if dir OR file
    01530    } // end of first while(1)
    01531
    01532 ushell_cmd_sync_error:
    01533    // Restore the position
    01534    nav_select( FS_NAV_ID_USHELL_CMD );
    01535    nav_gotoindex(&sav_index);
    01536    printf("!!!Copy fail\n\r");
    01537    return FALSE;
    01538
    01539 ushell_cmd_sync_finish:
    01540    // Restore the position
    01541    nav_select( FS_NAV_ID_USHELL_CMD );
    01542    nav_gotoindex(&sav_index);
    01543    printf("End of copy\n\r");
    01544    return TRUE;
    01545 }
    01546
    01547 // File alloc space (unit sector 512B)
    01548 #define  FILE_ALLOC_SIZE      ((1024*1024L)/512L)      // 1MB
    01549
    01550 Fs_file_segment ushell_cmd_perform_alloc( U8 lun, U16 size_alloc )
    01551 {
    01552    const FS_STRING file_tmp_name = "tmp.bin";
    01553    Fs_file_segment g_recorder_seg;
    01554    g_recorder_seg.u16_size = 0;
    01555
    01556    if( !nav_drive_set(lun))
    01557       return g_recorder_seg;
    01558
    01559    if( !nav_partition_mount() )
    01560       return g_recorder_seg;
    01561
    01562    if( !nav_file_create((FS_STRING)file_tmp_name))
    01563    {
    01564       if( FS_ERR_FILE_EXIST != fs_g_status)
    01565          return g_recorder_seg;
    01566       nav_file_del(FALSE);
    01567       if( !nav_file_create((FS_STRING)file_tmp_name))
    01568          return g_recorder_seg;
    01569    }
    01570    // Open file
    01571    if( !file_open(FOPEN_MODE_W) )
    01572    {
    01573       nav_file_del(FALSE);
    01574       return g_recorder_seg;
    01575    }
    01576    // Define the size of segment to alloc (unit 512B)
    01577    // Note: you can alloc more in case of you don't know total size
    01578    g_recorder_seg.u16_size = size_alloc;
    01579    // Alloc in FAT a cluster list equal or inferior at segment size
    01580    if( !file_write( &g_recorder_seg ))
    01581    {
    01582       g_recorder_seg.u16_size = 0;
    01583       file_close();
    01584       nav_file_del(FALSE);
    01585    }
    01586    return g_recorder_seg;   //** File open and FAT allocated
    01587 }
    01588
    01589 void ushell_cmd_perform_transfer( Fs_file_segment seg_src, Fs_file_segment seg_dest )
    01590 {
    01591    U8 id_trans_memtomem;
    01592    Ctrl_status status_stream;
    01593    U16 u16_i, u16_ctn, u16_trans_max;
    01594    U32 u32_tmp;
    01595
    01596    Timer16_set_waveform_mode(TIMER16_COMP_MODE_NORMAL);
    01597    Timer16_set_clock(TIMER16_CLKIO_BY_1024); // 8MHz / 1024
    01598    u16_trans_max = ( seg_src.u16_size < seg_dest.u16_size )?  seg_src.u16_size : seg_dest.u16_size;
    01599    for( u16_i=2; u16_i<=u16_trans_max; u16_i*=10 )
    01600    {
    01601       Timer16_clear_overflow_it();
    01602       Timer16_set_counter(0);
    01603       id_trans_memtomem = stream_mem_to_mem( seg_src.u8_lun , seg_src.u32_addr , seg_dest.u8_lun , seg_dest.u32_addr , u16_i );
    01604       if( ID_STREAM_ERR == id_trans_memtomem )
    01605       {
    01606          printf( "Transfert error\r\n");
    01607          return;
    01608       }
    01609       while(1)
    01610       {
    01611          status_stream = stream_state( id_trans_memtomem );
    01612          if( CTRL_BUSY == status_stream ) continue;
    01613          if( CTRL_GOOD == status_stream ) break;
    01614          if( CTRL_FAIL == status_stream ) {
    01615             printf( "Transfert error\r\n");
    01616             return;
    01617          }
    01618       }
    01619       u16_ctn = Timer16_get_counter();
    01620       if( Timer16_get_overflow_it() )
    01621       {
    01622          // Counter too small to get time
    01623          if( 1 == u16_i )
    01624             printf( "Transfert too slow\r\n");
    01625          break;
    01626       }
    01627       u32_tmp = ((U32)u16_i*1000)/((2*(U32)u16_ctn*1024)/8000);
    01628       printf( "Transfert rate %4luKB/s - stream size %4iKB\r\n", u32_tmp, u16_i/2 );
    01629    }
    01630 }
    01631
    01632 void ushell_cmd_perform_access( Bool b_sens_write, Fs_file_segment seg )
    01633 {
    01634    U16 u16_trans,u16_ctn;
    01635    U32 u32_tmp;
    01636
    01637    fat_cache_flush();
    01638    fat_cache_reset();
    01639    Timer16_set_waveform_mode(TIMER16_COMP_MODE_NORMAL);
    01640    Timer16_set_clock(TIMER16_CLKIO_BY_1024); // 8MHz / 1024
    01641    Timer16_clear_overflow_it();
    01642    Timer16_set_counter(0);
    01643    for( u16_trans=0; u16_trans<seg.u16_size; u16_trans++ )
    01644    {
    01645       if( b_sens_write )
    01646       {
    01647          if( CTRL_GOOD != ram_2_memory( seg.u8_lun , seg.u32_addr , fs_g_sector )) {
    01648             printf( "Transfert error\r\n");
    01649             return;
    01650          }
    01651       }else{
    01652          if( CTRL_GOOD != memory_2_ram( seg.u8_lun , seg.u32_addr , fs_g_sector )) {
    01653             printf( "Transfert error\r\n");
    01654             return;
    01655          }
    01656       }
    01657       seg.u32_addr++;
    01658       if( Timer16_get_overflow_it() )
    01659       {
    01660          u16_trans--;
    01661          break;
    01662       }
    01663       u16_ctn = Timer16_get_counter();
    01664    }
    01665    u32_tmp = ((U32)u16_trans*1000)/((2*(U32)u16_ctn*1024)/8000);
    01666    if( b_sens_write )
    01667       printf( "Transfert rate - WRITE %4luKB/s\r\n", u32_tmp );
    01668    else
    01669       printf( "Transfert rate - READ %4luKB/s\r\n", u32_tmp );
    01670 }
    01671
    01674 void ushell_cmd_perform( void )
    01675 {
    01676    Fs_index sav_index;
    01677    Fs_file_segment seg1, seg2;
    01678
    01679    if( g_s_arg[0][0] == 0 )
    01680       return;
    01681
    01682    sav_index = nav_getindex();   // Save the position
    01683
    01684    // Alloc a file on each devices
    01685    printf("Alloc a file on each devices\n\r");
    01686    seg1 = ushell_cmd_perform_alloc( (g_s_arg[0][0]-'a') , FILE_ALLOC_SIZE );
    01687    if( seg1.u16_size == 0 )
    01688    {
    01689       printf("!!!Error allocation on device 1\n\r");
    01690       // Restore the position
    01691       nav_gotoindex(&sav_index);
    01692       return;
    01693    }
    01694    if( g_s_arg[1][0] != 0 )
    01695    {
    01696       nav_select( FS_NAV_ID_COPYFILE );
    01697       seg2 = ushell_cmd_perform_alloc( (g_s_arg[1][0]-'a') , FILE_ALLOC_SIZE );
    01698       if( seg2.u16_size == 0 )
    01699       {
    01700          nav_select( FS_NAV_ID_USHELL_CMD );
    01701          file_close();
    01702          nav_file_del(FALSE);
    01703          printf("!!!Error allocation on device 2\n\r");
    01704          // Restore the position
    01705          nav_gotoindex(&sav_index);
    01706          return;
    01707       }
    01708
    01709       // Transfert data from device 1 to device 2
    01710       printf("Transfert data from device 1 to device 2\r\n");
    01711       ushell_cmd_perform_transfer(seg1,seg2);
    01712       printf("Transfert data from device 2 to device 1\r\n");
    01713       ushell_cmd_perform_transfer(seg2,seg1);
    01714       // Delete files allocated
    01715       nav_select( FS_NAV_ID_COPYFILE );
    01716       file_close();
    01717       nav_file_del(FALSE);
    01718       nav_select( FS_NAV_ID_USHELL_CMD );
    01719    }
    01720    else
    01721    {
    01722       ushell_cmd_perform_access( FALSE, seg1 );
    01723       ushell_cmd_perform_access( TRUE, seg1 );
    01724    }
    01725
    01726    file_close();
    01727    nav_file_del(FALSE);
    01728    // Restore the position
    01729    nav_gotoindex(&sav_index);
    01730    printf("End of test\n\r");
    01731    return;
    01732 }
    01733
    01734
    01735
    01736
    01739 void ushell_path_valid_syntac( char *path )
    01740 {
    01741    U8 u8_tmp;
    01742
    01743    // Compute size of substitute
    01744    for( u8_tmp=0; u8_tmp<MAX_FILE_LENGHT; u8_tmp++ )
    01745    {
    01746       if( path[u8_tmp]==0)
    01747          break;
    01748    }
    01749    // Append the '\' char for the nav_setcwd to enter the found directory
    01750    if ( path[u8_tmp-1] != '\\')
    01751    {
    01752       path[u8_tmp]='\\';
    01753       path[u8_tmp+1]=0;
    01754    }
    01755 }
    01756
    01757
    01760 void ushell_cmd_reboot( void )
    01761 {
    01762    // Reset SPI interface
    01763 #ifdef SPIDER_ADC_BRIDGE
    01764    #if (TARGET_BOARD==SPIDER)
    01765    SPI_InterMCU_Ready();
    01766    Spider_bridge_reset();
    01767    SPI_InterMCU_Suspend();
    01768    #endif
    01769 #endif
    01770    // Enable watch dog
    01771    wdtdrv_enable(WDTO_16MS);
    01772    // Wait watch dog event
    01773    while(1);
    01774 }
    01775
    01776
    01777 #if (USHELL_USB==ENABLE)
    01782 void ushell_cmdusb_ls(void)
    01783 {
    01784    U8 i,j,n,s;
    01785
    01786    // Check USB host status
    01787    if( (!Is_host_ready()) && (!Is_host_suspended()) )
    01788    {
    01789       print_msg((U8 code *)msg_no_device);
    01790       return;
    01791    }
    01792    if( Is_host_suspended() )
    01793    {
    01794       print_msg((U8 code *)msg_usb_suspended);
    01795    }
    01796
    01797    s = selected_device;
    01798    for( n=0; n<Get_nb_device(); n++ )
    01799    {
    01800       Host_select_device(n);
    01801       printf("\n\rDevice %i @:0x%02X\n\r",n+1,usb_tree.device[selected_device].device_address);
    01802       printf("VID:%04X, PID:%04X, ",Get_VID(),Get_PID());
    01803       printf("MaxPower is %imA, ",2*Get_maxpower());
    01804       if (Is_device_self_powered())
    01805       {  print_msg((U8 code *)msg_device_self_powered); }
    01806       else
    01807       {  print_msg((U8 code *)msg_device_bus_powered); }
    01808       printf("Control Endpoint is %i bytes, ",Get_ep0_size());
    01809       if (Is_host_full_speed())
    01810       {  print_msg((U8 code *)msg_device_full_speed); }
    01811       else
    01812       {  print_msg((U8 code *)msg_device_low_speed); }
    01813       if (Is_device_supports_remote_wakeup())
    01814       {  print_msg((U8 code *)msg_remote_wake_up_ok); }
    01815       else
    01816       {  print_msg((U8 code *)msg_remote_wake_up_ko); }
    01817       printf("Supported interface(s):%02i\n\r",Get_nb_supported_interface());
    01818       for(i=0;i<Get_nb_supported_interface();i++)
    01819       {
    01820          printf("Interface nb:%02i, AltS nb:%02i, Class:%02i, SubClass:%02i, Protocol:%02i\n\r",\
    01821             Get_interface_number(i), Get_alts_s(i), Get_class(i), Get_subclass(i), Get_protocol(i));
    01822          printf(" Endpoint(s) Addr:");
    01823          if(Get_nb_ep(i))
    01824          {
    01825             for(j=0;j<Get_nb_ep(i);j++)
    01826             {
    01827                printf(" %02X", Get_ep_addr(i,j));
    01828             }
    01829          }
    01830          else
    01831          {
    01832             printf("None");
    01833          }
    01834          ushell_putchar(ASCII_CR);ushell_putchar(ASCII_LF);
    01835          printf(" Physical pipe(s):");
    01836          if(Get_nb_ep(i))
    01837          {
    01838             for(j=0;j<Get_nb_ep(i);j++)
    01839             {
    01840                printf(" %02X", usb_tree.device[selected_device].interface[i].ep[j].pipe_number);
    01841             }
    01842          }
    01843          else
    01844          {
    01845             printf("None");
    01846          }
    01847          ushell_putchar(ASCII_CR);ushell_putchar(ASCII_LF);
    01848       }
    01849    }
    01850    selected_device=s;
    01851 }
    01852
    01855 void ushell_cmdusb_suspend(void)
    01856 {
    01857    if( !Is_host_ready() )
    01858    {
    01859       print_msg((U8 code *)msg_no_device);
    01860    }
    01861    Host_request_suspend();
    01862 }
    01863
    01866 void ushell_cmdusb_resume(void)
    01867 {
    01868    if( !Is_host_suspended() )
    01869    {
    01870       print_msg((U8 code *)msg_no_device);
    01871    }
    01872    Host_request_resume();
    01873 }
    01874
    01875
    01878 void ushell_cmdusb_force_enum(void)
    01879 {
    01880    if( !Is_host_ready() )
    01881    {
    01882       print_msg((U8 code *)msg_no_device);
    01883    }
    01884    Host_force_enumeration();
    01885 }
    01886 #endif //USHELL_USB==ENABLE
    01887
    01888
    01889 #if (USHELL_DFU==ENABLE)
    01892 void ushell_cmddfu_erase( void )
    01893 {
    01894    if( !Is_dfu_connected() )
    01895    {
    01896       print_msg((U8 code *)msg_no_device);
    01897       return;
    01898    }
    01899    Dfu_erase();
    01900 }
    01901
    01904 void ushell_cmddfu_load( void )
    01905 {
    01906    if( !Is_dfu_connected() )
    01907    {
    01908       print_msg((U8 code *)msg_no_device);
    01909       return;
    01910    }
    01911    // Select source file
    01912    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
    01913    {
    01914       print_msg((U8 code *)msg_er_unknown_file);
    01915       return;
    01916    }
    01917    Dfu_erase();
    01918    if( !dfu_load_hex() )
    01919    {
    01920       print_msg((U8 code *)msg_ko);
    01921       return;
    01922    }
    01923    print_msg((U8 code *)msg_ok);
    01924 }
    01925
    01928 void ushell_cmddfu_start( void )
    01929 {
    01930    if( !Is_dfu_connected() )
    01931    {
    01932       print_msg((U8 code *)msg_no_device);
    01933       return;
    01934    }
    01935    Dfu_start_appli();
    01936 }
    01937 #endif   // (USHELL_DFU==ENABLE)
    01938
    01939
    01940 #if (USHELL_HID==ENABLE)
    01943 void ushell_cmdhid_enter_dfu(void)
    01944 {
    01945    if( !Is_hid_connected() )
    01946    {
    01947       print_msg((U8 code *)msg_no_device);
    01948    }
    01949    Hid_send_enter_dfu();
    01950 }
    01951
    01954 void ushell_cmdhid_getinfo(void)
    01955 {
    01956    if( !Is_hid_connected() )
    01957    {
    01958       print_msg((U8 code *)msg_no_device);
    01959       return;
    01960    }
    01961 #if( HID_GENERIC_DEMO_FULL == ENABLE )
    01962    printf("Temperature %i C\n\r",Hid_get_temperature());
    01963    printf("Potentiometer %i\n\r",Hid_get_potentiometer());
    01964 #else
    01965    printf("No data available with this HID generic configuration.\n\r");
    01966 #endif
    01967 }
    01968 #endif // (USHELL_HID==ENABLE)
    01969
    01970
    01971 #ifdef   LOG_STR_CODE
    01976 extern void ushell_trace_msg(U8 code *str)
    01977 {
    01978    ushell_putchar(CR);
    01979    ushell_putchar(LF);
    01980    print_msg((U8 code *)str);
    01981    ushell_putchar(CR);
    01982    ushell_putchar(LF);
    01983    print_msg((U8 code *)msg_prompt);
    01984 }
    01985 #endif
    01986