static CMD_HANDLER_FUNC(wsFileTxHandler) { /** * If other node is running same software, we will just use its "file" handler: * buffer <offset> <num bytes> ... * commit <filename> <file offset> <num bytes from buffer> */ char srcFile[128] = { 0 }; char dstFile[128] = { 0 }; int timeout = 1000; int addr = 0; FIL file; if (3 != cmdParams.scanf("%128s %128s %i", &srcFile[0], &dstFile[0], &addr)) { return false; } if (FR_OK != f_open(&file, srcFile, FA_OPEN_EXISTING | FA_READ)) { return false; } NordicStream &n = NordicStream::getInstance(); n.setDestAddr(addr); char c = 0; char buffer[512]; int expectedChecksum = 0; unsigned int bytesRead = 0; unsigned int fileOffset = 0; unsigned int retries = 0; unsigned int retriesMax = 3; STR_ON_STACK(response, 128); // Sorry for the dirty hack #define #define doRetry() ++retries; n.printf("\n"); n.flush(); while (n.getChar(&c, timeout)); goto retry output.printf("Transfer %s --> %i:%s\n", srcFile, addr, dstFile); while(FR_OK == f_read(&file, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) { retry: if (retries >= retriesMax) { break; } n.printf("file buffer 0 %i\n", bytesRead); n.flush(); expectedChecksum = 0; for (unsigned int i=0; i < bytesRead; i++) { n.putChar(buffer[i]); expectedChecksum += buffer[i]; } n.flush(); // Confirm the checksum: response should be something like "Checksum: 123" n.gets((char*) response(), response.getCapacity(), timeout); response.eraseFirstWords(1); if ( (int)response != expectedChecksum) { output.printf("ERROR: Checksum Expected %i Actual %i\n", expectedChecksum, (int) response); doRetry(); } // Make sure the file was written correctly, response should be "OK" n.printf("file commit %s %i %i\n", dstFile, fileOffset, bytesRead); n.flush(); n.gets((char*) response(), response.getCapacity(), timeout); if (!response.containsIgnoreCase("ok")) { output.printf("ERROR: Remote node did not acknowledge file write (%s)\n", response()); doRetry(); } response = ""; fileOffset += bytesRead; output.printf("Sent %i/%i\n", fileOffset, file.fsize); // Reset the retries such that only if we fail continuously we will give up if (retries > 0) { --retries; } } f_close(&file); return true; }
bool terminalTask::taskEntry() { /* remoteTask() creates shared object in its init(), so we can get it now */ CommandProcessor &cp = mCmdProc; // System information handlers cp.addHandler(taskListHandler, "info", "Task/CPU Info. Use 'info 200' to get CPU during 200ms"); cp.addHandler(memInfoHandler, "meminfo", "See memory info"); cp.addHandler(healthHandler, "health", "Output system health"); cp.addHandler(timeHandler, "time", "'time' to view time. 'time set MM DD YYYY HH MM SS Wday' to set time"); // File I/O handlers: cp.addHandler(catHandler, "cat", "Read a file. Ex: 'cat 0:file.txt' or " "'cat 0:file.txt -noprint' to test if file can be read"); cp.addHandler(cpHandler, "cp", "Copy files from/to Flash/SD Card. Ex: 'cp 0:file.txt 1:file.txt'"); cp.addHandler(dcpHandler, "dcp", "Copy all files of a directory to another directory. Ex: 'dcp 0:src 1:dst'"); cp.addHandler(lsHandler, "ls", "Use 'ls 0:' for Flash, or 'ls 1:' for SD Card"); cp.addHandler(mkdirHandler, "mkdir", "Create a directory. Ex: 'mkdir test'"); cp.addHandler(mvHandler, "mv", "Rename a file. Ex: 'rm 0:file.txt 0:new.txt'"); cp.addHandler(newFileHandler,"nf", "Write a new file. Ex: 'nf <file.txt>"); cp.addHandler(rmHandler, "rm", "Remove a file. Ex: 'rm 0:file.txt'"); // Misc. handlers cp.addHandler(i2cIoHandler, "i2c", "'i2c read 0x01 0x02 <count>' : Reads device 0x01, and register 0x02\n" "'i2c write 0x01 0x02 0x03' : Writes device 0x01, reg 0x02, data 0x03\n" "'i2c discover' : Discover I2C devices"); #if TERMINAL_USE_CAN_BUS_HANDLER CMD_HANDLER_FUNC(canBusHandler); cp.addHandler(canBusHandler, "canbus", "'canbus init' : initialize CAN-1\n" "'canbus filter <id>' : Add 29-bit ID fitler\n" "'canbus tx <msg id> <len> <byte0> <byte1> ...' : Send CAN Message\n" "'canbus rx <timeout in ms>' : Receive a CAN message\n" "'canbus registers' : See some of CAN BUS registers"); #endif cp.addHandler(storageHandler, "storage", "Parameters: 'format sd', 'format flash', 'mount sd', 'mount flash'"); cp.addHandler(rebootHandler, "reboot", "Reboots the system"); cp.addHandler(logHandler, "log", "'log <hello>': log an info message\n" "'log flush' : flush the logs\n" "' log status': get status of the logger\n" "'log enableprint debug/info/warn/error' : Enables logger calls to printf\n" "'log disableprint debug/info/warn/error': Disables logger calls to printf\n" ); cp.addHandler(learnIrHandler, "learn", "Begin to learn IR codes for numbers 0-9"); cp.addHandler(wirelessHandler, "wireless", "Use 'wireless' to see the nested commands"); /* Firmware upgrade handlers * Please read "netload_readme.txt" at ref_and_datasheets directory. */ CMD_HANDLER_FUNC(getFileHandler); CMD_HANDLER_FUNC(flashProgHandler); cp.addHandler(getFileHandler, "file", "Get a file using netload.exe or by using the following protocol:\n" "Write buffer: buffer <offset> <num bytes> ...\n" "Write buffer to file: commit <filename> <file offset> <num bytes from buffer>"); cp.addHandler(flashProgHandler, "flash", "'flash <filename>' Will flash CPU with this new binary file"); #if (SYS_CFG_ENABLE_TLM) cp.addHandler(telemetryHandler, "telemetry", "Outputs registered telemetry: " "'telemetry save' : Saves disk tel\n" "'telemetry ascii' : Prints all telemetry in human readable format\n" "'telemetry <comp. name> <name> <value>' to set a telemetry variable\n" "'telemetry get <comp. name> <name>' to get variable value\n"); #endif // Initialize Interrupt driven version of getchar & putchar Uart0& uart0 = Uart0::getInstance(); bool success = uart0.init(SYS_CFG_UART0_BPS, 32, SYS_CFG_UART0_TXQ_SIZE); uart0.setReady(true); sys_set_inchar_func(uart0.getcharIntrDriven); sys_set_outchar_func(uart0.putcharIntrDriven); /* Add UART0 to command input/output */ addCommandChannel(&uart0, true); #if TERMINAL_USE_NRF_WIRELESS do { NordicStream& nrf = NordicStream::getInstance(); nrf.setReady(true); addCommandChannel(&nrf, false); } while(0); #endif #if SYS_CFG_ENABLE_TLM /* Telemetry should be registered at this point, so initialize the binary * telemetry space that we periodically check to save data to disk */ tlm_component *disk = tlm_component_get_by_name(SYS_CFG_DISK_TLM_NAME); mDiskTlmSize = tlm_binary_get_size_one(disk); mpBinaryDiskTlm = new char[mDiskTlmSize]; if (success) { success = (NULL != mpBinaryDiskTlm); } /* Now update our copy of disk telemetry */ tlm_binary_get_one(disk, mpBinaryDiskTlm); #endif /* Display "help" command on UART0 */ STR_ON_STACK(help, 8); help = "help"; mCmdProc.handleCommand(help, uart0); return success; }