Add handshake code

This commit is contained in:
spacemeowx2 2020-12-03 21:47:28 +08:00 committed by spacelin
parent 57214e9a4e
commit 5ddac977a9
13 changed files with 1064 additions and 5 deletions

710
Cargo.lock generated
View File

@ -1,9 +1,719 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "addr2line"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598"
dependencies = [
"addr2line",
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "bitvec"
version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "blflash"
version = "0.1.0"
dependencies = [
"byteorder",
"deku",
"directories-next",
"env_logger",
"indicatif",
"log",
"main_error",
"pico-args",
"serde",
"serial",
"thiserror",
"toml 0.5.7",
"xmas-elf",
]
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cargo-blflash"
version = "0.1.0"
dependencies = [
"blflash",
"cargo-project",
"main_error",
"pico-args",
"serial",
]
[[package]]
name = "cargo-project"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b735b1b2cf3bc8eed47b20da5ba5b8b33f343700d367e4e536b6f3054ecbd3a"
dependencies = [
"failure",
"glob",
"log",
"rustc-cfg",
"serde",
"serde_derive",
"toml 0.4.10",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "console"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a50aab2529019abfabfa93f1e6c41ef392f91fbf179b347a7e96abb524884a08"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"regex",
"terminal_size",
"unicode-width",
"winapi",
"winapi-util",
]
[[package]]
name = "darling"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "deku"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e58899e303bf5a70317f3458bcea62f62eb485d8a901e52f72b7fab74a735bef"
dependencies = [
"bitvec",
"deku_derive",
]
[[package]]
name = "deku_derive"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1d4fc5c2c06069f7400c2c639b567b0559e72ce79913f6955365cce52e513e6"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "directories-next"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a28ccebc1239c5c57f0c55986e2ac03f49af0d0ca3dff29bfcad39d60a8be56"
dependencies = [
"cfg-if 1.0.0",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99de365f605554ae33f115102a02057d4fc18b01f3284d6870be0938743cfe7d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "env_logger"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "failure"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
dependencies = [
"backtrace",
"failure_derive",
]
[[package]]
name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "funty"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8"
[[package]]
name = "getrandom"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
dependencies = [
"cfg-if 0.1.10",
"libc",
"wasi",
]
[[package]]
name = "gimli"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hermit-abi"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
dependencies = [
"libc",
]
[[package]]
name = "humantime"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a"
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "indicatif"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
dependencies = [
"console",
"lazy_static",
"number_prefix",
"regex",
]
[[package]]
name = "ioctl-rs"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
[[package]]
name = "log"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if 0.1.10",
]
[[package]]
name = "main_error"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb63bb1e282e0b6aba0addb1f0e87cb5181ea68142b2dfd21ba108f8e8088a64"
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "miniz_oxide"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
dependencies = [
"adler",
"autocfg",
]
[[package]]
name = "number_prefix"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
[[package]]
name = "object"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
[[package]]
name = "pico-args"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b9b4df73455c861d7cbf8be42f01d3b373ed7f02e378d55fa84eafc6f638b1"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "radium"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_users"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom",
"redox_syscall",
]
[[package]]
name = "regex"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
[[package]]
name = "rustc-cfg"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ad221fe7cd09334f8735dcc157b1178e343f43dfaefcd1b09d7fd4fc0921b6f"
dependencies = [
"failure",
]
[[package]]
name = "rustc-demangle"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
[[package]]
name = "serde"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serial"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86"
dependencies = [
"serial-core",
"serial-unix",
"serial-windows",
]
[[package]]
name = "serial-core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581"
dependencies = [
"libc",
]
[[package]]
name = "serial-unix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7"
dependencies = [
"ioctl-rs",
"libc",
"serial-core",
"termios",
]
[[package]]
name = "serial-windows"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162"
dependencies = [
"libc",
"serial-core",
]
[[package]]
name = "strsim"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "syn"
version = "1.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8833e20724c24de12bbaba5ad230ea61c3eafb05b881c7c9d3cfe8638b187e68"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "synstructure"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
dependencies = [
"proc-macro2",
"quote",
"syn",
"unicode-xid",
]
[[package]]
name = "tap"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e"
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bd2d183bd3fac5f5fe38ddbeb4dc9aec4a39a9d7d59e7491d900302da01cbe1"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "termios"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
dependencies = [
"libc",
]
[[package]]
name = "thiserror"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
dependencies = [
"lazy_static",
]
[[package]]
name = "toml"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
dependencies = [
"serde",
]
[[package]]
name = "toml"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645"
dependencies = [
"serde",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "wyz"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
[[package]]
name = "xmas-elf"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74de9a366f6ab8c405fa6b371d9ac24943921fa14b3d64afcb202065c405f11"
dependencies = [
"zero",
]
[[package]]
name = "zero"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5"

View File

@ -3,3 +3,5 @@
BL602 serial flasher
Inspired by https://github.com/esp-rs/espflash
ISP documentation: https://github.com/bouffalolab/bl_docs/tree/main/BL602_ISP

View File

@ -4,6 +4,23 @@ version = "0.1.0"
authors = ["spacelin <spacelin@tencent.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "blflash"
path = "src/main.rs"
[lib]
[dependencies]
serial = "0.4"
xmas-elf = "0.7.0"
main_error = "0.1.1"
pico-args = "0.3.4"
serde = { version = "1.0", features = ["derive"] }
toml = "0.5"
directories-next = "1.0.1"
thiserror = "1.0.22"
indicatif = "0.15.0"
log = "0.4.11"
env_logger = "0.8.2"
deku = "0.9.1"
byteorder = "1.3.4"

Binary file not shown.

View File

@ -0,0 +1 @@
pub const _EFLASH_LOADER: &'static [u8] = include_bytes!("eflash_loader_40m.bin");

1
blflash/src/chip/mod.rs Normal file
View File

@ -0,0 +1 @@
mod bl602;

34
blflash/src/config.rs Normal file
View File

@ -0,0 +1,34 @@
use directories_next::ProjectDirs;
use serde::Deserialize;
use std::fs::read;
#[derive(Debug, Deserialize, Default)]
pub struct Config {
#[serde(default)]
pub connection: Connection,
#[serde(default)]
pub build: Build,
}
#[derive(Debug, Deserialize, Default)]
pub struct Connection {
pub serial: Option<String>,
}
#[derive(Debug, Deserialize, Default)]
pub struct Build {
pub tool: Option<String>,
}
impl Config {
/// Load the config from config file
pub fn load() -> Self {
let dirs = ProjectDirs::from("rs", "esp", "espflash").unwrap();
let file = dirs.config_dir().join("espflash.toml");
if let Ok(data) = read(&file) {
toml::from_slice(&data).unwrap()
} else {
Self::default()
}
}
}

101
blflash/src/connection.rs Normal file
View File

@ -0,0 +1,101 @@
use std::io::{Read, Write, Cursor};
use std::thread::sleep;
use std::time::Duration;
use crate::{Error, RomError};
use byteorder::{ReadBytesExt, LittleEndian};
use serial::{BaudRate, SerialPort, SerialPortSettings};
pub const DEFAULT_BAUDRATE: BaudRate = BaudRate::Baud115200;
pub struct Connection {
serial: Box<dyn SerialPort>,
baud_rate: BaudRate,
}
impl Connection {
pub fn new(serial: impl SerialPort + 'static) -> Self {
Connection {
serial: Box::new(serial),
baud_rate: DEFAULT_BAUDRATE,
}
}
pub fn reset_to_flash(&mut self) -> Result<(), Error> {
self.serial.set_rts(true)?;
sleep(Duration::from_millis(50));
self.serial.set_dtr(true)?;
sleep(Duration::from_millis(50));
self.serial.set_dtr(false)?;
sleep(Duration::from_millis(50));
self.serial.set_rts(false)?;
sleep(Duration::from_millis(50));
Ok(())
}
pub fn set_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
self.serial.set_timeout(timeout)?;
Ok(())
}
pub fn set_baud(&mut self, speed: BaudRate) -> Result<(), Error> {
self.baud_rate = speed;
self.serial
.reconfigure(&|setup: &mut dyn SerialPortSettings| setup.set_baud_rate(speed))?;
Ok(())
}
pub fn with_timeout<T, F: FnMut(&mut Connection) -> Result<T, Error>>(
&mut self,
timeout: Duration,
mut f: F,
) -> Result<T, Error> {
let old_timeout = self.serial.timeout();
self.serial.set_timeout(timeout)?;
let result = f(self);
self.serial.set_timeout(old_timeout)?;
result
}
fn read_exact(&mut self, len: usize) -> Result<Vec<u8>, Error> {
let mut buf = vec![0u8; len];
self.serial.read_exact(&mut buf)?;
Ok(buf)
}
pub fn read_response(&mut self, len: usize) -> Result<Vec<u8>, Error> {
let resp = self.read_exact(2)?;
log::trace!("read_response {}", String::from_utf8_lossy(&resp).to_string());
match &resp[0..2] {
// OK
[0x4f, 0x4b] => {
if len > 0 {
self.read_exact(len)
} else {
Ok(vec![])
}
},
// FL
[0x46, 0x4c] => {
let code = self.read_exact(2)?;
let mut reader = Cursor::new(code);
let code = reader.read_u16::<LittleEndian>()?;
Err(Error::RomError(RomError::from(code)))
},
_ => Err(Error::RespError)
}
}
pub fn calc_duration_length(&mut self, duration: Duration) -> usize {
self.baud_rate.speed() / 10 / 1000 * (duration.as_millis() as usize)
}
pub fn write_all(&mut self, buf: &[u8]) -> Result<(), Error> {
Ok(self.serial.write_all(buf)?)
}
pub fn flush(&mut self) -> Result<(), Error> {
Ok(self.serial.flush()?)
}
}

50
blflash/src/error.rs Normal file
View File

@ -0,0 +1,50 @@
use thiserror::Error;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[error("IO error while using serial port: {0}")]
Serial(#[from] serial::core::Error),
#[error("Failed to connect to the device")]
ConnectionFailed,
#[error("Timeout while running command")]
Timeout,
#[error("Invalid response header")]
RespError,
#[error("Packet to large for buffer")]
OverSizedPacket,
#[error("elf image is not valid")]
InvalidElf,
#[error("elf image can not be ran from ram")]
ElfNotRamLoadable,
#[error("chip not recognized")]
UnrecognizedChip,
#[error("flash chip not supported, flash id: {0:#x}")]
UnsupportedFlash(u8),
#[error("ROM error")]
RomError(RomError),
#[error("Parse error")]
ParseError(#[from] deku::error::DekuError),
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Self::Serial(serial::core::Error::from(err))
}
}
#[derive(Copy, Clone, Debug)]
#[allow(dead_code)]
pub enum RomError {
Success,
Other(u16),
}
impl From<u16> for RomError {
fn from(raw: u16) -> Self {
match raw {
0x00 => RomError::Success,
_ => RomError::Other(raw),
}
}
}

84
blflash/src/flasher.rs Normal file
View File

@ -0,0 +1,84 @@
use crate::connection::{Connection, DEFAULT_BAUDRATE};
use crate::Error;
use serial::{BaudRate, SerialPort};
use std::time::{Duration, Instant};
use deku::prelude::*;
pub struct Flasher {
connection: Connection,
bootrom_info: protocol::BootInfo,
}
impl Flasher {
pub fn connect(
serial: impl SerialPort + 'static,
speed: Option<BaudRate>,
) -> Result<Self, Error> {
let mut flasher = Flasher {
connection: Connection::new(serial),
bootrom_info: protocol::BootInfo::default(),
};
flasher.connection.set_baud(speed.unwrap_or(DEFAULT_BAUDRATE))?;
flasher.start_connection()?;
flasher.connection.set_timeout(Duration::from_secs(3))?;
flasher.bootrom_info = flasher.get_boot_info()?;
Ok(flasher)
}
fn get_boot_info(&mut self) -> Result<protocol::BootInfo, Error> {
self.connection.write_all(protocol::GET_BOOT_INFO)?;
let data = self.connection.read_response(1 + 1 + 4 + 16)?;
let (_, data) = protocol::BootInfo::from_bytes((&data, 0))?;
Ok(data)
}
fn handshake(&mut self) -> Result<(), Error> {
self.connection
.with_timeout(Duration::from_millis(200), |connection| {
let len = connection.calc_duration_length(Duration::from_millis(5));
log::trace!("5ms send count {}", len);
let data: Vec<u8> = std::iter::repeat(0x55u8)
.take(len).collect();
let start = Instant::now();
connection.write_all(&data)?;
connection.flush()?;
log::trace!("handshake sent elapsed {:?}", start.elapsed());
for _ in 0..10 {
if connection.read_response(0).is_ok() {
return Ok(())
}
}
Err(Error::Timeout)
})
}
fn start_connection(&mut self) -> Result<(), Error> {
log::info!("Start connection...");
self.connection.reset_to_flash()?;
for i in 1..=10 {
self.connection.flush()?;
if self.handshake().is_ok() {
log::info!("Connection Succeed");
return Ok(());
} else {
log::debug!("Retry {}", i);
}
}
Err(Error::ConnectionFailed)
}
}
mod protocol {
use deku::prelude::*;
pub const GET_BOOT_INFO: &[u8] = &[0x10, 0x00, 0x00, 0x00];
#[derive(Debug, DekuRead, Default)]
#[deku(magic = b"\x14\x00")]
pub struct BootInfo {
bootrom_version: u32,
otp_info: [u8; 16],
}
}

9
blflash/src/lib.rs Normal file
View File

@ -0,0 +1,9 @@
mod config;
mod flasher;
mod connection;
mod chip;
mod error;
pub use config::Config;
pub use flasher::Flasher;
pub use error::{Error, RomError};

View File

@ -1,3 +1,50 @@
fn main() {
println!("Hello, world!");
use std::fs::read;
use blflash::{Config, Flasher};
use main_error::MainError;
use pico_args::Arguments;
use serial::BaudRate;
use env_logger::Env;
fn help() -> Result<(), MainError> {
println!("Usage: espflash [--board-info] [--ram] <serial> <elf image>");
Ok(())
}
fn main() -> Result<(), MainError> {
env_logger::Builder::from_env(Env::default().default_filter_or("blflash=trace")).init();
let mut args = Arguments::from_env();
let config = Config::load();
log::trace!("trace on");
if args.contains(["-h", "--help"]) {
return help();
}
let _ram = args.contains("--ram");
let mut serial: Option<String> = args.free_from_str()?;
let mut elf: Option<String> = args.free_from_str()?;
if elf.is_none() && config.connection.serial.is_some() {
elf = serial.take();
serial = config.connection.serial;
}
let serial: String = match serial {
Some(serial) => serial,
_ => return help(),
};
let serial = serial::open(&serial)?;
let _flasher = Flasher::connect(serial, Some(BaudRate::BaudOther(500_000)))?;
let input: String = match elf {
Some(input) => input,
_ => return help(),
};
let _input_bytes = read(&input)?;
Ok(())
}

View File

@ -4,6 +4,9 @@ version = "0.1.0"
authors = ["spacelin <spacelin@tencent.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cargo-project = "0.2.4"
blflash = { version = "0.1.0", path = "../blflash" }
main_error = "0.1.1"
pico-args = "0.3.4"
serial = "0.4"