Test
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,3 +4,5 @@ CMakeCache.txt
|
||||
timeout
|
||||
cmake_install.cmake
|
||||
serial-port/
|
||||
lib/
|
||||
Ymodem*/
|
||||
@@ -4,8 +4,9 @@ project(TEST)
|
||||
|
||||
## Target
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(TEST_SRCS main.cpp TimeoutSerial.cpp)
|
||||
set(TEST_SRCS main.cpp TimeoutSerial.cpp XModem.cpp)
|
||||
add_executable(timeout ${TEST_SRCS})
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
## Link libraries
|
||||
set(BOOST_LIBS date_time system)
|
||||
|
||||
30
Makefile
30
Makefile
@@ -150,6 +150,33 @@ TimeoutSerial.cpp.s:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/TimeoutSerial.cpp.s
|
||||
.PHONY : TimeoutSerial.cpp.s
|
||||
|
||||
XModem.o: XModem.cpp.o
|
||||
|
||||
.PHONY : XModem.o
|
||||
|
||||
# target to build an object file
|
||||
XModem.cpp.o:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/XModem.cpp.o
|
||||
.PHONY : XModem.cpp.o
|
||||
|
||||
XModem.i: XModem.cpp.i
|
||||
|
||||
.PHONY : XModem.i
|
||||
|
||||
# target to preprocess a source file
|
||||
XModem.cpp.i:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/XModem.cpp.i
|
||||
.PHONY : XModem.cpp.i
|
||||
|
||||
XModem.s: XModem.cpp.s
|
||||
|
||||
.PHONY : XModem.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
XModem.cpp.s:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/XModem.cpp.s
|
||||
.PHONY : XModem.cpp.s
|
||||
|
||||
main.o: main.cpp.o
|
||||
|
||||
.PHONY : main.o
|
||||
@@ -189,6 +216,9 @@ help:
|
||||
@echo "... TimeoutSerial.o"
|
||||
@echo "... TimeoutSerial.i"
|
||||
@echo "... TimeoutSerial.s"
|
||||
@echo "... XModem.o"
|
||||
@echo "... XModem.i"
|
||||
@echo "... XModem.s"
|
||||
@echo "... main.o"
|
||||
@echo "... main.i"
|
||||
@echo "... main.s"
|
||||
|
||||
@@ -141,8 +141,11 @@ int TimeoutSerial::readChar(int delay)
|
||||
timeout = posix_time::seconds(delay);
|
||||
try {
|
||||
result = read(1);
|
||||
return static_cast<int>(result[0]);
|
||||
std::cerr << std::hex << (uint8_t
|
||||
)result[0] << endl;
|
||||
return static_cast<u_int8_t>(result[0]);
|
||||
} catch (boost::system::system_error& e) {
|
||||
cerr << "EOF" << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
12
XModem.cpp
12
XModem.cpp
@@ -21,7 +21,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "XModem.h"
|
||||
#include "TimeoutSerial.h"
|
||||
|
||||
#ifdef UTEST
|
||||
#include "CppUTestExt/MockSupport.h"
|
||||
#endif
|
||||
@@ -32,7 +32,7 @@ const unsigned char XModem::SOH = 1;
|
||||
const unsigned char XModem::EOT = 4;
|
||||
const unsigned char XModem::CAN = 0x18;
|
||||
|
||||
const int XModem::receiveDelay=7000;
|
||||
const int XModem::receiveDelay=7;
|
||||
const int XModem::rcvRetryLimit = 10;
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ bool XModem::dataAvail(int delay)
|
||||
{
|
||||
if (this->byte != -1)
|
||||
return true;
|
||||
if ((this->byte = this->recvChar(delay)) != -1)
|
||||
if ((this->byte = this->serial->readChar(delay)) != -1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -68,11 +68,11 @@ int XModem::dataRead(int delay)
|
||||
this->byte = -1;
|
||||
return b;
|
||||
}
|
||||
return this->recvChar(delay);
|
||||
return this->serial->readChar(delay);
|
||||
}
|
||||
void XModem::dataWrite(char symbol)
|
||||
{
|
||||
this->sendData(&symbol, 1);
|
||||
this->serial->write(&symbol, 1);
|
||||
}
|
||||
bool XModem::receiveFrameNo()
|
||||
{
|
||||
@@ -148,7 +148,7 @@ bool XModem::receiveFrames(transfer_t transfer)
|
||||
this->blockNoExt = 1;
|
||||
this->retries = 0;
|
||||
while (1) {
|
||||
char cmd = this->dataRead(1000);
|
||||
char cmd = this->dataRead(10);
|
||||
switch(cmd){
|
||||
case XModem::SOH:
|
||||
if (!this->receiveFrameNo()) {
|
||||
|
||||
1
XModem.h
1
XModem.h
@@ -16,6 +16,7 @@
|
||||
// along with this program; if not, write to the Free Software Foundation,
|
||||
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// -----------------------------------------------------------------------------
|
||||
#include "TimeoutSerial.h"
|
||||
|
||||
typedef enum {
|
||||
Crc,
|
||||
|
||||
1
build/.cmake/api/v1/query/client-vscode/query.json
Normal file
1
build/.cmake/api/v1/query/client-vscode/query.json
Normal file
@@ -0,0 +1 @@
|
||||
{"requests":[{"kind":"cache","version":2},{"kind":"codemodel","version":2},{"kind":"toolchains","version":1}]}
|
||||
1327
build/.cmake/api/v1/reply/cache-v2-053ee6e25f83c56b3f05.json
Normal file
1327
build/.cmake/api/v1/reply/cache-v2-053ee6e25f83c56b3f05.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"configurations" :
|
||||
[
|
||||
{
|
||||
"directories" :
|
||||
[
|
||||
{
|
||||
"build" : ".",
|
||||
"minimumCMakeVersion" :
|
||||
{
|
||||
"string" : "3.1"
|
||||
},
|
||||
"projectIndex" : 0,
|
||||
"source" : ".",
|
||||
"targetIndexes" :
|
||||
[
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"name" : "Debug",
|
||||
"projects" :
|
||||
[
|
||||
{
|
||||
"directoryIndexes" :
|
||||
[
|
||||
0
|
||||
],
|
||||
"name" : "TEST",
|
||||
"targetIndexes" :
|
||||
[
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"targets" :
|
||||
[
|
||||
{
|
||||
"directoryIndex" : 0,
|
||||
"id" : "timeout::@6890427a1f51a3e7e1df",
|
||||
"jsonFile" : "target-timeout-Debug-6fb942df9d75cf9b39de.json",
|
||||
"name" : "timeout",
|
||||
"projectIndex" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"kind" : "codemodel",
|
||||
"paths" :
|
||||
{
|
||||
"build" : "/home/jaro/serialport-downloader/build",
|
||||
"source" : "/home/jaro/serialport-downloader"
|
||||
},
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"cmake" :
|
||||
{
|
||||
"generator" :
|
||||
{
|
||||
"name" : "Unix Makefiles"
|
||||
},
|
||||
"paths" :
|
||||
{
|
||||
"cmake" : "/usr/bin/cmake",
|
||||
"cpack" : "/usr/bin/cpack",
|
||||
"ctest" : "/usr/bin/ctest",
|
||||
"root" : "/usr/share/cmake-3.16"
|
||||
},
|
||||
"version" :
|
||||
{
|
||||
"isDirty" : false,
|
||||
"major" : 3,
|
||||
"minor" : 16,
|
||||
"patch" : 3,
|
||||
"string" : "3.16.3",
|
||||
"suffix" : ""
|
||||
}
|
||||
},
|
||||
"objects" :
|
||||
[
|
||||
{
|
||||
"jsonFile" : "codemodel-v2-a67eb6c77230df2253b5.json",
|
||||
"kind" : "codemodel",
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"jsonFile" : "cache-v2-053ee6e25f83c56b3f05.json",
|
||||
"kind" : "cache",
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"reply" :
|
||||
{
|
||||
"client-vscode" :
|
||||
{
|
||||
"query.json" :
|
||||
{
|
||||
"requests" :
|
||||
[
|
||||
{
|
||||
"kind" : "cache",
|
||||
"version" : 2
|
||||
},
|
||||
{
|
||||
"kind" : "codemodel",
|
||||
"version" : 2
|
||||
},
|
||||
{
|
||||
"kind" : "toolchains",
|
||||
"version" : 1
|
||||
}
|
||||
],
|
||||
"responses" :
|
||||
[
|
||||
{
|
||||
"jsonFile" : "cache-v2-053ee6e25f83c56b3f05.json",
|
||||
"kind" : "cache",
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"jsonFile" : "codemodel-v2-a67eb6c77230df2253b5.json",
|
||||
"kind" : "codemodel",
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"error" : "unknown request kind 'toolchains'"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"artifacts" :
|
||||
[
|
||||
{
|
||||
"path" : "timeout"
|
||||
}
|
||||
],
|
||||
"backtrace" : 1,
|
||||
"backtraceGraph" :
|
||||
{
|
||||
"commands" :
|
||||
[
|
||||
"add_executable",
|
||||
"target_link_libraries"
|
||||
],
|
||||
"files" :
|
||||
[
|
||||
"CMakeLists.txt"
|
||||
],
|
||||
"nodes" :
|
||||
[
|
||||
{
|
||||
"file" : 0
|
||||
},
|
||||
{
|
||||
"command" : 0,
|
||||
"file" : 0,
|
||||
"line" : 8,
|
||||
"parent" : 0
|
||||
},
|
||||
{
|
||||
"command" : 1,
|
||||
"file" : 0,
|
||||
"line" : 14,
|
||||
"parent" : 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"compileGroups" :
|
||||
[
|
||||
{
|
||||
"compileCommandFragments" :
|
||||
[
|
||||
{
|
||||
"fragment" : "-g "
|
||||
},
|
||||
{
|
||||
"fragment" : "-std=gnu++11"
|
||||
}
|
||||
],
|
||||
"defines" :
|
||||
[
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"define" : "BOOST_ALL_NO_LIB"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"define" : "BOOST_DATE_TIME_DYN_LINK"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"define" : "BOOST_SYSTEM_DYN_LINK"
|
||||
}
|
||||
],
|
||||
"language" : "CXX",
|
||||
"sourceIndexes" :
|
||||
[
|
||||
0,
|
||||
1,
|
||||
2
|
||||
]
|
||||
}
|
||||
],
|
||||
"id" : "timeout::@6890427a1f51a3e7e1df",
|
||||
"link" :
|
||||
{
|
||||
"commandFragments" :
|
||||
[
|
||||
{
|
||||
"fragment" : "-g",
|
||||
"role" : "flags"
|
||||
},
|
||||
{
|
||||
"fragment" : "-rdynamic",
|
||||
"role" : "flags"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"fragment" : "/usr/lib/x86_64-linux-gnu/libboost_date_time.so.1.71.0",
|
||||
"role" : "libraries"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"fragment" : "/usr/lib/x86_64-linux-gnu/libboost_system.so.1.71.0",
|
||||
"role" : "libraries"
|
||||
},
|
||||
{
|
||||
"fragment" : "-lpthread",
|
||||
"role" : "libraries"
|
||||
}
|
||||
],
|
||||
"language" : "CXX"
|
||||
},
|
||||
"name" : "timeout",
|
||||
"nameOnDisk" : "timeout",
|
||||
"paths" :
|
||||
{
|
||||
"build" : ".",
|
||||
"source" : "."
|
||||
},
|
||||
"sourceGroups" :
|
||||
[
|
||||
{
|
||||
"name" : "Source Files",
|
||||
"sourceIndexes" :
|
||||
[
|
||||
0,
|
||||
1,
|
||||
2
|
||||
]
|
||||
}
|
||||
],
|
||||
"sources" :
|
||||
[
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "main.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "TimeoutSerial.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "XModem.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
}
|
||||
],
|
||||
"type" : "EXECUTABLE"
|
||||
}
|
||||
238
build/Makefile
Normal file
238
build/Makefile
Normal file
@@ -0,0 +1,238 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.16
|
||||
|
||||
# Default target executed when no arguments are given to make.
|
||||
default_target: all
|
||||
|
||||
.PHONY : default_target
|
||||
|
||||
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
|
||||
.NOTPARALLEL:
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Special targets provided by cmake.
|
||||
|
||||
# Disable implicit rules so canonical targets will work.
|
||||
.SUFFIXES:
|
||||
|
||||
|
||||
# Remove some rules from gmake that .SUFFIXES does not remove.
|
||||
SUFFIXES =
|
||||
|
||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
||||
|
||||
|
||||
# Suppress display of executed commands.
|
||||
$(VERBOSE).SILENT:
|
||||
|
||||
|
||||
# A target that is always out of date.
|
||||
cmake_force:
|
||||
|
||||
.PHONY : cmake_force
|
||||
|
||||
#=============================================================================
|
||||
# Set environment variables for the build.
|
||||
|
||||
# The shell in which to execute make rules.
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The CMake executable.
|
||||
CMAKE_COMMAND = /usr/bin/cmake
|
||||
|
||||
# The command to remove a file.
|
||||
RM = /usr/bin/cmake -E remove -f
|
||||
|
||||
# Escaping for special characters.
|
||||
EQUALS = =
|
||||
|
||||
# The top-level source directory on which CMake was run.
|
||||
CMAKE_SOURCE_DIR = /home/jaro/serialport-downloader
|
||||
|
||||
# The top-level build directory on which CMake was run.
|
||||
CMAKE_BINARY_DIR = /home/jaro/serialport-downloader/build
|
||||
|
||||
#=============================================================================
|
||||
# Targets provided globally by CMake.
|
||||
|
||||
# Special rule for the target rebuild_cache
|
||||
rebuild_cache:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
|
||||
/usr/bin/cmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
||||
.PHONY : rebuild_cache
|
||||
|
||||
# Special rule for the target rebuild_cache
|
||||
rebuild_cache/fast: rebuild_cache
|
||||
|
||||
.PHONY : rebuild_cache/fast
|
||||
|
||||
# Special rule for the target edit_cache
|
||||
edit_cache:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..."
|
||||
/usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
|
||||
.PHONY : edit_cache
|
||||
|
||||
# Special rule for the target edit_cache
|
||||
edit_cache/fast: edit_cache
|
||||
|
||||
.PHONY : edit_cache/fast
|
||||
|
||||
# The main all target
|
||||
all: cmake_check_build_system
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /home/jaro/serialport-downloader/build/CMakeFiles /home/jaro/serialport-downloader/build/CMakeFiles/progress.marks
|
||||
$(MAKE) -f CMakeFiles/Makefile2 all
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /home/jaro/serialport-downloader/build/CMakeFiles 0
|
||||
.PHONY : all
|
||||
|
||||
# The main clean target
|
||||
clean:
|
||||
$(MAKE) -f CMakeFiles/Makefile2 clean
|
||||
.PHONY : clean
|
||||
|
||||
# The main clean target
|
||||
clean/fast: clean
|
||||
|
||||
.PHONY : clean/fast
|
||||
|
||||
# Prepare targets for installation.
|
||||
preinstall: all
|
||||
$(MAKE) -f CMakeFiles/Makefile2 preinstall
|
||||
.PHONY : preinstall
|
||||
|
||||
# Prepare targets for installation.
|
||||
preinstall/fast:
|
||||
$(MAKE) -f CMakeFiles/Makefile2 preinstall
|
||||
.PHONY : preinstall/fast
|
||||
|
||||
# clear depends
|
||||
depend:
|
||||
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
|
||||
.PHONY : depend
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named timeout
|
||||
|
||||
# Build rule for target.
|
||||
timeout: cmake_check_build_system
|
||||
$(MAKE) -f CMakeFiles/Makefile2 timeout
|
||||
.PHONY : timeout
|
||||
|
||||
# fast build rule for target.
|
||||
timeout/fast:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/build
|
||||
.PHONY : timeout/fast
|
||||
|
||||
TimeoutSerial.o: TimeoutSerial.cpp.o
|
||||
|
||||
.PHONY : TimeoutSerial.o
|
||||
|
||||
# target to build an object file
|
||||
TimeoutSerial.cpp.o:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/TimeoutSerial.cpp.o
|
||||
.PHONY : TimeoutSerial.cpp.o
|
||||
|
||||
TimeoutSerial.i: TimeoutSerial.cpp.i
|
||||
|
||||
.PHONY : TimeoutSerial.i
|
||||
|
||||
# target to preprocess a source file
|
||||
TimeoutSerial.cpp.i:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/TimeoutSerial.cpp.i
|
||||
.PHONY : TimeoutSerial.cpp.i
|
||||
|
||||
TimeoutSerial.s: TimeoutSerial.cpp.s
|
||||
|
||||
.PHONY : TimeoutSerial.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
TimeoutSerial.cpp.s:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/TimeoutSerial.cpp.s
|
||||
.PHONY : TimeoutSerial.cpp.s
|
||||
|
||||
XModem.o: XModem.cpp.o
|
||||
|
||||
.PHONY : XModem.o
|
||||
|
||||
# target to build an object file
|
||||
XModem.cpp.o:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/XModem.cpp.o
|
||||
.PHONY : XModem.cpp.o
|
||||
|
||||
XModem.i: XModem.cpp.i
|
||||
|
||||
.PHONY : XModem.i
|
||||
|
||||
# target to preprocess a source file
|
||||
XModem.cpp.i:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/XModem.cpp.i
|
||||
.PHONY : XModem.cpp.i
|
||||
|
||||
XModem.s: XModem.cpp.s
|
||||
|
||||
.PHONY : XModem.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
XModem.cpp.s:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/XModem.cpp.s
|
||||
.PHONY : XModem.cpp.s
|
||||
|
||||
main.o: main.cpp.o
|
||||
|
||||
.PHONY : main.o
|
||||
|
||||
# target to build an object file
|
||||
main.cpp.o:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/main.cpp.o
|
||||
.PHONY : main.cpp.o
|
||||
|
||||
main.i: main.cpp.i
|
||||
|
||||
.PHONY : main.i
|
||||
|
||||
# target to preprocess a source file
|
||||
main.cpp.i:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/main.cpp.i
|
||||
.PHONY : main.cpp.i
|
||||
|
||||
main.s: main.cpp.s
|
||||
|
||||
.PHONY : main.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
main.cpp.s:
|
||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/main.cpp.s
|
||||
.PHONY : main.cpp.s
|
||||
|
||||
# Help Target
|
||||
help:
|
||||
@echo "The following are some of the valid targets for this Makefile:"
|
||||
@echo "... all (the default if no target is provided)"
|
||||
@echo "... clean"
|
||||
@echo "... depend"
|
||||
@echo "... rebuild_cache"
|
||||
@echo "... edit_cache"
|
||||
@echo "... timeout"
|
||||
@echo "... TimeoutSerial.o"
|
||||
@echo "... TimeoutSerial.i"
|
||||
@echo "... TimeoutSerial.s"
|
||||
@echo "... XModem.o"
|
||||
@echo "... XModem.i"
|
||||
@echo "... XModem.s"
|
||||
@echo "... main.o"
|
||||
@echo "... main.i"
|
||||
@echo "... main.s"
|
||||
.PHONY : help
|
||||
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Special targets to cleanup operation of make.
|
||||
|
||||
# Special rule to run CMake to check the build system integrity.
|
||||
# No rule that depends on this can have commands that come from listfiles
|
||||
# because they might be regenerated.
|
||||
cmake_check_build_system:
|
||||
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
|
||||
.PHONY : cmake_check_build_system
|
||||
|
||||
17
build/compile_commands.json
Normal file
17
build/compile_commands.json
Normal file
@@ -0,0 +1,17 @@
|
||||
[
|
||||
{
|
||||
"directory": "/home/jaro/serialport-downloader/build",
|
||||
"command": "/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_DATE_TIME_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -g -std=gnu++11 -o CMakeFiles/timeout.dir/main.cpp.o -c /home/jaro/serialport-downloader/main.cpp",
|
||||
"file": "/home/jaro/serialport-downloader/main.cpp"
|
||||
},
|
||||
{
|
||||
"directory": "/home/jaro/serialport-downloader/build",
|
||||
"command": "/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_DATE_TIME_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -g -std=gnu++11 -o CMakeFiles/timeout.dir/TimeoutSerial.cpp.o -c /home/jaro/serialport-downloader/TimeoutSerial.cpp",
|
||||
"file": "/home/jaro/serialport-downloader/TimeoutSerial.cpp"
|
||||
},
|
||||
{
|
||||
"directory": "/home/jaro/serialport-downloader/build",
|
||||
"command": "/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_DATE_TIME_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -g -std=gnu++11 -o CMakeFiles/timeout.dir/XModem.cpp.o -c /home/jaro/serialport-downloader/XModem.cpp",
|
||||
"file": "/home/jaro/serialport-downloader/XModem.cpp"
|
||||
}
|
||||
]
|
||||
35
main.cpp
35
main.cpp
@@ -9,12 +9,24 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include "TimeoutSerial.h"
|
||||
#include "XModem.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
typedef vector< string > split_vector_type;
|
||||
|
||||
bool dataHandler(unsigned long blockNo, char* buffer, int size)
|
||||
{
|
||||
cout << "Block No. = " << blockNo << endl;
|
||||
for (int i=0 ; i<size ; i++) {
|
||||
cout << char(buffer[i]) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
string line;
|
||||
@@ -65,6 +77,29 @@ int main(int argc, char* argv[])
|
||||
cout << "vlhkost = " << humidity << endl;
|
||||
cout << "tlak = " << pressure << endl;
|
||||
|
||||
XModem modem(&serial,dataHandler);
|
||||
|
||||
serial.writeString("capture\r\n");
|
||||
sleep(1);
|
||||
line = serial.readStringUntil("\r\n");
|
||||
cout << line << endl;
|
||||
line = serial.readStringUntil("\r\n");
|
||||
cout << line << endl;
|
||||
line = serial.readStringUntil("\r\n");
|
||||
cout << line << endl;
|
||||
line = serial.readStringUntil("\r\n");
|
||||
cout << line << endl;
|
||||
// line = serial.readStringUntil("\r\n");
|
||||
// cout << line << endl;
|
||||
|
||||
serial.writeString("rb\r\n");
|
||||
sleep(1);
|
||||
serial.readChar(1);
|
||||
serial.readChar(1);
|
||||
modem.receive();
|
||||
sleep(1);
|
||||
serial.writeString("free\r\n");
|
||||
|
||||
serial.close();
|
||||
|
||||
} catch(boost::system::system_error& e)
|
||||
|
||||
597
xymodem.c
Normal file
597
xymodem.c
Normal file
@@ -0,0 +1,597 @@
|
||||
/*
|
||||
* Handles the X-Modem, Y-Modem and Y-Modem/G protocols
|
||||
*
|
||||
* Copyright (C) 2008 Robert Jarzmik
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This file provides functions to receive X-Modem or Y-Modem(/G) protocols.
|
||||
*
|
||||
* References:
|
||||
* *-Modem: http://www.techfest.com/hardware/modem/xymodem.htm
|
||||
* XMODEM/YMODEM PROTOCOL REFERENCE, Chuck Forsberg
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <xfuncs.h>
|
||||
#include <errno.h>
|
||||
#include <crc.h>
|
||||
#include <clock.h>
|
||||
#include <console.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <fs.h>
|
||||
#include <kfifo.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <xymodem.h>
|
||||
|
||||
#define xy_dbg(fmt, args...)
|
||||
|
||||
/* Values magic to the protocol */
|
||||
#define SOH 0x01
|
||||
#define STX 0x02
|
||||
#define EOT 0x04
|
||||
#define ACK 0x06
|
||||
#define BSP 0x08
|
||||
#define NAK 0x15
|
||||
#define CAN 0x18
|
||||
|
||||
#define PROTO_XMODEM 0
|
||||
#define PROTO_YMODEM 1
|
||||
#define PROTO_YMODEM_G 2
|
||||
#define MAX_PROTOS 3
|
||||
|
||||
#define CRC_NONE 0 /* No CRC checking */
|
||||
#define CRC_ADD8 1 /* Add of all data bytes */
|
||||
#define CRC_CRC16 2 /* CCCIT CRC16 */
|
||||
#define MAX_CRCS 3
|
||||
|
||||
#define MAX_RETRIES 10
|
||||
#define MAX_RETRIES_WITH_CRC 5
|
||||
#define TIMEOUT_READ (1 * SECOND)
|
||||
#define TIMEOUT_FLUSH (1 * SECOND)
|
||||
#define MAX_CAN_BEFORE_ABORT 5
|
||||
#define INPUT_FIFO_SIZE (4 * 1024) /* Should always be > 1029 */
|
||||
|
||||
enum proto_state {
|
||||
PROTO_STATE_GET_FILENAME = 0,
|
||||
PROTO_STATE_NEGOCIATE_CRC,
|
||||
PROTO_STATE_RECEIVE_BODY,
|
||||
PROTO_STATE_FINISHED_FILE,
|
||||
PROTO_STATE_FINISHED_XFER,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct xyz_ctxt - context of a x/y modem (g) transfer
|
||||
*
|
||||
* @cdev: console device to support *MODEM transfer
|
||||
* @fifo: fifo to buffer input from serial line
|
||||
* This is necessary for low hardware FIFOs buffers as UARTs.
|
||||
* @mode: protocol (XMODEM, YMODEM or YMODEM/G)
|
||||
* @crc_mode: CRC_NONE, CRC_ADD8 or CRC_CRC16
|
||||
* @state: protocol state (as in "state machine")
|
||||
* @buf: buffer to store the last tranfered buffer chunk
|
||||
* @filename : filename transmitted by sender (YMODEM* only)
|
||||
* @fd : file descriptor of the current stored file
|
||||
* @file_len: length declared by sender (YMODEM* only)
|
||||
* @nb_received: number of data bytes received since session open
|
||||
* (this doesn't count resends)
|
||||
* @total_SOH: number of SOH frames received (128 bytes chunks)
|
||||
* @total_STX: number of STX frames received (1024 bytes chunks)
|
||||
* @total_CAN: nubmer of CAN frames received (cancel frames)
|
||||
*/
|
||||
struct xyz_ctxt {
|
||||
struct console_device *cdev;
|
||||
struct kfifo *fifo;
|
||||
int mode;
|
||||
int crc_mode;
|
||||
enum proto_state state;
|
||||
char filename[1024];
|
||||
int fd;
|
||||
int file_len;
|
||||
int nb_received;
|
||||
int next_blk;
|
||||
int total_SOH, total_STX, total_CAN, total_retries;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct xy_block - one unitary block of x/y modem (g) transfer
|
||||
*
|
||||
* @buf: data buffer
|
||||
* @len: length of data buffer (can only be 128 or 1024)
|
||||
* @seq: block sequence number (as in X/Y/YG MODEM protocol)
|
||||
*/
|
||||
struct xy_block {
|
||||
unsigned char buf[1024];
|
||||
int len;
|
||||
int seq;
|
||||
};
|
||||
|
||||
/*
|
||||
* For XMODEM/YMODEM, always try to use the CRC16 versions, called also
|
||||
* XMODEM/CRC and YMODEM.
|
||||
* Only fallback to additive CRC (8 bits) if sender doesn't cope with CRC16.
|
||||
*/
|
||||
static const char invite_filename_hdr[MAX_PROTOS][MAX_CRCS] = {
|
||||
{ 0, NAK, 'C' }, /* XMODEM */
|
||||
{ 0, NAK, 'C' }, /* YMODEM */
|
||||
{ 0, 'G', 'G' }, /* YMODEM-G */
|
||||
};
|
||||
|
||||
static const char invite_file_body[MAX_PROTOS][MAX_CRCS] = {
|
||||
{ 0, NAK, 'C' }, /* XMODEM */
|
||||
{ 0, NAK, 'C' }, /* YMODEM */
|
||||
{ 0, 'G', 'G' }, /* YMODEM-G */
|
||||
};
|
||||
|
||||
static const char block_ack[MAX_PROTOS][MAX_CRCS] = {
|
||||
{ 0, ACK, ACK }, /* XMODEM */
|
||||
{ 0, ACK, ACK }, /* YMODEM */
|
||||
{ 0, 0, 0 }, /* YMODEM-G */
|
||||
};
|
||||
|
||||
static const char block_nack[MAX_PROTOS][MAX_CRCS] = {
|
||||
{ 0, NAK, NAK }, /* XMODEM */
|
||||
{ 0, NAK, NAK }, /* YMODEM */
|
||||
{ 0, 0, 0 }, /* YMODEM-G */
|
||||
};
|
||||
|
||||
static int input_fifo_fill(struct console_device *cdev, struct kfifo *fifo)
|
||||
{
|
||||
while (cdev->tstc(cdev) && kfifo_len(fifo) < INPUT_FIFO_SIZE)
|
||||
kfifo_putc(fifo, (unsigned char)(cdev->getc(cdev)));
|
||||
return kfifo_len(fifo);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is optimized to :
|
||||
* - maximize throughput (ie. read as much as is available in lower layer fifo)
|
||||
* - minimize latencies (no delay or wait timeout if data available)
|
||||
* - have a timeout
|
||||
* This is why standard getc() is not used, and input_fifo_fill() exists.
|
||||
*/
|
||||
static int xy_gets(struct console_device *cdev, struct kfifo *fifo,
|
||||
unsigned char *buf, int len, uint64_t timeout)
|
||||
{
|
||||
int i, rc;
|
||||
uint64_t start = get_time_ns();
|
||||
|
||||
for (i = 0, rc = 0; rc >= 0 && i < len; ) {
|
||||
if (is_timeout(start, timeout)) {
|
||||
rc = -ETIMEDOUT;
|
||||
continue;
|
||||
}
|
||||
if (input_fifo_fill(cdev, fifo))
|
||||
kfifo_getc(fifo, &buf[i++]);
|
||||
}
|
||||
|
||||
return rc < 0 ? rc : i;
|
||||
}
|
||||
|
||||
static void xy_putc(struct console_device *cdev, unsigned char c)
|
||||
{
|
||||
cdev->putc(cdev, c);
|
||||
}
|
||||
|
||||
static void xy_flush(struct console_device *cdev, struct kfifo *fifo)
|
||||
{
|
||||
uint64_t start;
|
||||
|
||||
start = get_time_ns();
|
||||
while (cdev->tstc(cdev) &&
|
||||
!is_timeout(start, TIMEOUT_FLUSH))
|
||||
cdev->getc(cdev);
|
||||
mdelay(250);
|
||||
while (cdev->tstc(cdev) &&
|
||||
!is_timeout(start, TIMEOUT_FLUSH))
|
||||
cdev->getc(cdev);
|
||||
kfifo_reset(fifo);
|
||||
}
|
||||
|
||||
static int is_xmodem(struct xyz_ctxt *proto)
|
||||
{
|
||||
return proto->mode == PROTO_XMODEM;
|
||||
}
|
||||
|
||||
static void xy_block_ack(struct xyz_ctxt *proto)
|
||||
{
|
||||
unsigned char c = block_ack[proto->mode][proto->crc_mode];
|
||||
|
||||
if (c)
|
||||
xy_putc(proto->cdev, c);
|
||||
}
|
||||
|
||||
static void xy_block_nack(struct xyz_ctxt *proto)
|
||||
{
|
||||
unsigned char c = block_nack[proto->mode][proto->crc_mode];
|
||||
|
||||
if (c)
|
||||
xy_putc(proto->cdev, c);
|
||||
proto->total_retries++;
|
||||
}
|
||||
|
||||
static int check_crc(unsigned char *buf, int len, int crc, int crc_mode)
|
||||
{
|
||||
unsigned char crc8 = 0;
|
||||
uint16_t crc16;
|
||||
int i;
|
||||
|
||||
switch (crc_mode) {
|
||||
case CRC_ADD8:
|
||||
for (i = 0; i < len; i++)
|
||||
crc8 += buf[i];
|
||||
return crc8 == crc ? 0 : -EBADMSG;
|
||||
case CRC_CRC16:
|
||||
crc16 = cyg_crc16(buf, len);
|
||||
xy_dbg("crc16: received = %x, calculated=%x\n", crc, crc16);
|
||||
return crc16 == crc ? 0 : -EBADMSG;
|
||||
case CRC_NONE:
|
||||
return 0;
|
||||
default:
|
||||
return -EBADMSG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* xy_read_block - read a X-Modem or Y-Modem(G) block
|
||||
* @proto: protocol control structure
|
||||
* @blk: block read
|
||||
* @timeout: maximal time to get data
|
||||
*
|
||||
* This is the pivotal function for block receptions. It attempts to receive one
|
||||
* block, ie. one 128 bytes or one 1024 bytes block. The received data can also
|
||||
* be an end of transmission, or a cancel.
|
||||
*
|
||||
* Returns :
|
||||
* >0 : size of the received block
|
||||
* 0 : last block, ie. end of transmission, ie. EOT
|
||||
* -EBADMSG : malformed message (ie. sequence bi-bytes are not
|
||||
* complementary), or CRC check error
|
||||
* -EILSEQ : block sequence number error wrt previously received block
|
||||
* -ETIMEDOUT : block not received before timeout passed
|
||||
* -ECONNABORTED : transfer aborted by sender, ie. CAN
|
||||
*/
|
||||
static ssize_t xy_read_block(struct xyz_ctxt *proto, struct xy_block *blk,
|
||||
uint64_t timeout)
|
||||
{
|
||||
ssize_t rc, data_len = 0;
|
||||
unsigned char hdr, seqs[2], crcs[2];
|
||||
int crc = 0;
|
||||
bool hdr_found = 0;
|
||||
uint64_t start = get_time_ns();
|
||||
|
||||
while (!hdr_found) {
|
||||
rc = xy_gets(proto->cdev, proto->fifo, &hdr, 1, timeout);
|
||||
xy_dbg("read 0x%x(%c) -> %d\n", hdr, hdr, rc);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
if (is_timeout(start, timeout))
|
||||
goto timeout;
|
||||
switch (hdr) {
|
||||
case SOH:
|
||||
data_len = 128;
|
||||
hdr_found = 1;
|
||||
proto->total_SOH++;
|
||||
break;
|
||||
case STX:
|
||||
data_len = 1024;
|
||||
hdr_found = 1;
|
||||
proto->total_STX++;
|
||||
break;
|
||||
case CAN:
|
||||
rc = -ECONNABORTED;
|
||||
if (proto->total_CAN++ > MAX_CAN_BEFORE_ABORT)
|
||||
goto out;
|
||||
break;
|
||||
case EOT:
|
||||
rc = 0;
|
||||
blk->len = 0;
|
||||
goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
blk->seq = 0;
|
||||
rc = xy_gets(proto->cdev, proto->fifo, seqs, 2, timeout);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
blk->seq = seqs[0];
|
||||
if (255 - seqs[0] != seqs[1])
|
||||
return -EBADMSG;
|
||||
|
||||
rc = xy_gets(proto->cdev, proto->fifo, blk->buf, data_len, timeout);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
blk->len = rc;
|
||||
|
||||
switch (proto->crc_mode) {
|
||||
case CRC_ADD8:
|
||||
rc = xy_gets(proto->cdev, proto->fifo, crcs, 1, timeout);
|
||||
crc = crcs[0];
|
||||
break;
|
||||
case CRC_CRC16:
|
||||
rc = xy_gets(proto->cdev, proto->fifo, crcs, 2, timeout);
|
||||
crc = (crcs[0] << 8) + crcs[1];
|
||||
break;
|
||||
case CRC_NONE:
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
rc = check_crc(blk->buf, data_len, crc, proto->crc_mode);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
return data_len;
|
||||
timeout:
|
||||
return -ETIMEDOUT;
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int check_blk_seq(struct xyz_ctxt *proto, struct xy_block *blk,
|
||||
int read_rc)
|
||||
{
|
||||
if (blk->seq == ((proto->next_blk - 1) % 256))
|
||||
return -EALREADY;
|
||||
if (blk->seq != proto->next_blk)
|
||||
return -EILSEQ;
|
||||
return read_rc;
|
||||
}
|
||||
|
||||
static int parse_first_block(struct xyz_ctxt *proto, struct xy_block *blk)
|
||||
{
|
||||
int filename_len;
|
||||
char *str_num;
|
||||
|
||||
filename_len = strlen(blk->buf);
|
||||
if (filename_len > blk->len)
|
||||
return -EINVAL;
|
||||
strlcpy(proto->filename, blk->buf, sizeof(proto->filename));
|
||||
str_num = blk->buf + filename_len + 1;
|
||||
strsep(&str_num, " ");
|
||||
proto->file_len = simple_strtoul(blk->buf + filename_len + 1, NULL, 10);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int xy_get_file_header(struct xyz_ctxt *proto)
|
||||
{
|
||||
struct xy_block blk;
|
||||
int tries, rc = 0;
|
||||
|
||||
memset(&blk, 0, sizeof(blk));
|
||||
proto->state = PROTO_STATE_GET_FILENAME;
|
||||
proto->crc_mode = CRC_CRC16;
|
||||
for (tries = 0; tries < MAX_RETRIES; tries++) {
|
||||
xy_putc(proto->cdev,
|
||||
invite_filename_hdr[proto->mode][proto->crc_mode]);
|
||||
rc = xy_read_block(proto, &blk, 3 * SECOND);
|
||||
xy_dbg("read block returned %d\n", rc);
|
||||
switch (rc) {
|
||||
case -ECONNABORTED:
|
||||
goto fail;
|
||||
case -ETIMEDOUT:
|
||||
case -EBADMSG:
|
||||
if (proto->mode != PROTO_YMODEM_G)
|
||||
xy_flush(proto->cdev, proto->fifo);
|
||||
break;
|
||||
case -EALREADY:
|
||||
default:
|
||||
proto->next_blk = 1;
|
||||
xy_block_ack(proto);
|
||||
proto->state = PROTO_STATE_NEGOCIATE_CRC;
|
||||
rc = parse_first_block(proto, &blk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rc < 0 && tries++ >= MAX_RETRIES_WITH_CRC)
|
||||
proto->crc_mode = CRC_ADD8;
|
||||
}
|
||||
rc = -ETIMEDOUT;
|
||||
fail:
|
||||
proto->total_retries += tries;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int xy_await_header(struct xyz_ctxt *proto)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = xy_get_file_header(proto);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
proto->state = PROTO_STATE_NEGOCIATE_CRC;
|
||||
xy_dbg("header received, filename=%s, file length=%d\n",
|
||||
proto->filename, proto->file_len);
|
||||
if (proto->filename[0])
|
||||
proto->fd = open(proto->filename, O_WRONLY | O_CREAT);
|
||||
else
|
||||
proto->state = PROTO_STATE_FINISHED_XFER;
|
||||
proto->nb_received = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void xy_finish_file(struct xyz_ctxt *proto)
|
||||
{
|
||||
close(proto->fd);
|
||||
proto->fd = 0;
|
||||
proto->state = PROTO_STATE_FINISHED_FILE;
|
||||
}
|
||||
|
||||
static struct xyz_ctxt *xymodem_open(struct console_device *cdev,
|
||||
int proto_mode, int xmodem_fd)
|
||||
{
|
||||
struct xyz_ctxt *proto;
|
||||
|
||||
proto = xzalloc(sizeof(struct xyz_ctxt));
|
||||
proto->fifo = kfifo_alloc(INPUT_FIFO_SIZE);
|
||||
proto->mode = proto_mode;
|
||||
proto->cdev = cdev;
|
||||
proto->crc_mode = CRC_CRC16;
|
||||
|
||||
if (is_xmodem(proto)) {
|
||||
proto->fd = xmodem_fd;
|
||||
proto->state = PROTO_STATE_NEGOCIATE_CRC;
|
||||
} else {
|
||||
proto->state = PROTO_STATE_GET_FILENAME;
|
||||
}
|
||||
xy_flush(proto->cdev, proto->fifo);
|
||||
return proto;
|
||||
}
|
||||
|
||||
static int xymodem_handle(struct xyz_ctxt *proto)
|
||||
{
|
||||
int rc = 0, xfer_max, len = 0, again = 1, remain;
|
||||
int crc_tries = 0, same_blk_retries = 0;
|
||||
unsigned char invite;
|
||||
struct xy_block blk;
|
||||
|
||||
while (again) {
|
||||
switch (proto->state) {
|
||||
case PROTO_STATE_GET_FILENAME:
|
||||
crc_tries = 0;
|
||||
rc = xy_await_header(proto);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
continue;
|
||||
case PROTO_STATE_FINISHED_FILE:
|
||||
if (is_xmodem(proto))
|
||||
proto->state = PROTO_STATE_FINISHED_XFER;
|
||||
else
|
||||
proto->state = PROTO_STATE_GET_FILENAME;
|
||||
xy_putc(proto->cdev, ACK);
|
||||
continue;
|
||||
case PROTO_STATE_FINISHED_XFER:
|
||||
again = 0;
|
||||
rc = 0;
|
||||
goto out;
|
||||
case PROTO_STATE_NEGOCIATE_CRC:
|
||||
invite = invite_file_body[proto->mode][proto->crc_mode];
|
||||
proto->next_blk = 1;
|
||||
if (crc_tries++ > MAX_RETRIES_WITH_CRC)
|
||||
proto->crc_mode = CRC_ADD8;
|
||||
xy_putc(proto->cdev, invite);
|
||||
/* Fall through */
|
||||
case PROTO_STATE_RECEIVE_BODY:
|
||||
rc = xy_read_block(proto, &blk, 3 * SECOND);
|
||||
if (rc > 0) {
|
||||
rc = check_blk_seq(proto, &blk, rc);
|
||||
proto->state = PROTO_STATE_RECEIVE_BODY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (proto->state != PROTO_STATE_RECEIVE_BODY)
|
||||
continue;
|
||||
|
||||
switch (rc) {
|
||||
case -ECONNABORTED:
|
||||
goto fail;
|
||||
case -ETIMEDOUT:
|
||||
if (proto->mode == PROTO_YMODEM_G)
|
||||
goto fail;
|
||||
xy_flush(proto->cdev, proto->fifo);
|
||||
xy_block_nack(proto);
|
||||
break;
|
||||
case -EBADMSG:
|
||||
case -EILSEQ:
|
||||
if (proto->mode == PROTO_YMODEM_G)
|
||||
goto fail;
|
||||
xy_flush(proto->cdev, proto->fifo);
|
||||
xy_block_nack(proto);
|
||||
break;
|
||||
case -EALREADY:
|
||||
xy_block_ack(proto);
|
||||
break;
|
||||
case 0:
|
||||
xy_finish_file(proto);
|
||||
break;
|
||||
default:
|
||||
remain = proto->file_len - proto->nb_received;
|
||||
if (is_xmodem(proto))
|
||||
xfer_max = blk.len;
|
||||
else
|
||||
xfer_max = min(blk.len, remain);
|
||||
rc = write(proto->fd, blk.buf, xfer_max);
|
||||
proto->next_blk = ((blk.seq + 1) % 256);
|
||||
proto->nb_received += rc;
|
||||
len += rc;
|
||||
xy_block_ack(proto);
|
||||
break;
|
||||
}
|
||||
if (rc < 0)
|
||||
same_blk_retries++;
|
||||
else
|
||||
same_blk_retries = 0;
|
||||
if (same_blk_retries > MAX_RETRIES)
|
||||
goto fail;
|
||||
}
|
||||
out:
|
||||
return rc;
|
||||
fail:
|
||||
if (proto->fd)
|
||||
close(proto->fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void xymodem_close(struct xyz_ctxt *proto)
|
||||
{
|
||||
xy_flush(proto->cdev, proto->fifo);
|
||||
printf("\nxyModem - %d(SOH)/%d(STX)/%d(CAN) packets,"
|
||||
" %d retries\n",
|
||||
proto->total_SOH, proto->total_STX,
|
||||
proto->total_CAN, proto->total_retries);
|
||||
kfifo_free(proto->fifo);
|
||||
}
|
||||
|
||||
int do_load_serial_xmodem(struct console_device *cdev, int fd)
|
||||
{
|
||||
struct xyz_ctxt *proto;
|
||||
int rc;
|
||||
|
||||
proto = xymodem_open(cdev, PROTO_XMODEM, fd);
|
||||
do {
|
||||
rc = xymodem_handle(proto);
|
||||
} while (rc > 0);
|
||||
xymodem_close(proto);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(do_load_serial_xmodem);
|
||||
|
||||
int do_load_serial_ymodem(struct console_device *cdev)
|
||||
{
|
||||
struct xyz_ctxt *proto;
|
||||
int rc;
|
||||
|
||||
proto = xymodem_open(cdev, PROTO_YMODEM, 0);
|
||||
do {
|
||||
rc = xymodem_handle(proto);
|
||||
} while (rc > 0);
|
||||
xymodem_close(proto);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(do_load_serial_ymodem);
|
||||
|
||||
int do_load_serial_ymodemg(struct console_device *cdev)
|
||||
{
|
||||
struct xyz_ctxt *proto;
|
||||
int rc;
|
||||
|
||||
proto = xymodem_open(cdev, PROTO_YMODEM_G, 0);
|
||||
do {
|
||||
rc = xymodem_handle(proto);
|
||||
} while (rc > 0);
|
||||
xymodem_close(proto);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(do_load_serial_ymodemg);
|
||||
671
ymodem.cpp
Normal file
671
ymodem.cpp
Normal file
@@ -0,0 +1,671 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file IAP/src/ymodem.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.3.0
|
||||
* @date 10/15/2010
|
||||
* @brief This file provides all the software functions related to the ymodem
|
||||
* protocol.
|
||||
******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <boost/bind.hpp>
|
||||
#include <sys/ioctl.h>
|
||||
#include "ymodem.h"
|
||||
|
||||
uint8_t file_name[FILE_NAME_LENGTH];
|
||||
uint32_t FlashDestination = ApplicationAddress; /* Flash user program offset */
|
||||
uint16_t PageSize = PAGE_SIZE;
|
||||
uint32_t EraseCounter = 0x0;
|
||||
uint32_t NbrOfPage = 0;
|
||||
FLASH_Status FLASHStatus = FLASH_COMPLETE;
|
||||
uint32_t RamSource;
|
||||
extern uint8_t tab_1024[1024];
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Receive byte from sender
|
||||
* @param c: Character
|
||||
* @param timeout: Timeout
|
||||
* @retval 0: Byte received
|
||||
* -1: Timeout
|
||||
*/
|
||||
static int32_t Receive_Byte (uint8_t *c, uint32_t timeout)
|
||||
{
|
||||
while (timeout-- > 0)
|
||||
{
|
||||
if (SerialKeyPressed(c) == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send a byte
|
||||
* @param c: Character
|
||||
* @retval 0: Byte sent
|
||||
*/
|
||||
static uint32_t Send_Byte (uint8_t c)
|
||||
{
|
||||
SerialPutChar(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a packet from sender
|
||||
* @param data
|
||||
* @param length
|
||||
* @param timeout
|
||||
* 0: end of transmission
|
||||
* -1: abort by sender
|
||||
* >0: packet length
|
||||
* @retval 0: normally return
|
||||
* -1: timeout or packet error
|
||||
* 1: abort by user
|
||||
*/
|
||||
static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout)
|
||||
{
|
||||
uint16_t i, packet_size;
|
||||
uint8_t c;
|
||||
*length = 0;
|
||||
if (Receive_Byte(&c, timeout) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
switch (c)
|
||||
{
|
||||
case SOH:
|
||||
packet_size = PACKET_SIZE;
|
||||
break;
|
||||
case STX:
|
||||
packet_size = PACKET_1K_SIZE;
|
||||
break;
|
||||
case EOT:
|
||||
return 0;
|
||||
case CA:
|
||||
if ((Receive_Byte(&c, timeout) == 0) && (c == CA))
|
||||
{
|
||||
*length = -1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
case ABORT1:
|
||||
case ABORT2:
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
*data = c;
|
||||
for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++)
|
||||
{
|
||||
if (Receive_Byte(data + i, timeout) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
*length = packet_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a file using the ymodem protocol
|
||||
* @param buf: Address of the first byte
|
||||
* @retval The size of the file
|
||||
*/
|
||||
int32_t Ymodem_Receive (uint8_t *buf)
|
||||
{
|
||||
uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;
|
||||
int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0;
|
||||
|
||||
/* Initialize FlashDestination variable */
|
||||
FlashDestination = ApplicationAddress;
|
||||
|
||||
for (session_done = 0, errors = 0, session_begin = 0; ;)
|
||||
{
|
||||
for (packets_received = 0, file_done = 0, buf_ptr = buf; ;)
|
||||
{
|
||||
switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT))
|
||||
{
|
||||
case 0:
|
||||
errors = 0;
|
||||
switch (packet_length)
|
||||
{
|
||||
/* Abort by sender */
|
||||
case - 1:
|
||||
Send_Byte(ACK);
|
||||
return 0;
|
||||
/* End of transmission */
|
||||
case 0:
|
||||
Send_Byte(ACK);
|
||||
file_done = 1;
|
||||
break;
|
||||
/* Normal packet */
|
||||
default:
|
||||
if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))
|
||||
{
|
||||
Send_Byte(NAK);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (packets_received == 0)
|
||||
{
|
||||
/* Filename packet */
|
||||
if (packet_data[PACKET_HEADER] != 0)
|
||||
{
|
||||
/* Filename packet has valid data */
|
||||
for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
|
||||
{
|
||||
file_name[i++] = *file_ptr++;
|
||||
}
|
||||
file_name[i++] = '\0';
|
||||
for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);)
|
||||
{
|
||||
file_size[i++] = *file_ptr++;
|
||||
}
|
||||
file_size[i++] = '\0';
|
||||
Str2Int(file_size, &size);
|
||||
|
||||
/* Test the size of the image to be sent */
|
||||
/* Image size is greater than Flash size */
|
||||
if (size > (FLASH_SIZE - 1))
|
||||
{
|
||||
/* End session */
|
||||
Send_Byte(CA);
|
||||
Send_Byte(CA);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Erase the needed pages where the user application will be loaded */
|
||||
/* Define the number of page to be erased */
|
||||
NbrOfPage = FLASH_PagesMask(size);
|
||||
|
||||
/* Erase the FLASH pages */
|
||||
for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
|
||||
{
|
||||
FLASHStatus = FLASH_ErasePage(FlashDestination + (PageSize * EraseCounter));
|
||||
}
|
||||
Send_Byte(ACK);
|
||||
Send_Byte(CRC16);
|
||||
}
|
||||
/* Filename packet is empty, end session */
|
||||
else
|
||||
{
|
||||
Send_Byte(ACK);
|
||||
file_done = 1;
|
||||
session_done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Data packet */
|
||||
else
|
||||
{
|
||||
memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
|
||||
RamSource = (uint32_t)buf;
|
||||
for (j = 0;(j < packet_length) && (FlashDestination < ApplicationAddress + size);j += 4)
|
||||
{
|
||||
/* Program the data received into STM32F10x Flash */
|
||||
FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource);
|
||||
|
||||
if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource)
|
||||
{
|
||||
/* End session */
|
||||
Send_Byte(CA);
|
||||
Send_Byte(CA);
|
||||
return -2;
|
||||
}
|
||||
FlashDestination += 4;
|
||||
RamSource += 4;
|
||||
}
|
||||
Send_Byte(ACK);
|
||||
}
|
||||
packets_received ++;
|
||||
session_begin = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
Send_Byte(CA);
|
||||
Send_Byte(CA);
|
||||
return -3;
|
||||
default:
|
||||
if (session_begin > 0)
|
||||
{
|
||||
errors ++;
|
||||
}
|
||||
if (errors > MAX_ERRORS)
|
||||
{
|
||||
Send_Byte(CA);
|
||||
Send_Byte(CA);
|
||||
return 0;
|
||||
}
|
||||
Send_Byte(CRC16);
|
||||
break;
|
||||
}
|
||||
if (file_done != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (session_done != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (int32_t)size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check response using the ymodem protocol
|
||||
* @param buf: Address of the first byte
|
||||
* @retval The size of the file
|
||||
*/
|
||||
int32_t Ymodem_CheckResponse(uint8_t c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepare the first block
|
||||
* @param timeout
|
||||
* 0: end of transmission
|
||||
*/
|
||||
void Ymodem_PrepareIntialPacket(uint8_t *data, const uint8_t* fileName, uint32_t *length)
|
||||
{
|
||||
uint16_t i, j;
|
||||
uint8_t file_ptr[10];
|
||||
|
||||
/* Make first three packet */
|
||||
data[0] = SOH;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0xff;
|
||||
|
||||
/* Filename packet has valid data */
|
||||
for (i = 0; (fileName[i] != '\0') && (i < FILE_NAME_LENGTH);i++)
|
||||
{
|
||||
data[i + PACKET_HEADER] = fileName[i];
|
||||
}
|
||||
|
||||
data[i + PACKET_HEADER] = 0x00;
|
||||
|
||||
Int2Str (file_ptr, *length);
|
||||
for (j =0, i = i + PACKET_HEADER + 1; file_ptr[j] != '\0' ; )
|
||||
{
|
||||
data[i++] = file_ptr[j++];
|
||||
}
|
||||
|
||||
for (j = i; j < PACKET_SIZE + PACKET_HEADER; j++)
|
||||
{
|
||||
data[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepare the data packet
|
||||
* @param timeout
|
||||
* 0: end of transmission
|
||||
*/
|
||||
void Ymodem_PreparePacket(uint8_t *SourceBuf, uint8_t *data, uint8_t pktNo, uint32_t sizeBlk)
|
||||
{
|
||||
uint16_t i, size, packetSize;
|
||||
uint8_t* file_ptr;
|
||||
|
||||
/* Make first three packet */
|
||||
packetSize = sizeBlk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE;
|
||||
size = sizeBlk < packetSize ? sizeBlk :packetSize;
|
||||
if (packetSize == PACKET_1K_SIZE)
|
||||
{
|
||||
data[0] = STX;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[0] = SOH;
|
||||
}
|
||||
data[1] = pktNo;
|
||||
data[2] = (~pktNo);
|
||||
file_ptr = SourceBuf;
|
||||
|
||||
/* Filename packet has valid data */
|
||||
for (i = PACKET_HEADER; i < size + PACKET_HEADER;i++)
|
||||
{
|
||||
data[i] = *file_ptr++;
|
||||
}
|
||||
if ( size <= packetSize)
|
||||
{
|
||||
for (i = size + PACKET_HEADER; i < packetSize + PACKET_HEADER; i++)
|
||||
{
|
||||
data[i] = 0x1A; /* EOF (0x1A) or 0x00 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update CRC16 for input byte
|
||||
* @param CRC input value
|
||||
* @param input byte
|
||||
* @retval None
|
||||
*/
|
||||
uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte)
|
||||
{
|
||||
uint32_t crc = crcIn;
|
||||
uint32_t in = byte|0x100;
|
||||
do
|
||||
{
|
||||
crc <<= 1;
|
||||
in <<= 1;
|
||||
if(in&0x100)
|
||||
++crc;
|
||||
if(crc&0x10000)
|
||||
crc ^= 0x1021;
|
||||
}
|
||||
while(!(in&0x10000));
|
||||
return crc&0xffffu;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Cal CRC16 for YModem Packet
|
||||
* @param data
|
||||
* @param length
|
||||
* @retval None
|
||||
*/
|
||||
uint16_t Cal_CRC16(const uint8_t* data, uint32_t size)
|
||||
{
|
||||
uint32_t crc = 0;
|
||||
const uint8_t* dataEnd = data+size;
|
||||
while(data<dataEnd)
|
||||
crc = UpdateCRC16(crc,*data++);
|
||||
|
||||
crc = UpdateCRC16(crc,0);
|
||||
crc = UpdateCRC16(crc,0);
|
||||
return crc&0xffffu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cal Check sum for YModem Packet
|
||||
* @param data
|
||||
* @param length
|
||||
* @retval None
|
||||
*/
|
||||
uint8_t CalChecksum(const uint8_t* data, uint32_t size)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
const uint8_t* dataEnd = data+size;
|
||||
while(data < dataEnd )
|
||||
sum += *data++;
|
||||
return sum&0xffu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmit a data packet using the ymodem protocol
|
||||
* @param data
|
||||
* @param length
|
||||
* @retval None
|
||||
*/
|
||||
void Ymodem_SendPacket(uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint16_t i;
|
||||
i = 0;
|
||||
while (i < length)
|
||||
{
|
||||
Send_Byte(data[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmit a file using the ymodem protocol
|
||||
* @param buf: Address of the first byte
|
||||
* @retval The size of the file
|
||||
*/
|
||||
uint8_t Ymodem_Transmit (uint8_t *buf, const uint8_t* sendFileName, uint32_t sizeFile)
|
||||
{
|
||||
|
||||
uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];
|
||||
uint8_t FileName[FILE_NAME_LENGTH];
|
||||
uint8_t *buf_ptr, tempCheckSum ;
|
||||
uint16_t tempCRC, blkNumber;
|
||||
uint8_t receivedC[2], CRC16_F = 0, i;
|
||||
uint32_t errors, ackReceived, size = 0, pktSize;
|
||||
|
||||
errors = 0;
|
||||
ackReceived = 0;
|
||||
for (i = 0; i < (FILE_NAME_LENGTH - 1); i++)
|
||||
{
|
||||
FileName[i] = sendFileName[i];
|
||||
}
|
||||
CRC16_F = 1;
|
||||
|
||||
/* Prepare first block */
|
||||
Ymodem_PrepareIntialPacket(&packet_data[0], FileName, &sizeFile);
|
||||
|
||||
do
|
||||
{
|
||||
/* Send Packet */
|
||||
Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);
|
||||
/* Send CRC or Check Sum based on CRC16_F */
|
||||
if (CRC16_F)
|
||||
{
|
||||
tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE);
|
||||
Send_Byte(tempCRC >> 8);
|
||||
Send_Byte(tempCRC & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempCheckSum = CalChecksum (&packet_data[3], PACKET_SIZE);
|
||||
Send_Byte(tempCheckSum);
|
||||
}
|
||||
|
||||
/* Wait for Ack and 'C' */
|
||||
if (Receive_Byte(&receivedC[0], 10000) == 0)
|
||||
{
|
||||
if (receivedC[0] == ACK)
|
||||
{
|
||||
/* Packet transfered correctly */
|
||||
ackReceived = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while (!ackReceived && (errors < 0x0A));
|
||||
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
buf_ptr = buf;
|
||||
size = sizeFile;
|
||||
blkNumber = 0x01;
|
||||
/* Here 1024 bytes package is used to send the packets */
|
||||
|
||||
|
||||
/* Resend packet if NAK for a count of 10 else end of commuincation */
|
||||
while (size)
|
||||
{
|
||||
/* Prepare next packet */
|
||||
Ymodem_PreparePacket(buf_ptr, &packet_data[0], blkNumber, size);
|
||||
ackReceived = 0;
|
||||
receivedC[0]= 0;
|
||||
errors = 0;
|
||||
do
|
||||
{
|
||||
/* Send next packet */
|
||||
if (size >= PACKET_1K_SIZE)
|
||||
{
|
||||
pktSize = PACKET_1K_SIZE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
pktSize = PACKET_SIZE;
|
||||
}
|
||||
Ymodem_SendPacket(packet_data, pktSize + PACKET_HEADER);
|
||||
/* Send CRC or Check Sum based on CRC16_F */
|
||||
/* Send CRC or Check Sum based on CRC16_F */
|
||||
if (CRC16_F)
|
||||
{
|
||||
tempCRC = Cal_CRC16(&packet_data[3], pktSize);
|
||||
Send_Byte(tempCRC >> 8);
|
||||
Send_Byte(tempCRC & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempCheckSum = CalChecksum (&packet_data[3], pktSize);
|
||||
Send_Byte(tempCheckSum);
|
||||
}
|
||||
|
||||
/* Wait for Ack */
|
||||
if ((Receive_Byte(&receivedC[0], 100000) == 0) && (receivedC[0] == ACK))
|
||||
{
|
||||
ackReceived = 1;
|
||||
if (size > pktSize)
|
||||
{
|
||||
buf_ptr += pktSize;
|
||||
size -= pktSize;
|
||||
if (blkNumber == (FLASH_IMAGE_SIZE/1024))
|
||||
{
|
||||
return 0xFF; /* error */
|
||||
}
|
||||
else
|
||||
{
|
||||
blkNumber++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf_ptr += pktSize;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while(!ackReceived && (errors < 0x0A));
|
||||
/* Resend packet if NAK for a count of 10 else end of commuincation */
|
||||
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
}
|
||||
ackReceived = 0;
|
||||
receivedC[0] = 0x00;
|
||||
errors = 0;
|
||||
do
|
||||
{
|
||||
Send_Byte(EOT);
|
||||
/* Send (EOT); */
|
||||
/* Wait for Ack */
|
||||
if ((Receive_Byte(&receivedC[0], 10000) == 0) && receivedC[0] == ACK)
|
||||
{
|
||||
ackReceived = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while (!ackReceived && (errors < 0x0A));
|
||||
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
/* Last packet preparation */
|
||||
ackReceived = 0;
|
||||
receivedC[0] = 0x00;
|
||||
errors = 0;
|
||||
|
||||
packet_data[0] = SOH;
|
||||
packet_data[1] = 0;
|
||||
packet_data [2] = 0xFF;
|
||||
|
||||
for (i = PACKET_HEADER; i < (PACKET_SIZE + PACKET_HEADER); i++)
|
||||
{
|
||||
packet_data [i] = 0x00;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* Send Packet */
|
||||
Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);
|
||||
/* Send CRC or Check Sum based on CRC16_F */
|
||||
tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE);
|
||||
Send_Byte(tempCRC >> 8);
|
||||
Send_Byte(tempCRC & 0xFF);
|
||||
|
||||
/* Wait for Ack and 'C' */
|
||||
if (Receive_Byte(&receivedC[0], 10000) == 0)
|
||||
{
|
||||
if (receivedC[0] == ACK)
|
||||
{
|
||||
/* Packet transfered correctly */
|
||||
ackReceived = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
|
||||
}while (!ackReceived && (errors < 0x0A));
|
||||
/* Resend packet if NAK for a count of 10 else end of commuincation */
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
Send_Byte(EOT);
|
||||
/* Send (EOT); */
|
||||
/* Wait for Ack */
|
||||
if ((Receive_Byte(&receivedC[0], 10000) == 0) && receivedC[0] == ACK)
|
||||
{
|
||||
ackReceived = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while (!ackReceived && (errors < 0x0A));
|
||||
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
return 0; /* file trasmitted successfully */
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*******************(C)COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
|
||||
63
ymodem.h
Normal file
63
ymodem.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file IAP/inc/ymodem.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.3.0
|
||||
* @date 10/15/2010
|
||||
* @brief This file provides all the software function headers of the ymodem.c
|
||||
* file.
|
||||
******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _YMODEM_H_
|
||||
#define _YMODEM_H_
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#define PACKET_SEQNO_INDEX (1)
|
||||
#define PACKET_SEQNO_COMP_INDEX (2)
|
||||
|
||||
#define PACKET_HEADER (3)
|
||||
#define PACKET_TRAILER (2)
|
||||
#define PACKET_OVERHEAD (PACKET_HEADER + PACKET_TRAILER)
|
||||
#define PACKET_SIZE (128)
|
||||
#define PACKET_1K_SIZE (1024)
|
||||
|
||||
#define FILE_NAME_LENGTH (256)
|
||||
#define FILE_SIZE_LENGTH (16)
|
||||
|
||||
#define SOH (0x01) /* start of 128-byte data packet */
|
||||
#define STX (0x02) /* start of 1024-byte data packet */
|
||||
#define EOT (0x04) /* end of transmission */
|
||||
#define ACK (0x06) /* acknowledge */
|
||||
#define NAK (0x15) /* negative acknowledge */
|
||||
#define CA (0x18) /* two of these in succession aborts transfer */
|
||||
#define CRC16 (0x43) /* 'C' == 0x43, request 16-bit CRC */
|
||||
|
||||
#define ABORT1 (0x41) /* 'A' == 0x41, abort by user */
|
||||
#define ABORT2 (0x61) /* 'a' == 0x61, abort by user */
|
||||
|
||||
#define NAK_TIMEOUT (0x100000)
|
||||
#define MAX_ERRORS (5)
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
int32_t Ymodem_Receive (uint8_t *);
|
||||
uint8_t Ymodem_Transmit (uint8_t *,const uint8_t* , uint32_t );
|
||||
|
||||
#endif /* _YMODEM_H_ */
|
||||
|
||||
/*******************(C)COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
|
||||
Reference in New Issue
Block a user