Compare commits
No commits in common. "master" and "fix-stc15f104w" have entirely different histories.
master
...
fix-stc15f
6
.github/workflows/python.yml
vendored
6
.github/workflows/python.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
name: Python package
|
name: Python package
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
@ -9,7 +9,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.7, 3.8]
|
python-version: [3.5, 3.7, 3.8]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@ -47,4 +47,4 @@ jobs:
|
|||||||
pip3 install --upgrade coveralls
|
pip3 install --upgrade coveralls
|
||||||
coveralls --finish
|
coveralls --finish
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
@ -1,68 +0,0 @@
|
|||||||
文档说明 Explanation
|
|
||||||
-------------------
|
|
||||||
此文档翻译自README.MD
|
|
||||||
|
|
||||||
This document was translated from README.MD
|
|
||||||
|
|
||||||
最后修改时间:2020年6月8日
|
|
||||||
|
|
||||||
Last modified time: June 8, 2020
|
|
||||||
|
|
||||||
|
|
||||||
stcgal - 用于STC MCU的ISP闪存工具
|
|
||||||
===============================
|
|
||||||
|
|
||||||
stcgal是用于[STC MCU Ltd]的命令行闪存编程工具。
|
|
||||||
兼容8051微控制器。
|
|
||||||
|
|
||||||
|
|
||||||
STC微控制器具有基于UART / USB的引导加载程序(BSL)。
|
|
||||||
它采用系统内编程,即基于数据包的协议通过串行链路刷新代码存储器和IAP存储器。
|
|
||||||
BSL还用于配置各种设备选项。
|
|
||||||
不幸的是,该协议没有公开记录,STC仅提供(粗略的)Windows GUI应用程序进行编程
|
|
||||||
|
|
||||||
|
|
||||||
stcgal是STC的Windows软件的功能全面的开源替代品。
|
|
||||||
它支持多种MCU,非常便携,适合自动下载。
|
|
||||||
|
|
||||||
特点
|
|
||||||
--------
|
|
||||||
|
|
||||||
* 支持STC 89/90/10/11/12/15/8/32系列
|
|
||||||
* UART和USB BSL支持
|
|
||||||
* 显示信息
|
|
||||||
* 确定工作频率
|
|
||||||
* 程序闪存
|
|
||||||
* 程序IAP / EEPROM
|
|
||||||
* 设置设备选项
|
|
||||||
* 读取唯一的设备ID(STC 10/11/12/15/8)
|
|
||||||
* 设置RC振荡器频率(STC 15/8)
|
|
||||||
* 自动电源(使用DTR切换或自定义Shell命令循环)
|
|
||||||
* 自动UART协议检测
|
|
||||||
|
|
||||||
快速开始
|
|
||||||
----------
|
|
||||||
|
|
||||||
安装stcgal(可能需要root /管理员权限):
|
|
||||||
|
|
||||||
pip3 install stcgal
|
|
||||||
|
|
||||||
呼叫stcgal并显示的用法:
|
|
||||||
|
|
||||||
stcgal -h
|
|
||||||
|
|
||||||
更多的信息
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
[安装方法](doc/zh_CN/INSTALL.md)
|
|
||||||
|
|
||||||
[如何取使用](doc/zh_CN/USAGE.md)
|
|
||||||
|
|
||||||
[常见问题](doc/zh_CN/FAQ.md)
|
|
||||||
|
|
||||||
[支持的MCU型号](doc/zh_CN/MODELS.md)
|
|
||||||
|
|
||||||
执照
|
|
||||||
-------
|
|
||||||
|
|
||||||
stcgal是根据MIT许可发布的。
|
|
@ -22,7 +22,7 @@ suitable for automation.
|
|||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
* Support for STC 89/90/10/11/12/15/8/32 series
|
* Support for STC 89/90/10/11/12/15/8 series
|
||||||
* UART and USB BSL support
|
* UART and USB BSL support
|
||||||
* Display part info
|
* Display part info
|
||||||
* Determine operating frequency
|
* Determine operating frequency
|
||||||
|
30
debian/changelog
vendored
Normal file
30
debian/changelog
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
stcgal (1.6) unstable; urgency=low
|
||||||
|
|
||||||
|
* Update to 1.6
|
||||||
|
|
||||||
|
-- Grigori Goronzy <greg@chown.ath.cx> Mon, 24 Sep 2018 22:56:31 +0200
|
||||||
|
|
||||||
|
stcgal (1.4) unstable; urgency=low
|
||||||
|
|
||||||
|
* Update to 1.4
|
||||||
|
|
||||||
|
-- Grigori <greg@chown.ath.cx> Tue, 19 Sep 2017 17:57:11 +0200
|
||||||
|
|
||||||
|
stcgal (1.3) unstable; urgency=low
|
||||||
|
|
||||||
|
* Update to 1.3
|
||||||
|
|
||||||
|
-- Grigori Goronzy <greg@chown.ath.cx> Sat, 10 Jun 2017 10:01:07 +0200
|
||||||
|
|
||||||
|
stcgal (1.2) unstable; urgency=low
|
||||||
|
|
||||||
|
* Update to 1.2
|
||||||
|
* Add optional python3-usb dependency
|
||||||
|
|
||||||
|
-- Grigori Goronzy <greg@chown.ath.cx> Fri, 20 May 2016 03:21:25 +0200
|
||||||
|
|
||||||
|
stcgal (1.0git) unstable; urgency=low
|
||||||
|
|
||||||
|
* Initial Debianized Release
|
||||||
|
|
||||||
|
-- Andrew 'Necromant' Andrianov <andrew@ncrmnt.org> Wed, 25 Nov 2015 13:07:03 +0300
|
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
9
|
27
debian/control
vendored
Normal file
27
debian/control
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Source: stcgal
|
||||||
|
Section: electronics
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Andrew Andrianov <andrew@ncrmnt.org>
|
||||||
|
Build-Depends: debhelper (>= 9), python3, python3-setuptools, dh-python, python3-serial, python3-tqdm, python3-yaml
|
||||||
|
Standards-Version: 3.9.5
|
||||||
|
Homepage: https://github.com/grigorig/stcgal
|
||||||
|
X-Python3-Version: >= 3.2
|
||||||
|
|
||||||
|
Package: stcgal
|
||||||
|
Architecture: all
|
||||||
|
Depends: ${misc:Depends}, python3, python3-serial, python3-tqdm
|
||||||
|
Recommends: python3-usb (>= 1.0.0~b2)
|
||||||
|
Description: STC MCU ISP flash tool
|
||||||
|
stcgal is a command line flash programming tool for STC MCU Ltd.
|
||||||
|
8051 compatible microcontrollers. The name was inspired by avrdude.
|
||||||
|
.
|
||||||
|
STC microcontrollers have an UART/USB based boot strap loader (BSL). It
|
||||||
|
utilizes a packet-based protocol to flash the code memory and IAP
|
||||||
|
memory over a serial link. This is referred to as in-system programming
|
||||||
|
(ISP). The BSL is also used to configure various (fuse-like) device
|
||||||
|
options. Unfortunately, this protocol is not publicly documented and
|
||||||
|
STC only provide a (crude) Windows GUI application for programming.
|
||||||
|
.
|
||||||
|
stcgal is a full-featured Open Source replacement for STC's Windows
|
||||||
|
software; it supports a wide range of MCUs, it is very portable and
|
||||||
|
suitable for automation.
|
32
debian/copyright
vendored
Normal file
32
debian/copyright
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: stcgal
|
||||||
|
Upstream-Contact: Grigori Goronzy <greg@kinoho.net>
|
||||||
|
Source: https://github.com/grigorig/stcgal
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2013-2015 Grigori Goronzy <greg@kinoho.net>
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
Files: debian/*
|
||||||
|
Copyright: 2015 Andrew 'Necromant' Andrianov <andrew@ncrmnt.org>
|
||||||
|
2015 Grigori Goronzy <greg@kinoho.net>
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
License: MIT
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
.
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
4
debian/docs
vendored
Normal file
4
debian/docs
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
README.md
|
||||||
|
doc/USAGE.md
|
||||||
|
doc/MODELS.md
|
||||||
|
doc/FAQ.md
|
7
debian/rules
vendored
Executable file
7
debian/rules
vendored
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
|
||||||
|
export PYBUILD_NAME=stcgal
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --with python3 --buildsystem=pybuild
|
||||||
|
|
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.0 (native)
|
@ -1,30 +1,22 @@
|
|||||||
Supported MCU models
|
Supported MCU models
|
||||||
====================
|
====================
|
||||||
|
|
||||||
stcgal should fully support STC 89/90/10/11/12/15/8/32 series MCUs.
|
stcgal should fully support STC 89/90/10/11/12/15/8 series MCUs.
|
||||||
|
|
||||||
So far, stcgal was tested with the following MCU models:
|
So far, stcgal was tested with the following MCU models:
|
||||||
|
|
||||||
STC89/90 series
|
|
||||||
* STC89C52RC (BSL version: 4.3C/6.6C)
|
* STC89C52RC (BSL version: 4.3C/6.6C)
|
||||||
* STC89C54RD+ (BSL version: 4.3C)
|
|
||||||
* STC90C52RC (BSL version: 4.3C)
|
* STC90C52RC (BSL version: 4.3C)
|
||||||
* STC90C58RD+ (BSL version: 4.3C)
|
* STC89C54RD+ (BSL version: 4.3C)
|
||||||
|
|
||||||
STC10/11 series
|
|
||||||
* STC10F04XE (BSL version: 6.5J)
|
|
||||||
* STC11F02E (BSL version: 6.5K)
|
|
||||||
* STC11F08XE (BSL version: 6.5M)
|
|
||||||
|
|
||||||
STC12 series
|
|
||||||
* STC12C2052 (BSL version: 5.8D)
|
* STC12C2052 (BSL version: 5.8D)
|
||||||
* STC12C2052AD (BSL version: 5.8D)
|
* STC12C2052AD (BSL version: 5.8D)
|
||||||
* STC12C5608AD (BSL version: 6.0G)
|
* STC12C5608AD (BSL version: 6.0G)
|
||||||
* STC12C5A16S2 (BSL version: 6.2I)
|
* STC12C5A16S2 (BSL version: 6.2I)
|
||||||
* STC12C5A60S2 (BSL version: 6.2I/7.1I)
|
* STC12C5A60S2 (BSL version: 6.2I/7.1I)
|
||||||
|
* STC11F02E (BSL version: 6.5K)
|
||||||
|
* STC10F04XE (BSL version: 6.5J)
|
||||||
|
* STC11F08XE (BSL version: 6.5M)
|
||||||
* STC12C5204AD (BSL version: 6.6H)
|
* STC12C5204AD (BSL version: 6.6H)
|
||||||
|
|
||||||
STC15 series
|
|
||||||
* STC15F104E (BSL version: 6.7Q)
|
* STC15F104E (BSL version: 6.7Q)
|
||||||
* STC15F204EA (BSL version: 6.7R)
|
* STC15F204EA (BSL version: 6.7R)
|
||||||
* STC15L104W (BSL version: 7.1.4Q)
|
* STC15L104W (BSL version: 7.1.4Q)
|
||||||
@ -32,25 +24,9 @@ STC15 series
|
|||||||
* IAP15F2K61S2 (BSL version: 7.1.4S)
|
* IAP15F2K61S2 (BSL version: 7.1.4S)
|
||||||
* STC15L2K16S2 (BSL version: 7.2.4S)
|
* STC15L2K16S2 (BSL version: 7.2.4S)
|
||||||
* IAP15L2K61S2 (BSL version: 7.2.5S)
|
* IAP15L2K61S2 (BSL version: 7.2.5S)
|
||||||
* STC15W408AS (BSL version: 7.2.4T and 7.2.5T)
|
* STC15W408AS (BSL version: 7.2.4T)
|
||||||
* STC15W4K56S4 (BSL version: 7.3.4T and 7.3.7T, UART and USB mode)
|
* STC15W4K56S4 (BSL version: 7.3.4T, UART and USB mode)
|
||||||
|
* STC8A8K64S4A12 (BSL version: 7.3.9U)
|
||||||
STC8 series
|
|
||||||
* STC8A8K64S4A12 (BSL version: 7.3.9U and 7.3.12U)
|
|
||||||
* STC8F2K08S2 (BSL version: 7.3.10U)
|
* STC8F2K08S2 (BSL version: 7.3.10U)
|
||||||
* STC8A8K64D4 (BSL version: 7.4.2U)
|
|
||||||
* STC8G1K08A-8PIN (BSL version: 7.3.12U)
|
|
||||||
* STC8G1K08-20/16PIN (BSL version: 7.3.12U)
|
|
||||||
* STC8G1K17-20/16PIN (BSL version: 7.3.12U)
|
|
||||||
* STC8G2K64S4 (BSL version: 7.3.11U)
|
|
||||||
* STC8H1K08 (BSL version: 7.3.12U)
|
|
||||||
* STC8H1K17T (BSL version: 7.4.5U)
|
|
||||||
* STC8H3K64S2 (BSL version: 7.4.1U)
|
|
||||||
* STC8H3K64S4 (BSL version: 7.4.1U)
|
|
||||||
* STC8H4K64TL (BSL version: 7.4.3U)
|
|
||||||
* STC8H8K64U (BSL version: 7.4.4U)
|
|
||||||
|
|
||||||
STC32 series
|
|
||||||
* STC32G12K128-Beta (BSL version: 7.4.4U)
|
|
||||||
|
|
||||||
Compatibility reports, both negative and positive, are welcome.
|
Compatibility reports, both negative and positive, are welcome.
|
||||||
|
34
doc/USAGE.md
34
doc/USAGE.md
@ -4,13 +4,13 @@ Usage
|
|||||||
Call stcgal with ```-h``` for usage information.
|
Call stcgal with ```-h``` for usage information.
|
||||||
|
|
||||||
```
|
```
|
||||||
usage: stcgal [-h] [-e] [-a] [-A {dtr,rts}] [-r RESETCMD]
|
usage: stcgal.py [-h] [-a] [-r RESETCMD]
|
||||||
[-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,stc8d,stc8g,usb15,auto}]
|
[-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}]
|
||||||
[-p PORT] [-b BAUD] [-l HANDSHAKE] [-o OPTION] [-t TRIM] [-D]
|
[-p PORT] [-b BAUD] [-l HANDSHAKE] [-o OPTION] [-t TRIM] [-D]
|
||||||
[-V]
|
[-V]
|
||||||
[code_image] [eeprom_image]
|
[code_image] [eeprom_image]
|
||||||
|
|
||||||
stcgal 1.7 - an STC MCU ISP flash tool
|
stcgal 1.5 - an STC MCU ISP flash tool
|
||||||
(C) 2014-2018 Grigori Goronzy and others
|
(C) 2014-2018 Grigori Goronzy and others
|
||||||
https://github.com/grigorig/stcgal
|
https://github.com/grigorig/stcgal
|
||||||
|
|
||||||
@ -18,19 +18,16 @@ positional arguments:
|
|||||||
code_image code segment file to flash (BIN/HEX)
|
code_image code segment file to flash (BIN/HEX)
|
||||||
eeprom_image eeprom segment file to flash (BIN/HEX)
|
eeprom_image eeprom segment file to flash (BIN/HEX)
|
||||||
|
|
||||||
options:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
-e, --erase only erase flash memory
|
|
||||||
-a, --autoreset cycle power automatically by asserting DTR
|
-a, --autoreset cycle power automatically by asserting DTR
|
||||||
-A {dtr,rts,dtr_inverted,rts_inverted}, --resetpin {dtr,rts,dtr_inverted,rts_inverted}
|
|
||||||
pin to hold down when using --autoreset (default: DTR)
|
|
||||||
-r RESETCMD, --resetcmd RESETCMD
|
-r RESETCMD, --resetcmd RESETCMD
|
||||||
shell command for board power-cycling (instead of DTR
|
shell command for board power-cycling (instead of DTR
|
||||||
assertion)
|
assertion)
|
||||||
-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,stc8d,stc8g,usb15,auto}, --protocol {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,stc8d,stc8g,usb15,auto}
|
-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}, --protocol {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}
|
||||||
protocol version (default: auto)
|
protocol version (default: auto)
|
||||||
-p PORT, --port PORT serial port device
|
-p PORT, --port PORT serial port device
|
||||||
-b BAUD, --baud BAUD transfer baud rate (default: 115200)
|
-b BAUD, --baud BAUD transfer baud rate (default: 19200)
|
||||||
-l HANDSHAKE, --handshake HANDSHAKE
|
-l HANDSHAKE, --handshake HANDSHAKE
|
||||||
handshake baud rate (default: 2400)
|
handshake baud rate (default: 2400)
|
||||||
-o OPTION, --option OPTION
|
-o OPTION, --option OPTION
|
||||||
@ -43,12 +40,6 @@ options:
|
|||||||
|
|
||||||
Most importantly, ```-p``` sets the serial port to be used for programming.
|
Most importantly, ```-p``` sets the serial port to be used for programming.
|
||||||
|
|
||||||
### Transfer baud rate
|
|
||||||
|
|
||||||
The default value of 115200 Baud is supported by all MCU starting with
|
|
||||||
the STC15 family, and at least the STC12C5A56S2 before that. For older
|
|
||||||
MCU, you might have to use ```-b 19200``` for correct operation.
|
|
||||||
|
|
||||||
### Protocols
|
### Protocols
|
||||||
|
|
||||||
STC MCUs use a variety of related but incompatible protocols for the
|
STC MCUs use a variety of related but incompatible protocols for the
|
||||||
@ -58,15 +49,12 @@ and MCU series is as follows:
|
|||||||
|
|
||||||
* ```auto``` Automatic detection of UART based protocols (default)
|
* ```auto``` Automatic detection of UART based protocols (default)
|
||||||
* ```stc89``` STC89/90 series
|
* ```stc89``` STC89/90 series
|
||||||
* ```stc89a``` STC89/90 series (BSL 7.2.5C)
|
|
||||||
* ```stc12a``` STC12x052 series and possibly others
|
* ```stc12a``` STC12x052 series and possibly others
|
||||||
* ```stc12b``` STC12x52 series, STC12x56 series and possibly others
|
* ```stc12b``` STC12x52 series, STC12x56 series and possibly others
|
||||||
* ```stc12``` Most STC10/11/12 series
|
* ```stc12``` Most STC10/11/12 series
|
||||||
* ```stc15a``` STC15x104E and STC15x204E(A) series
|
* ```stc15a``` STC15x104E and STC15x204E(A) series
|
||||||
* ```stc15``` Most STC15 series
|
* ```stc15``` Most STC15 series
|
||||||
* ```stc8``` STC8A8K64S4A12 and STC8F series
|
* ```stc8``` STC8 series
|
||||||
* ```stc8d``` All STC8 and STC32 series
|
|
||||||
* ```stc8g``` STC8G1 and STC8H1 series
|
|
||||||
* ```usb15``` USB support on STC15W4 series
|
* ```usb15``` USB support on STC15W4 series
|
||||||
|
|
||||||
The text files in the doc/reverse-engineering subdirectory provide an
|
The text files in the doc/reverse-engineering subdirectory provide an
|
||||||
@ -254,4 +242,4 @@ STC15W4 series have an USB-based BSL that can be optionally
|
|||||||
used. USB support in stcgal is experimental and might change in the
|
used. USB support in stcgal is experimental and might change in the
|
||||||
future. USB mode is enabled by using the ```usb15``` protocol. The
|
future. USB mode is enabled by using the ```usb15``` protocol. The
|
||||||
port (```-p```) flag as well as the baudrate options are ignored for
|
port (```-p```) flag as well as the baudrate options are ignored for
|
||||||
the USB protocol. RC frequency trimming is not supported.
|
the USB protocol. RC frequency trimming is not supported.
|
@ -1,484 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
*
|
|
||||||
* Copyright (c) 2022 Vincent DEFERT. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This program automates the procedure explained below and generates
|
|
||||||
* on the standard output the content of the 'models' list of models.py.
|
|
||||||
*
|
|
||||||
* It takes the name of the stc-isp executable as argument.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Manual procedure to read MCU definitions from a new STC-ISP executable
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* We want to extract 2 tables from the executable, one with MCU names and
|
|
||||||
* the other with their characteristics, let's call them "Name Table" and
|
|
||||||
* "Info Table" respectively.
|
|
||||||
*
|
|
||||||
* The Info Table appears first in the executable and contains references
|
|
||||||
* to the MCU name in the Name Table. Each entry in the Name Table is 16
|
|
||||||
* bytes long, 32 for the Info Table. New entries are prepended to the
|
|
||||||
* Info Table, and appended to the Name Table. Of course, both have the
|
|
||||||
* same number of entries.
|
|
||||||
*
|
|
||||||
* This means that the Name Table is very easy to locate, as well as the
|
|
||||||
* end of the Info Table, but not its beginning, which must be calculated.
|
|
||||||
*
|
|
||||||
* Finally, the field of an Info Table entry that references the MCU name
|
|
||||||
* is expressed as a memory address, not a file position, so we'll need to
|
|
||||||
* determine the base memory address of the name table.
|
|
||||||
*
|
|
||||||
* 1. Dump the content of the executable in a text file.
|
|
||||||
*
|
|
||||||
* hexdump -C stc-isp-v6.89G.exe > stc-isp-v6.89G.txt
|
|
||||||
*
|
|
||||||
* 2. Locate the first entry of the Name Table.
|
|
||||||
*
|
|
||||||
* Search for the following byte sequence:
|
|
||||||
* 53 54 43 39 30 4c 45 35 31 36 41 44 00 00 00 00
|
|
||||||
* (i.e. nul-terminated "STC90LE516AD" string).
|
|
||||||
*
|
|
||||||
* Let's call this file position NTS (Name Table Start).
|
|
||||||
*
|
|
||||||
* 3. Locate the end of the Name Table.
|
|
||||||
*
|
|
||||||
* Search for the following byte sequence:
|
|
||||||
* 55 4e 4b 4e 4f 57 4e 00 25 30 36 58 00 00 00 00
|
|
||||||
* (i.e. nul-terminated "UNKNOWN" and "%06X" strings).
|
|
||||||
*
|
|
||||||
* Let's call this file position NTE (Name Table End).
|
|
||||||
*
|
|
||||||
* 4. Find the end of the Info Table.
|
|
||||||
*
|
|
||||||
* Search for the following byte sequence (fixed last entry):
|
|
||||||
* 05 46 01 00 xx xx xx xx 90 f1 00 00 00 f8 00 00
|
|
||||||
* 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00
|
|
||||||
*
|
|
||||||
* Bytes marked as 'xx' must be ignored while searching
|
|
||||||
*
|
|
||||||
* [Note: searching for '90 f1 00 00 00 f8 00 00' is sufficient.]
|
|
||||||
*
|
|
||||||
* It should be followed by 32 zeroed bytes. Let's call the file position
|
|
||||||
* of the first zeroed byte ITE (Info Table End).
|
|
||||||
*
|
|
||||||
* 5. Find the beginning of the Info Table.
|
|
||||||
*
|
|
||||||
* The Info Table start with a block of 32 zeroed bytes except bytes
|
|
||||||
* 4-7 which point at NTE, i.e. an info block pointing at the 'UNKNOWN'
|
|
||||||
* MCU name. It's the only reliable way to determine the location of
|
|
||||||
* the Info Table.
|
|
||||||
*
|
|
||||||
* Our first valid info block will thus be the offset of the Unknown
|
|
||||||
* block + 32. Let's call this file position ITS (Info Table Start).
|
|
||||||
*
|
|
||||||
* 6. Calculate the number of MCU definitions (i.e. Info Table entries).
|
|
||||||
*
|
|
||||||
* NB_MCU = (ITE - ITS) / 32
|
|
||||||
*
|
|
||||||
* 7. Determine the base memory address of the name table.
|
|
||||||
*
|
|
||||||
* Let's suppose 'xx xx xx xx' is '9c f7 4a 00'. As it belongs to the Info
|
|
||||||
* Table entry describing the first item of the Name Table, we directly
|
|
||||||
* have what we're looking for, i.e. 0x004af79c.
|
|
||||||
*
|
|
||||||
* NTBA = littleEndianOf32bitUnsignedInt('xx xx xx xx')
|
|
||||||
*
|
|
||||||
* The index in the Name Table corresponding to a given Info Table item
|
|
||||||
* is thus:
|
|
||||||
*
|
|
||||||
* NAME_IDX = (nameAddressFieldOfInfoTableItem - NTBA) / 0x10
|
|
||||||
*
|
|
||||||
* NOTE: for some reason, the Info Table entries of the STC08XE-3V and
|
|
||||||
* STC08XE-5V each have 2 distinct mcuId, which gives 1115 Info Table
|
|
||||||
* entries for 1113 strings in the Name Table.
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// Must be updated with the "UNKNOWN" name offset before use.
|
|
||||||
static uint8_t infoTableStartSignature[] = {
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
// 0x90, 0xf1 is the magic number of the STC90LE516AD
|
|
||||||
// We test only the last 24 byte of its 32-byte entry, as they are
|
|
||||||
// sufficiently discriminating and do not depend on a particular
|
|
||||||
// executable release.
|
|
||||||
static const uint8_t infoTableEndSignature[] = {
|
|
||||||
0x90, 0xf1, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
// NUL-terminated "STC90LE516AD" followed by 3 NUL bytes
|
|
||||||
static const uint8_t nameTableStartSignature[] = {
|
|
||||||
0x53, 0x54, 0x43, 0x39, 0x30, 0x4c, 0x45, 0x35,
|
|
||||||
0x31, 0x36, 0x41, 0x44, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
// NUL-terminated "UNKNOWN" and "%06X" followed by 3 NUL bytes
|
|
||||||
static const uint8_t nameTableEndSignature[] = {
|
|
||||||
0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x00,
|
|
||||||
0x25, 0x30, 0x36, 0x58, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t nameAddr;
|
|
||||||
uint32_t mcuId;
|
|
||||||
uint32_t flashSize;
|
|
||||||
uint32_t eepromSize;
|
|
||||||
uint32_t eepromStartAddr; // STC89 & STC90 only. 0 means IAP.
|
|
||||||
uint32_t totalSize;
|
|
||||||
uint32_t unknown2;
|
|
||||||
} MCUInfo;
|
|
||||||
|
|
||||||
// Bit 1 is 1 for MCU which can accept 5V power supply voltage, be it
|
|
||||||
// exclusively or not, and 0 for low-voltage only MCU (around 3.3V).
|
|
||||||
#define FLAG_ACCEPT_5V_SUPPLY_VOLTAGE 0x00000002
|
|
||||||
|
|
||||||
// Bit 3 is 1 for so-called "IAP" MCU, meaning the start address of the
|
|
||||||
// flash portion used for EEPROM emulation can be configured.
|
|
||||||
#define FLAG_CONFIGURABLE_EEPROM_SIZE 0x00000008
|
|
||||||
|
|
||||||
// Bit 7 is 1 for MCU with an adjustable internal RC oscillator, i.e.
|
|
||||||
// that supports calibration. When bits 7 and 8 are both 0, the MCU has
|
|
||||||
// no IRCO at all (external crystal only).
|
|
||||||
#define FLAG_CONFIGURABLE_IRCO_FREQ 0x00000080
|
|
||||||
|
|
||||||
// Bit 8 is 1 for MCU with a fixed-frequency internal RC oscillator
|
|
||||||
// (the old IRC* models).
|
|
||||||
#define FLAG_FIXED_FREQUENCY_IRCO 0x00000100
|
|
||||||
|
|
||||||
// Bit 12 is 1 for MCS-251 MCU, i.e. with a flash size that can be
|
|
||||||
// larger than 64KB.
|
|
||||||
#define FLAG_IS_MCS251_MCU 0x00001000
|
|
||||||
|
|
||||||
#define SEARCH_BUFFER_LEN 8192
|
|
||||||
#define MCU_NAME_LEN 16
|
|
||||||
|
|
||||||
#define NO_MATCH -1
|
|
||||||
#define FOUND -2
|
|
||||||
|
|
||||||
// May help to guess the meaning of new flags as they are added.
|
|
||||||
|
|
||||||
static void toBits(uint32_t n, char *result) {
|
|
||||||
*result = '\0';
|
|
||||||
int pos = 0;
|
|
||||||
|
|
||||||
for (uint32_t mask = 0x80000000; mask; mask >>= 1, pos++) {
|
|
||||||
if (pos) {
|
|
||||||
strcat(result, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n & mask) {
|
|
||||||
strcat(result, "1");
|
|
||||||
} else {
|
|
||||||
strcat(result, "0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printCSVHeader(FILE *csvFile) {
|
|
||||||
if (csvFile != NULL) {
|
|
||||||
fprintf(csvFile, "name,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,flags (hex),mcuId,flashSize,eepromSize,eepromStartAddr,totalSize,unknown2\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printCSVRow(FILE *csvFile, const MCUInfo *info, const char *name) {
|
|
||||||
char flags[64];
|
|
||||||
|
|
||||||
if (csvFile != NULL) {
|
|
||||||
toBits(info->flags, flags);
|
|
||||||
|
|
||||||
fprintf(
|
|
||||||
csvFile,
|
|
||||||
"%s,%s,0x%08x,0x%04x,%u,%u,0x%08x,%u,0x%08x\n",
|
|
||||||
name,
|
|
||||||
flags,
|
|
||||||
info->flags,
|
|
||||||
(uint16_t) info->mcuId,
|
|
||||||
info->flashSize,
|
|
||||||
info->eepromSize,
|
|
||||||
info->eepromStartAddr,
|
|
||||||
info->totalSize,
|
|
||||||
info->unknown2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *toBool(uint32_t flags, uint32_t mask) {
|
|
||||||
return (flags & mask) ? "True" : "False";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printMCUModel(const MCUInfo *info, const char *name) {
|
|
||||||
printf(
|
|
||||||
" MCUModel(name='%s', magic=0x%04x, total=%u, code=%u, eeprom=%u, iap=%s, calibrate=%s, mcs251=%s),\n",
|
|
||||||
name,
|
|
||||||
(uint16_t) info->mcuId,
|
|
||||||
info->totalSize,
|
|
||||||
info->flashSize,
|
|
||||||
info->eepromSize,
|
|
||||||
toBool(info->flags, FLAG_CONFIGURABLE_EEPROM_SIZE),
|
|
||||||
toBool(info->flags, FLAG_CONFIGURABLE_IRCO_FREQ),
|
|
||||||
toBool(info->flags, FLAG_IS_MCS251_MCU)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printUsage(const char *pgmName) {
|
|
||||||
printf("Usage: %s <STC-ISP_executable> [<CSV_output_file>]\n", pgmName);
|
|
||||||
printf("\n");
|
|
||||||
printf("- STC-ISP_executable is the file from which MCU models must be extracted.\n");
|
|
||||||
printf("Their list will be printed on the standard output.\n");
|
|
||||||
printf("\n");
|
|
||||||
printf("- The optional CSV_output_file will receive the MCU flags detail of each model\n");
|
|
||||||
printf("to facilitate reverse engineering efforts.\n");
|
|
||||||
printf("\n");
|
|
||||||
printf("Example: %s stc-isp-v6.91Q.exe MCUFlags.csv > MCUModels.txt\n", pgmName);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, const char **argv) {
|
|
||||||
int rc = 1;
|
|
||||||
MCUInfo *infoTable = NULL;
|
|
||||||
char *nameTable = NULL;
|
|
||||||
int mcuCount = 0;
|
|
||||||
uint32_t infoTableStartOffset = 0;
|
|
||||||
uint32_t infoTableEndOffset = 0;
|
|
||||||
uint32_t nameTableStartOffset = 0;
|
|
||||||
uint32_t nameTableEndOffset = 0;
|
|
||||||
uint32_t baseAddr = 0;
|
|
||||||
int nameTableSize = 0;
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
fprintf(stderr, "ERROR: missing argument\n");
|
|
||||||
printUsage(argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *exeFile = fopen(argv[1], "rb");
|
|
||||||
FILE *csvFile = NULL;
|
|
||||||
|
|
||||||
if (exeFile != NULL) {
|
|
||||||
if (argc > 2) {
|
|
||||||
csvFile = fopen(argv[2], "wt");
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = 2;
|
|
||||||
uint8_t *buffer = (uint8_t *) malloc(SEARCH_BUFFER_LEN);
|
|
||||||
|
|
||||||
if (buffer != NULL) {
|
|
||||||
rc = 3;
|
|
||||||
int infoTableEndMatch = NO_MATCH;
|
|
||||||
int nameTableStartMatch = NO_MATCH;
|
|
||||||
int nameTableEndMatch = NO_MATCH;
|
|
||||||
uint32_t fileOffset = 0;
|
|
||||||
int bytesRead = 0;
|
|
||||||
|
|
||||||
while ((bytesRead = fread(buffer, 1, SEARCH_BUFFER_LEN, exeFile)) != 0) {
|
|
||||||
for (int curByte = 0; curByte < SEARCH_BUFFER_LEN; curByte++) {
|
|
||||||
int noMatch = 1;
|
|
||||||
|
|
||||||
if (infoTableEndMatch > NO_MATCH) {
|
|
||||||
if (infoTableEndSignature[infoTableEndMatch + 1] == buffer[curByte]) {
|
|
||||||
infoTableEndMatch++;
|
|
||||||
noMatch = 0;
|
|
||||||
|
|
||||||
if (infoTableEndMatch == (sizeof(infoTableEndSignature) -1)) {
|
|
||||||
infoTableEndMatch = FOUND;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
infoTableEndMatch = NO_MATCH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nameTableStartMatch > NO_MATCH) {
|
|
||||||
if (nameTableStartSignature[nameTableStartMatch + 1] == buffer[curByte]) {
|
|
||||||
nameTableStartMatch++;
|
|
||||||
noMatch = 0;
|
|
||||||
|
|
||||||
if (nameTableStartMatch == (sizeof(nameTableStartSignature) -1)) {
|
|
||||||
nameTableStartMatch = FOUND;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nameTableStartMatch = NO_MATCH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nameTableEndMatch > NO_MATCH) {
|
|
||||||
if (nameTableEndSignature[nameTableEndMatch + 1] == buffer[curByte]) {
|
|
||||||
nameTableEndMatch++;
|
|
||||||
noMatch = 0;
|
|
||||||
|
|
||||||
if (nameTableEndMatch == (sizeof(nameTableEndSignature) - 1)) {
|
|
||||||
nameTableEndMatch = FOUND;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nameTableEndMatch = NO_MATCH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (noMatch) {
|
|
||||||
if (infoTableEndMatch == NO_MATCH && infoTableEndSignature[0] == buffer[curByte]) {
|
|
||||||
infoTableEndMatch = 0;
|
|
||||||
infoTableEndOffset = fileOffset + curByte;
|
|
||||||
} else if (nameTableStartMatch == NO_MATCH && nameTableStartSignature[0] == buffer[curByte]) {
|
|
||||||
nameTableStartMatch = 0;
|
|
||||||
nameTableStartOffset = fileOffset + curByte;
|
|
||||||
} else if (nameTableEndMatch == NO_MATCH && nameTableEndSignature[0] == buffer[curByte]) {
|
|
||||||
nameTableEndMatch = 0;
|
|
||||||
nameTableEndOffset = fileOffset + curByte;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (infoTableEndMatch == FOUND && nameTableStartMatch == FOUND && nameTableEndMatch == FOUND) {
|
|
||||||
rc = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileOffset += SEARCH_BUFFER_LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc == 0) {
|
|
||||||
// Point to the byte immediately following the table's last entry.
|
|
||||||
infoTableEndOffset += sizeof(infoTableEndSignature);
|
|
||||||
// Read last item of Info Table
|
|
||||||
fseek(exeFile, infoTableEndOffset - sizeof(MCUInfo), SEEK_SET);
|
|
||||||
MCUInfo lastItem;
|
|
||||||
fread(&lastItem, sizeof(MCUInfo), 1, exeFile);
|
|
||||||
// We need it now in order to calculate the memory address
|
|
||||||
// corresponding to the UNKNOWN name.
|
|
||||||
// We'll also need baseAddr later, anyway.
|
|
||||||
baseAddr = lastItem.nameAddr;
|
|
||||||
|
|
||||||
rc = 4;
|
|
||||||
int infoTableStartMatch = NO_MATCH;
|
|
||||||
uint32_t fileOffset = 0;
|
|
||||||
int bytesRead = 0;
|
|
||||||
*((uint32_t *)(infoTableStartSignature)) = (baseAddr - nameTableStartOffset) + nameTableEndOffset;
|
|
||||||
fseek(exeFile, 0, SEEK_SET);
|
|
||||||
|
|
||||||
while ((bytesRead = fread(buffer, 1, SEARCH_BUFFER_LEN, exeFile)) != 0) {
|
|
||||||
for (int curByte = 0; curByte < SEARCH_BUFFER_LEN; curByte++) {
|
|
||||||
if (infoTableStartMatch > NO_MATCH) {
|
|
||||||
if (infoTableStartSignature[infoTableStartMatch + 1] == buffer[curByte]) {
|
|
||||||
infoTableStartMatch++;
|
|
||||||
|
|
||||||
if (infoTableStartMatch == (sizeof(infoTableStartSignature) - 1)) {
|
|
||||||
infoTableStartMatch = FOUND;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
infoTableStartMatch = NO_MATCH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (infoTableStartMatch == NO_MATCH && infoTableStartSignature[0] == buffer[curByte]) {
|
|
||||||
infoTableStartMatch = 0;
|
|
||||||
infoTableStartOffset = fileOffset + curByte;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (infoTableStartMatch == FOUND) {
|
|
||||||
// Point to the first entry following the Unknown one.
|
|
||||||
infoTableStartOffset += sizeof(MCUInfo) - 4;
|
|
||||||
// Calculate number of entries while we're at it
|
|
||||||
mcuCount = (infoTableEndOffset - infoTableStartOffset) / sizeof(MCUInfo);
|
|
||||||
rc = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileOffset += SEARCH_BUFFER_LEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
|
|
||||||
if (rc == 0) {
|
|
||||||
nameTableSize = nameTableEndOffset - nameTableStartOffset;
|
|
||||||
|
|
||||||
nameTable = (char *) malloc(nameTableSize);
|
|
||||||
|
|
||||||
if (nameTable == NULL) {
|
|
||||||
rc = 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc == 0) {
|
|
||||||
fseek(exeFile, nameTableStartOffset, SEEK_SET);
|
|
||||||
fread(nameTable, nameTableSize, 1, exeFile);
|
|
||||||
|
|
||||||
infoTable = (MCUInfo *) malloc(infoTableEndOffset - infoTableStartOffset);
|
|
||||||
|
|
||||||
if (infoTable != NULL) {
|
|
||||||
fseek(exeFile, infoTableStartOffset, SEEK_SET);
|
|
||||||
fread(infoTable, infoTableEndOffset - infoTableStartOffset, 1, exeFile);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
rc = 6;
|
|
||||||
free(nameTable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(exeFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc == 0) {
|
|
||||||
printCSVHeader(csvFile);
|
|
||||||
|
|
||||||
for (int mcu = 0; mcu < mcuCount; mcu++) {
|
|
||||||
const char *mcuName = &nameTable[infoTable[mcu].nameAddr - baseAddr];
|
|
||||||
|
|
||||||
if (strncmp(mcuName, "STC12C54", 8) == 0 || strncmp(mcuName, "STC12LE54", 9) == 0) {
|
|
||||||
// STC12x54xx always have 12KB EEPROM
|
|
||||||
infoTable[mcu].eepromSize = 12 * 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
printCSVRow(csvFile, &infoTable[mcu], mcuName);
|
|
||||||
printMCUModel(&infoTable[mcu], mcuName);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(infoTable);
|
|
||||||
free(nameTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (csvFile != NULL) {
|
|
||||||
fclose(csvFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
40
doc/reverse-engineering/dump-mcu.py
Normal file
40
doc/reverse-engineering/dump-mcu.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# This curious script dumps all model info from STC-ISP.
|
||||||
|
# Data is directly read from the binary.
|
||||||
|
# Offsets are for stc-isp-15xx-v6.86O.exe, sha1sum f70e317d758ef8c942613a8b0540147d7170589b
|
||||||
|
|
||||||
|
MCU_TABLE_OFFSET = 0x0006ac80
|
||||||
|
MCU_TABLE_SIZE = 984
|
||||||
|
MCU_RECORD_SIZE = 32
|
||||||
|
MCU_NAMES_OFFSET = 0x00087810
|
||||||
|
MCU_NAMES_PTR_OFFSET = 0x00487810
|
||||||
|
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
|
||||||
|
inp = open(sys.argv[1], "rb")
|
||||||
|
|
||||||
|
for i in range(MCU_TABLE_SIZE):
|
||||||
|
mcu_record_offset = MCU_TABLE_OFFSET + MCU_RECORD_SIZE * i
|
||||||
|
inp.seek(mcu_record_offset)
|
||||||
|
mcu_record = inp.read(MCU_RECORD_SIZE)
|
||||||
|
flags, name_ptr, mcu_id, code_size, ee_size, _, total_size, _ = struct.unpack("<8I", mcu_record)
|
||||||
|
mcu_id &= 0xffff
|
||||||
|
|
||||||
|
mcu_name_offset = MCU_NAMES_OFFSET + (name_ptr - MCU_NAMES_PTR_OFFSET)
|
||||||
|
inp.seek(mcu_name_offset)
|
||||||
|
name_str = inp.read(16).split(b'\00')[0].decode("ascii")
|
||||||
|
|
||||||
|
# TODO: With some MCUs, the amount of available EEPROM depends on the BSL version.
|
||||||
|
# Generally, newer BSLs free up a KB of additional EEPROM. Currently, always the
|
||||||
|
# maximum amount (with newer BSL) is reported.
|
||||||
|
|
||||||
|
# STC12x54xx always have 12 KB eeprom
|
||||||
|
if name_str.startswith("STC12C54") or name_str.startswith("STC12LE54"):
|
||||||
|
ee_size = 12 * 1024
|
||||||
|
|
||||||
|
print("MCUModel(name='%s', magic=0x%02x%02x, total=%d, code=%d, eeprom=%d)," %
|
||||||
|
(name_str, mcu_id >> 8, mcu_id & 0xff, total_size, code_size, ee_size))
|
||||||
|
|
||||||
|
inp.close()
|
||||||
|
|
Binary file not shown.
Binary file not shown.
@ -1,80 +0,0 @@
|
|||||||
001046: Read (UP): 2021-01-09 15:37:44.9125552 +0.0085328
|
|
||||||
46 b9 68 00 29 50 fd 84 1e 11 4d 05 8e 96 27 7c F.h.)P....M...'|
|
|
||||||
^
|
|
||||||
cpu_6t
|
|
||||||
04 47 01 7f 40 81 72 43 00 f0 51 05 80 00 ff ff .G..@.rC..Q.....
|
|
||||||
^ ^ ^ ^
|
|
||||||
freq_counte | | |
|
|
||||||
bl_version |
|
|
||||||
bl_stepping |
|
|
||||||
bl_minor
|
|
||||||
|
|
||||||
|
|
||||||
ff ff 38 20 20 02 19 60 0d a0 16 ..8 ..`...
|
|
||||||
|
|
||||||
|
|
||||||
001057: Write (DOWN): 2021-01-09 15:37:44.9814096 +0.0129872
|
|
||||||
46 b9 6a 00 0a 01 ff fd 82 02 f3 16 F.j.........
|
|
||||||
^
|
|
||||||
handshake
|
|
||||||
|
|
||||||
|
|
||||||
001072: Read (UP): 2021-01-09 15:37:45.0836096 +0.0115168
|
|
||||||
46 b9 68 00 07 01 00 70 16 F.h....p.
|
|
||||||
|
|
||||||
001113: Write (DOWN): 2021-01-09 15:37:45.1352048 +0.0171904
|
|
||||||
46 b9 6a 00 0b 05 00 00 46 b9 01 79 16 F.j.....F..y.
|
|
||||||
^
|
|
||||||
ping-pong
|
|
||||||
|
|
||||||
|
|
||||||
001116: Read (UP): 2021-01-09 15:37:45.1392768 +0.0017200
|
|
||||||
46 b9 68 00 07 05 00 74 16 F.h....t.
|
|
||||||
|
|
||||||
|
|
||||||
001127: Write (DOWN): 2021-01-09 15:37:45.1502464 +0.0109472
|
|
||||||
46 b9 6a 00 0b 03 00 00 46 b9 01 77 16 F.j.....F..w.
|
|
||||||
^
|
|
||||||
erase_flash ?
|
|
||||||
|
|
||||||
|
|
||||||
001170: Read (UP): 2021-01-09 15:37:45.4729040 +0.0099696
|
|
||||||
46 b9 68 00 0e 03 f0 51 c5 f2 06 7c 14 04 07 16 F.h....Q...|....
|
|
||||||
^
|
|
||||||
mcu id
|
|
||||||
|
|
||||||
|
|
||||||
001181: Write (DOWN): 2021-01-09 15:37:45.4791856 +0.0062576
|
|
||||||
46 b9 6a 00 8b 32 00 00 46 b9 02 00 08 12 00 3f F.j..2..F......?
|
|
||||||
^ ^
|
|
||||||
write address
|
|
||||||
write data
|
|
||||||
80 fe 75 81 07 12 00 4c e5 82 60 03 02 00 03 e4 ..u....L..`.....
|
|
||||||
78 ff f6 d8 fd 02 00 03 ae 82 af 83 8e 04 8f 05 x...............
|
|
||||||
1e be ff 01 1f ec 4d 60 0f 7c 90 7d 01 1c bc ff ......M`.|.}....
|
|
||||||
01 1d ec 4d 70 f7 80 e4 22 90 03 e8 12 00 1e e5 ...Mp...".......
|
|
||||||
80 f4 f5 80 80 f3 75 82 00 22 ff ff ff ff ff ff ......u.."......
|
|
||||||
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
|
|
||||||
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
|
|
||||||
ff ff ff ff ff ff ff ff ff ff 52 f9 16 ..........R..
|
|
||||||
|
|
||||||
|
|
||||||
001188: Read (UP): 2021-01-09 15:37:45.5301744 +0.0047088
|
|
||||||
46 b9 68 00 08 02 54 00 c6 16 F.h...T...
|
|
||||||
^
|
|
||||||
write done
|
|
||||||
|
|
||||||
|
|
||||||
001199: Write (DOWN): 2021-01-09 15:37:45.5575264 +0.0273248
|
|
||||||
46 b9 6a 00 0c 04 00 00 46 b9 fd 02 76 16 F.j.....F...v.
|
|
||||||
^
|
|
||||||
write msr
|
|
||||||
|
|
||||||
|
|
||||||
001202: Read (UP): 2021-01-09 15:37:45.5625296 +0.0018304
|
|
||||||
46 b9 68 00 08 04 54 00 c8 16 F.h...T...
|
|
||||||
unknown
|
|
||||||
|
|
||||||
001213: Write (DOWN): 2021-01-09 15:37:45.5712992 +0.0087472
|
|
||||||
46 b9 6a 00 07 ff 01 70 16 F.j....p.
|
|
||||||
unknown
|
|
@ -1,84 +0,0 @@
|
|||||||
文档说明 Explanation
|
|
||||||
------------------------
|
|
||||||
此文档翻译自FAQ.md
|
|
||||||
|
|
||||||
This document was translated from FAQ.md
|
|
||||||
|
|
||||||
最后修改时间:2020年6月8日
|
|
||||||
|
|
||||||
Last modified time: June 8, 2020
|
|
||||||
|
|
||||||
常见问题
|
|
||||||
======================================
|
|
||||||
|
|
||||||
### 问题1:是否可以从芯片中读取代码(或EEPROM)存储器?
|
|
||||||
|
|
||||||
从设计上讲,这是STC的引导加载程序协议无法实现的。 STC将此视为安全功能。目前没有已知的解决方法。有关更多详细信息和讨论,请参见问题7。
|
|
||||||
|
|
||||||
### 问题2:哪些串行接口已通过stcgal测试过?
|
|
||||||
|
|
||||||
stcgal应该可以与波特率为16550的UART兼容。
|
|
||||||
但是,如今,基于USB模拟的UART是典型的情况。
|
|
||||||
以下是已通过stcgal成功测试的USB模拟UART接口芯片:
|
|
||||||
|
|
||||||
* FT232系列(操作系统:Linux,Windows)
|
|
||||||
* CH340 / CH341(操作系统:Windows,Linux需要内核4.10)
|
|
||||||
* PL2303(操作系统:Windows,Linux)
|
|
||||||
* CP2102(操作系统:Windows,Linux,macOS)
|
|
||||||
|
|
||||||
已知不起作用的接口:
|
|
||||||
|
|
||||||
* Raspberry Pi Mini UART(缺少奇偶校验支持,请启用PL011 UART)
|
|
||||||
|
|
||||||
### 问题3:stcgal 启动失败同时显示 `module 'serial' has no attribute 'PARITY_NONE'` 等类似信息
|
|
||||||
|
|
||||||
PyPI软件包“ serial”(数据序列库)和PyPI软件包“ pyserial”(stcgal所需的串行端口访问库)之间存在模块名称冲突。
|
|
||||||
您必须卸载'serial'软件包(`pip3 uninstall serial`)并重新安装'pyserial'(`pip3 install --force-reinstall pyserial`)才能解决此问题。
|
|
||||||
目前没有其他已知的解决方案。
|
|
||||||
|
|
||||||
### 问题4:stcgal无法识别MCU,并停留在“Waiting for MCU”中
|
|
||||||
|
|
||||||
有许多问题可能导致此症状:
|
|
||||||
* 电气问题和错误连接。确保正确连接了RX / TX,GND和VCC。
|
|
||||||
如果您不使用自动复位功能,还应确保仅在stcgal启动后才接通电源,因为引导加载程序仅在上电复位时被调用。
|
|
||||||
* 通过I / O引脚供电。
|
|
||||||
即使未连接VCC,也可以通过I / O引脚(例如RX / TX)为MCU供电。
|
|
||||||
在这种情况下,上电复位逻辑不起作用。请参阅下一个问题。
|
|
||||||
* erial接口不兼容。由于各种原因,一些基于USB的UART与STC MCU的兼容性很差。
|
|
||||||
您可以尝试使用选项`-l 1200`将握手波特率从标准2400波特降低到1200波特,在某些情况下可以解决这些问题。
|
|
||||||
|
|
||||||
### 问题5:如何避免MCU从I/O引脚供电?
|
|
||||||
可以采取各种补救措施来避免MCU从I/O引脚供电。
|
|
||||||
* 您可以尝试在MCU VCC和GND之间连接一个电阻(<1k),以使注入的电源短路,并希望将电压降至欠压值以下。
|
|
||||||
* 另一种选择是在可能注入功率的I / O线上插入串联电阻。例如,在RX / TX线上尝试一个类似1k的值。
|
|
||||||
* 还有另一种可能性是切换GND而不是VCC。
|
|
||||||
在大多数情况下,这应该是一个相当可靠的解决方案。
|
|
||||||
|
|
||||||
### 问题6:RC频率调整失败
|
|
||||||
首先,请确保指定的频率使用正确的单位。频率以kHz为单位指定,安全范围约为5000 kHz-30000 kHz。
|
|
||||||
此外,频率调整使用UART时钟作为时钟参考,因此UART不兼容或时钟不准确也会导致频率调整问题。如果可能的话,
|
|
||||||
尝试另一个UART芯片。
|
|
||||||
|
|
||||||
### 问题7:波特率切换失败或闪存编程失败
|
|
||||||
特别是在高编程波特率,例如, 115200波特。尝试降低波特率,或使用默认的19200波特率。
|
|
||||||
某些USB UART也会由于时序不正确而引起问题,这可能会导致各种问题。
|
|
||||||
|
|
||||||
### 问题8:如何使用自动重置功能?
|
|
||||||
标准自动重置功能的工作原理与Arduino类似。 DTR是低电平有效信号,在stcgal启动时置位500 ms,然后在其余的编程序列中置为无效。
|
|
||||||
在标准USB UART上,这将导致500 ms的低脉冲,然后是高相位。 stcgal作者推荐以下电路:
|
|
||||||
```
|
|
||||||
VCC --o o-- MCU GND
|
|
||||||
| |
|
|
||||||
.-. |
|
|
||||||
| | 1k |
|
|
||||||
| | |
|
|
||||||
'_' |
|
|
||||||
| |
|
|
||||||
| ||-+
|
|
||||||
DTR --o --||<- BS170/BSS138
|
|
||||||
||-| (N-CH MOSFET)
|
|
||||||
|
|
|
||||||
|
|
|
||||||
GND ---------o
|
|
||||||
```
|
|
||||||
该电路使用一个N沟道MOSFET作为开关来切换MCU的GND。 VCC直接连接。这避免了寄生供电问题。上拉电阻可确保在DTR输入悬空时接通MCU。
|
|
@ -1,24 +0,0 @@
|
|||||||
文档说明 Explanation
|
|
||||||
------------------------
|
|
||||||
此文档翻译自INSTALL.md
|
|
||||||
|
|
||||||
This document was translated from INSTALL.md
|
|
||||||
|
|
||||||
最后修改时间:2020年6月8日
|
|
||||||
|
|
||||||
Last modified time: June 8, 2020
|
|
||||||
|
|
||||||
安装说明
|
|
||||||
============
|
|
||||||
|
|
||||||
stcgal需要Python 3.2(或更高版本),pyserial 3.0或更高版本以及TQDM 4.0.0或更高版本。
|
|
||||||
USB支持是可选的,并且需要pyusb 1.0.0b2或更高版本。如果已经安装了依赖项,则可以使用包含的
|
|
||||||
```stcgal.py``` 脚本直接运行stcgal。
|
|
||||||
|
|
||||||
永久安装有几种选择:
|
|
||||||
|
|
||||||
* 使用Python3和```pip```。运行```pip3 install stcgal```
|
|
||||||
在系统上全局安装最新版本的stcgal。
|
|
||||||
这可能需要管理员/ root用户权限才能进行写到系统目录。
|
|
||||||
|
|
||||||
* 使用setuptools。运行`./setup.py build`来构建,并运行'sudo ./setup.py install`'来安装stcgal。
|
|
@ -1,65 +0,0 @@
|
|||||||
文档说明 Explanation
|
|
||||||
------------------------
|
|
||||||
此文档翻译自MODELS.md
|
|
||||||
|
|
||||||
This document was translated from MODELS.md
|
|
||||||
|
|
||||||
最后修改时间:2020年6月8日
|
|
||||||
|
|
||||||
Last modified time: June 8, 2020
|
|
||||||
|
|
||||||
支持的MCU型号
|
|
||||||
====================
|
|
||||||
|
|
||||||
stcgal理论上完全支持STC 89/90/10/11/12/15/8/32系列MCU。
|
|
||||||
|
|
||||||
到目前为止,stcgal已使用以下MCU模型进行了测试:
|
|
||||||
|
|
||||||
89/90系列
|
|
||||||
* STC89C52RC (BSL 版本: 4.3C/6.6C)
|
|
||||||
* STC89C54RD+ (BSL 版本: 4.3C)
|
|
||||||
* STC90C52RC (BSL 版本: 4.3C)
|
|
||||||
* STC90C58RD+ (BSL 版本: 4.3C)
|
|
||||||
|
|
||||||
STC12C系列
|
|
||||||
* STC12C2052 (BSL 版本: 5.8D)
|
|
||||||
* STC12C2052AD (BSL 版本: 5.8D)
|
|
||||||
* STC12C5608AD (BSL 版本: 6.0G)
|
|
||||||
* STC12C5A16S2 (BSL 版本: 6.2I)
|
|
||||||
* STC12C5A60S2 (BSL 版本: 6.2I/7.1I)
|
|
||||||
* STC12C5204AD (BSL 版本: 6.6H)
|
|
||||||
|
|
||||||
10/11系列价格
|
|
||||||
* STC10F04XE (BSL 版本: 6.5J)
|
|
||||||
* STC11F02E (BSL 版本: 6.5K)
|
|
||||||
* STC11F08XE (BSL 版本: 6.5M)
|
|
||||||
|
|
||||||
STC15系列
|
|
||||||
* STC15F104E (BSL 版本: 6.7Q)
|
|
||||||
* STC15F204EA (BSL 版本: 6.7R)
|
|
||||||
* STC15L104W (BSL 版本: 7.1.4Q)
|
|
||||||
* STC15F104W (BSL 版本: 7.1.4Q)
|
|
||||||
* IAP15F2K61S2 (BSL 版本: 7.1.4S)
|
|
||||||
* STC15L2K16S2 (BSL 版本: 7.2.4S)
|
|
||||||
* IAP15L2K61S2 (BSL 版本: 7.2.5S)
|
|
||||||
* STC15W408AS (BSL 版本: 7.2.4T 和 7.2.5T)
|
|
||||||
* STC15W4K56S4 (BSL 版本: 7.3.4T 和 7.3.7T, UART and USB mode)
|
|
||||||
|
|
||||||
STC8系列
|
|
||||||
* STC8A8K64S4A12 (BSL 版本: 7.3.9U 和 7.3.12U)
|
|
||||||
* STC8F2K08S2 (BSL 版本: 7.3.10U)
|
|
||||||
* STC8A8K64D4 (BSL 版本: 7.4.2U)
|
|
||||||
* STC8G1K08A-8PIN (BSL 版本: 7.3.12U)
|
|
||||||
* STC8G1K08-20/16PIN (BSL 版本: 7.3.12U)
|
|
||||||
* STC8G1K17-20/16PIN (BSL 版本: 7.3.12U)
|
|
||||||
* STC8G2K64S4 (BSL 版本: 7.3.11U)
|
|
||||||
* STC8H1K08 (BSL 版本: 7.3.12U)
|
|
||||||
* STC8H3K64S2 (BSL 版本: 7.4.1U)
|
|
||||||
* STC8H3K64S4 (BSL 版本: 7.4.1U)
|
|
||||||
* STC8H4K64TL (BSL 版本: 7.4.3U)
|
|
||||||
* STC8H8K64U (BSL 版本: 7.4.4U)
|
|
||||||
|
|
||||||
STC32系列
|
|
||||||
* STC32G12K128-Beta (BSL 版本: 7.4.4U)
|
|
||||||
|
|
||||||
欢迎提供兼容性报告,无论是负面的还是正面的。
|
|
@ -1,22 +0,0 @@
|
|||||||
文档说明 Explanation
|
|
||||||
------------------------
|
|
||||||
此文档翻译自PyPI.md
|
|
||||||
|
|
||||||
This document was translated from PyPI.md
|
|
||||||
|
|
||||||
最后修改时间:2020年6月8日
|
|
||||||
|
|
||||||
Last modified time: June 8, 2020
|
|
||||||
|
|
||||||
stcgal - 用于STC MCU的ISP闪存工具
|
|
||||||
===============================
|
|
||||||
|
|
||||||
stcgal是用于[STC MCU Ltd](http://stcmcu.com/)的命令行闪存编程工具。 兼容8051微控制器。
|
|
||||||
|
|
||||||
STC微控制器具有基于UART / USB的引导加载程序(BSL)。
|
|
||||||
它采用系统内编程,即基于数据包的协议通过串行链路刷新代码存储器和IAP存储器。
|
|
||||||
BSL还用于配置各种设备选项。 不幸的是,该协议没有公开记录,STC仅提供(粗略的)Windows GUI应用程序进行编程
|
|
||||||
|
|
||||||
stcgal是STC的Windows软件的功能全面的开源替代品。 它支持多种MCU,非常便携,适合自动下载。
|
|
||||||
|
|
||||||
[有关更多信息,请参见GitHub页面。](https://github.com/grigorig/stcgal).
|
|
@ -1,248 +0,0 @@
|
|||||||
文档说明 Explanation
|
|
||||||
------------------------
|
|
||||||
此文档翻译自USAGE.md
|
|
||||||
|
|
||||||
This document was translated from USAGE.md
|
|
||||||
|
|
||||||
最后修改时间:2020年6月8日
|
|
||||||
|
|
||||||
Last modified time: June 8, 2020
|
|
||||||
|
|
||||||
使用方法
|
|
||||||
=====
|
|
||||||
|
|
||||||
使用 ```-h``` 调用stcgal以获取使用信息。('//'后面是翻译,实际使用过程中没有后面内容)
|
|
||||||
|
|
||||||
```
|
|
||||||
usage: stcgal [-h] [-e] [-a] [-A {dtr,rts}] [-r RESETCMD]
|
|
||||||
[-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,stc8d,stc8g,usb15,auto}]
|
|
||||||
[-p PORT] [-b BAUD] [-l HANDSHAKE] [-o OPTION] [-t TRIM] [-D]
|
|
||||||
[-V]
|
|
||||||
[code_image] [eeprom_image]
|
|
||||||
|
|
||||||
stcgal 1.7 - an STC MCU ISP flash tool
|
|
||||||
(C) 2014-2018 Grigori Goronzy and others
|
|
||||||
https://github.com/grigorig/stcgal
|
|
||||||
|
|
||||||
positional arguments:
|
|
||||||
code_image code segment file to flash (BIN/HEX) //代码段文件刷新
|
|
||||||
eeprom_image eeprom segment file to flash (BIN/HEX) //EEPROM段文件刷新
|
|
||||||
|
|
||||||
optional arguments:
|
|
||||||
-h, --help show this help message and exit //显示此帮助消息并退出
|
|
||||||
-a, --autoreset cycle power automatically by asserting DTR//断言DTR自动重启电源
|
|
||||||
-A {dtr,rts}, --resetpin {dtr,rts}
|
|
||||||
pin to hold down when using --autoreset (default: DTR)
|
|
||||||
-r RESETCMD, --resetcmd RESETCMD
|
|
||||||
shell command for board power-cycling (instead of DTR //用于板上电重启的shell命令(而不是DTR断言)
|
|
||||||
assertion)
|
|
||||||
-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,stc8d,stc8g,usb15,auto}, --protocol {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,stc8d,stc8g,usb15,auto}
|
|
||||||
protocol version (default: auto) //协议版本(芯片系列)(在默认状态为auto)
|
|
||||||
-p PORT, --port PORT serial port device //串口设备
|
|
||||||
-b BAUD, --baud BAUD transfer baud rate (default: 115200) //传输波特率(默认值:115200)
|
|
||||||
-l HANDSHAKE, --handshake HANDSHAKE
|
|
||||||
handshake baud rate (default: 2400) //握手波特率(默认值:2400)
|
|
||||||
-o OPTION, --option OPTION
|
|
||||||
set option (can be used multiple times, see//设置选项(可以多次使用,请参阅文档)
|
|
||||||
documentation)
|
|
||||||
-t TRIM, --trim TRIM RC oscillator frequency in kHz (STC15+ series only)//RC振荡器频率(kHz)(仅STC15 +系列)
|
|
||||||
-D, --debug enable debug output //启用调试输出
|
|
||||||
-V, --version print version info and exit //打印版本信息并退出
|
|
||||||
```
|
|
||||||
|
|
||||||
最重要的是, ```-p``` 设置用于编程的串行端口。
|
|
||||||
|
|
||||||
### 传输波特率
|
|
||||||
|
|
||||||
所有从 STC15 系列开始的 MCU 都支持默认值 115200 波特,至少是之前的 STC12C5A56S2。
|
|
||||||
对于较旧的 MCU,您可能必须使用 ```-b 19200``` 才能正确操作。
|
|
||||||
|
|
||||||
### 通讯协议与规定
|
|
||||||
|
|
||||||
STC MCU对BSL使用各种相关但不兼容的协议。协议可以用```-P``` 标志来指定。
|
|
||||||
默认情况下,使用UART协议自动检测。协议与MCU系列的对应关系如下:
|
|
||||||
|
|
||||||
* ```auto``` 自动检测基于UART的协议(默认)
|
|
||||||
* ```stc89``` STC89/90 系列
|
|
||||||
* ```stc89a``` STC89/90 系列(BSL 7.2.5C)
|
|
||||||
* ```stc12a``` STC12x052 系列和其他类似系列
|
|
||||||
* ```stc12b``` STC12x52 系列, STC12x56 系列和其他类似系列
|
|
||||||
* ```stc12``` 多数 STC10/11/12 系列
|
|
||||||
* ```stc15a``` STC15x104E 和 STC15x204E(A) 系列
|
|
||||||
* ```stc15``` 多数 STC15 系列
|
|
||||||
* ```stc8``` STC8A8K64S4A12 和 STC8F 系列
|
|
||||||
* ```stc8d``` 所有 STC8 和 STC32 系列
|
|
||||||
* ```stc8g``` STC8G1 和 STC8H1 系列
|
|
||||||
* ```usb15``` 支持USB的STC15W4系列
|
|
||||||
|
|
||||||
doc / reverse-engineering子目录中的文本文件提供了BSL使用的反向工程协议的概述。
|
|
||||||
有关更多详细信息,请阅读源代码。
|
|
||||||
|
|
||||||
### 获取MCU信息
|
|
||||||
|
|
||||||
调用stcgal而不编写任何文件。它将转储有关MCU的信息,例如:('//'后面是翻译,实际使用过程中没有后面内容)
|
|
||||||
|
|
||||||
```
|
|
||||||
$ ./stcgal.py -P stc15
|
|
||||||
Waiting for MCU, please cycle power: done //等待MCU,请重启电源
|
|
||||||
Target model:
|
|
||||||
Name: IAP15F2K61S2
|
|
||||||
Magic: F449
|
|
||||||
Code flash: 61.0 KB
|
|
||||||
EEPROM flash: 0.0 KB
|
|
||||||
Target frequency: 10.046 MHz //单片机频率
|
|
||||||
Target BSL version: 7.1S //单片机BSL版本
|
|
||||||
Target wakeup frequency: 34.771 KHz //单片机唤醒频率
|
|
||||||
Target options:
|
|
||||||
reset_pin_enabled=False //复位引脚启用状态
|
|
||||||
clock_source=internal //时钟来源
|
|
||||||
clock_gain=high
|
|
||||||
watchdog_por_enabled=False //看门狗状态
|
|
||||||
watchdog_stop_idle=True
|
|
||||||
watchdog_prescale=256 //看门狗预分频系数
|
|
||||||
low_voltage_reset=True //低电压复位
|
|
||||||
low_voltage_threshold=3
|
|
||||||
eeprom_lvd_inhibit=True
|
|
||||||
eeprom_erase_enabled=False
|
|
||||||
bsl_pindetect_enabled=False
|
|
||||||
por_reset_delay=long
|
|
||||||
rstout_por_state=high
|
|
||||||
uart2_passthrough=False //串口2直通
|
|
||||||
uart2_pin_mode=normal //串口2引脚模式
|
|
||||||
Disconnected!
|
|
||||||
```
|
|
||||||
|
|
||||||
如果识别失败,阅读[FAQ(chinese)](FAQ.md)
|
|
||||||
|
|
||||||
### 编程Flash闪存
|
|
||||||
|
|
||||||
stcgal支持Intel十六进制编码文件以及二进制文件。
|
|
||||||
Intel HEX通过文件扩展名(. hex,. ihx 或者. ihex ) 自动测试。
|
|
||||||
|
|
||||||
像前面一样调用 stcgal,但提供代码映像的路径:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ ./stcgal.py -P stc15 hello.hex
|
|
||||||
Waiting for MCU, please cycle power: done
|
|
||||||
Target model:
|
|
||||||
Name: IAP15F2K61S2
|
|
||||||
Magic: F449
|
|
||||||
Code flash: 61.0 KB
|
|
||||||
EEPROM flash: 0.0 KB
|
|
||||||
Target frequency: 10.046 MHz //单片机频率
|
|
||||||
Target BSL version: 7.1S //单片机BSL版本
|
|
||||||
Target wakeup frequency: 34.771 KHz //单片机唤醒频率
|
|
||||||
Target options:
|
|
||||||
reset_pin_enabled=False //复位引脚启用状态
|
|
||||||
clock_source=internal //时钟来源
|
|
||||||
clock_gain=high
|
|
||||||
watchdog_por_enabled=False //看门狗状态
|
|
||||||
watchdog_stop_idle=True
|
|
||||||
watchdog_prescale=256 //看门狗预分频系数
|
|
||||||
low_voltage_reset=True //低电压复位
|
|
||||||
low_voltage_threshold=3
|
|
||||||
eeprom_lvd_inhibit=True
|
|
||||||
eeprom_erase_enabled=False
|
|
||||||
bsl_pindetect_enabled=False
|
|
||||||
por_reset_delay=long
|
|
||||||
rstout_por_state=high
|
|
||||||
uart2_passthrough=False //串口2直通
|
|
||||||
uart2_pin_mode=normal //串口2模式
|
|
||||||
Loading flash: 80 bytes (Intel HEX)
|
|
||||||
Trimming frequency: 10.046 MHz
|
|
||||||
Switching to 19200 baud: done
|
|
||||||
Erasing flash: done
|
|
||||||
Writing 256 bytes: .... done
|
|
||||||
Setting options: done
|
|
||||||
Target UID: 0D000021022632
|
|
||||||
Disconnected!
|
|
||||||
```
|
|
||||||
|
|
||||||
还可以编程存储器的EEPROM部分,。 将 Flash 图像路径添加到命令行后添加EEPROM图像路径。
|
|
||||||
|
|
||||||
stcgal默认使用 19200 bps的保守波特率。 可以通过标志```-b```选择更快的波特率来加快编程速度。
|
|
||||||
|
|
||||||
### 设备选项
|
|
||||||
|
|
||||||
stcgal转储了许多目标选项。 也可以修改这些。 在命令行上提供一个( 或者更多) `-o` 标志,后面跟一个 key-value 对来调整这些设置。
|
|
||||||
例如你可以将外部晶体启用为时钟源:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ ./stcgal.py -P stc15 -o clock_source=external hello.bin
|
|
||||||
```
|
|
||||||
|
|
||||||
请注意,设备选项只能在 Flash 内存被编程时设置 !
|
|
||||||
|
|
||||||
#### 命令行选项键
|
|
||||||
|
|
||||||
并非所有部件都支持所有选项。 描述中列出了支持每个选项的协议或者部分。
|
|
||||||
|
|
||||||
选项密钥 | 可能的值 | 协议/模型 | 描述
|
|
||||||
------------------------------|-------------------|---------------------|------------
|
|
||||||
```cpu_6t_enabled``` | true/false | 仅STC89 | 6T快速模式
|
|
||||||
```bsl_pindetect_enabled``` | true/false | 全部 | BSL仅在 p3。2/p3。3 或者 p1.0/p1.1 ( 取决于模型) 低时启用
|
|
||||||
```eeprom_erase_enabled``` | true/false | 全部 | 使用下一个编程周期擦除 EEPROM
|
|
||||||
```clock_gain``` | low/high | 所有带XTAL引脚 | 外部晶体的时钟增益
|
|
||||||
```ale_enabled``` | true/false | 仅STC89 | 如果 true,正常 GPIO,如果 false,则启用ALE引脚
|
|
||||||
```xram_enabled``` | true/false | 仅STC89 | 使用内部 XRAM ( 仅适用于 STC89 )
|
|
||||||
```watchdog_por_enabled``` | true/false | 全部 | 复位复位后的看门狗状态( POR )
|
|
||||||
```low_voltage_reset``` | low/high | STC12A/STC12 | 低电压复位级别( 低:~3.3V, 高: ~3.7V)
|
|
||||||
```low_voltage_reset``` | true/false | STC12 | 启用RESET2引脚低压检测
|
|
||||||
```low_voltage_reset``` | true/false | STC15A | 启用低电压复位( brownout )
|
|
||||||
```clock_source``` | internal/external | 带XTAL的STC12A+ | 使用内部( RC ) 或者外部( 晶体) 时钟
|
|
||||||
```watchdog_stop_idle``` | true/false | STC12A+ | 在空闲模式停止看门狗
|
|
||||||
```watchdog_prescale``` | 2,4,8,...,256 | STC12A+ | 看门狗定时器预分频器,必须是两个电源。
|
|
||||||
```reset_pin_enabled``` | true/false | STC12+ | 如果 true,正常 GPIO,如果 false,则复位引脚
|
|
||||||
```oscillator_stable_delay``` | 4096,...,32768 | 仅STC11F系列 | 时钟中的晶体稳定延迟。 一定是 two。
|
|
||||||
```por_reset_delay``` | short/long | STC12+ | 复位复位( POR ) 延迟
|
|
||||||
```low_voltage_threshold``` | 0...7 | STC15A+ | 低电压检测阈值。型号特定
|
|
||||||
```eeprom_lvd_inhibit``` | true/false | STC15A+ | 在低电压情况下忽略EEPROM写入
|
|
||||||
```rstout_por_state``` | low/high | STC15+ | 上电复位后的RSTOUT / RSTSV引脚状态
|
|
||||||
```uart1_remap``` | true/false | STC8 | 通过UART1到UART2引脚( 用于单导线UART模式)
|
|
||||||
```uart2_passthrough``` | true/false | STC15+ | 直通UART1至UART2引脚(用于单线UART模式)
|
|
||||||
```uart2_pin_mode``` | push-pull/normal | STC15+ | UART2 TX引脚的输出模式
|
|
||||||
```cpu_core_voltage``` | low/mid/high | STC15W+ | CPU核心电压( 低:~2.7V, mid: ~3.3V, 高:~3.6V)
|
|
||||||
```epwm_open_drain``` | true/false | STC8 | 上电复位后,对EPWM引脚使用漏极开路引脚模式
|
|
||||||
```program_eeprom_split``` | 512 - 65024 | STC8A8 w/ 64 KB | 选择代码闪存和EEPROM闪存之间的划分(以512字节块为单位)
|
|
||||||
|
|
||||||
### 频率微调
|
|
||||||
|
|
||||||
如果使用内部RC振荡器 (```clock_source=internal```),
|
|
||||||
stcgal可以执行修整过程以将其调整为给定值。 仅在STC15系列及更高版本中受支持。
|
|
||||||
调整值与设备选项一起存储。 使用 ```-t``` 标志请求对某个值进行修剪。
|
|
||||||
通常可以实现4000到30000 kHz之间的频率。 如果修剪失败,stcgal将中止。
|
|
||||||
|
|
||||||
### 自动功率循环
|
|
||||||
|
|
||||||
STC的微控制器需要上电复位才能调用引导加载程序,这可能很不方便。
|
|
||||||
stcgal可以使用串行接口的DTR控制信号来自动执行此操作。
|
|
||||||
当通过```-a```用自动复位功能时,DTR信号有效约500 ms。
|
|
||||||
这需要外部电路来实际切换电源。
|
|
||||||
在某些情况下,当微控制器仅消耗很少的功率时,就有可能直接从DTR信号提供功率。
|
|
||||||
|
|
||||||
作为DTR的替代方法,可以使用定制的shell命令或外部脚本(通过-r选项)来重置设备。
|
|
||||||
您应将命令与```-a```选项一起指定。不要忘了引号 !
|
|
||||||
|
|
||||||
例如:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ ./stcgal.py -P stc15 -a -r "echo 1 > /sys/class/gpio/gpio666/value"
|
|
||||||
```
|
|
||||||
或者
|
|
||||||
|
|
||||||
```
|
|
||||||
$ ./stcgal.py -P stc15 -a -r "./powercycle.sh"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 退出状态
|
|
||||||
|
|
||||||
如果在执行stcgal时没有发生错误,则退出状态为 0.。
|
|
||||||
任何错误( 如协议错误或者 I/O 错误) 都会导致退出状态 1。
|
|
||||||
如果用户按ctrl键中止 stcgal,则会导致退出状态为 2.
|
|
||||||
|
|
||||||
### USB支持
|
|
||||||
|
|
||||||
STC15W4系列具有一个基于USB的BSL,可以选择性的使用它。
|
|
||||||
stcgal中的USB支持是实验性的,将来可能会改变。
|
|
||||||
USB模式是通过使用“ usb15”协议启用的。
|
|
||||||
USB协议会忽略端口(```-p```)标志以及波特率选项。同时不支持RC频率调整。
|
|
@ -1 +1 @@
|
|||||||
__version__ = "1.10"
|
__version__ = "1.6"
|
||||||
|
@ -26,7 +26,6 @@ import stcgal
|
|||||||
import serial
|
import serial
|
||||||
from stcgal.utils import BaudType
|
from stcgal.utils import BaudType
|
||||||
from stcgal.protocols import Stc89Protocol
|
from stcgal.protocols import Stc89Protocol
|
||||||
from stcgal.protocols import Stc89AProtocol
|
|
||||||
from stcgal.protocols import Stc12AProtocol
|
from stcgal.protocols import Stc12AProtocol
|
||||||
from stcgal.protocols import Stc12BProtocol
|
from stcgal.protocols import Stc12BProtocol
|
||||||
from stcgal.protocols import Stc12Protocol
|
from stcgal.protocols import Stc12Protocol
|
||||||
@ -34,8 +33,6 @@ from stcgal.protocols import Stc15Protocol
|
|||||||
from stcgal.protocols import Stc15AProtocol
|
from stcgal.protocols import Stc15AProtocol
|
||||||
from stcgal.protocols import StcUsb15Protocol
|
from stcgal.protocols import StcUsb15Protocol
|
||||||
from stcgal.protocols import Stc8Protocol
|
from stcgal.protocols import Stc8Protocol
|
||||||
from stcgal.protocols import Stc8dProtocol
|
|
||||||
from stcgal.protocols import Stc8gProtocol
|
|
||||||
from stcgal.protocols import StcAutoProtocol
|
from stcgal.protocols import StcAutoProtocol
|
||||||
from stcgal.protocols import StcProtocolException
|
from stcgal.protocols import StcProtocolException
|
||||||
from stcgal.protocols import StcFramingException
|
from stcgal.protocols import StcFramingException
|
||||||
@ -46,15 +43,12 @@ class StcGal:
|
|||||||
|
|
||||||
def __init__(self, opts):
|
def __init__(self, opts):
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
self.hexFileType = 8
|
|
||||||
self.initialize_protocol(opts)
|
self.initialize_protocol(opts)
|
||||||
|
|
||||||
def initialize_protocol(self, opts):
|
def initialize_protocol(self, opts):
|
||||||
"""Initialize protocol backend"""
|
"""Initialize protocol backend"""
|
||||||
if opts.protocol == "stc89":
|
if opts.protocol == "stc89":
|
||||||
self.protocol = Stc89Protocol(opts.port, opts.handshake, opts.baud)
|
self.protocol = Stc89Protocol(opts.port, opts.handshake, opts.baud)
|
||||||
elif opts.protocol == "stc89a":
|
|
||||||
self.protocol = Stc89AProtocol(opts.port, opts.handshake, opts.baud)
|
|
||||||
elif opts.protocol == "stc12a":
|
elif opts.protocol == "stc12a":
|
||||||
self.protocol = Stc12AProtocol(opts.port, opts.handshake, opts.baud)
|
self.protocol = Stc12AProtocol(opts.port, opts.handshake, opts.baud)
|
||||||
elif opts.protocol == "stc12b":
|
elif opts.protocol == "stc12b":
|
||||||
@ -62,19 +56,14 @@ class StcGal:
|
|||||||
elif opts.protocol == "stc12":
|
elif opts.protocol == "stc12":
|
||||||
self.protocol = Stc12Protocol(opts.port, opts.handshake, opts.baud)
|
self.protocol = Stc12Protocol(opts.port, opts.handshake, opts.baud)
|
||||||
elif opts.protocol == "stc15a":
|
elif opts.protocol == "stc15a":
|
||||||
self.protocol = Stc15AProtocol(opts.port, opts.handshake, opts.baud, round(opts.trim * 1000))
|
self.protocol = Stc15AProtocol(opts.port, opts.handshake, opts.baud,
|
||||||
|
round(opts.trim * 1000))
|
||||||
elif opts.protocol == "stc15":
|
elif opts.protocol == "stc15":
|
||||||
self.protocol = Stc15Protocol(opts.port, opts.handshake, opts.baud, round(opts.trim * 1000))
|
self.protocol = Stc15Protocol(opts.port, opts.handshake, opts.baud,
|
||||||
|
round(opts.trim * 1000))
|
||||||
elif opts.protocol == "stc8":
|
elif opts.protocol == "stc8":
|
||||||
self.protocol = Stc8Protocol(opts.port, opts.handshake, opts.baud, round(opts.trim * 1000))
|
self.protocol = Stc8Protocol(opts.port, opts.handshake, opts.baud,
|
||||||
elif opts.protocol == "stc8d":
|
round(opts.trim * 1000))
|
||||||
self.protocol = Stc8dProtocol(opts.port, opts.handshake, opts.baud, round(opts.trim * 1000))
|
|
||||||
elif opts.protocol == "stc8g":
|
|
||||||
"""FIXME Ugly hack, but works until I fully implement the STC8G protocol"""
|
|
||||||
if opts.trim < 27360:
|
|
||||||
self.protocol = Stc8dProtocol(opts.port, opts.handshake, opts.baud, round(opts.trim * 1000))
|
|
||||||
else:
|
|
||||||
self.protocol = Stc8gProtocol(opts.port, opts.handshake, opts.baud, round(opts.trim * 1000))
|
|
||||||
elif opts.protocol == "usb15":
|
elif opts.protocol == "usb15":
|
||||||
self.protocol = StcUsb15Protocol()
|
self.protocol = StcUsb15Protocol()
|
||||||
else:
|
else:
|
||||||
@ -101,7 +90,6 @@ class StcGal:
|
|||||||
fname.endswith(".ihex")):
|
fname.endswith(".ihex")):
|
||||||
try:
|
try:
|
||||||
hexfile = IHex.read(fileobj)
|
hexfile = IHex.read(fileobj)
|
||||||
self.hexFileType = hexfile.get_mode()
|
|
||||||
binary = hexfile.extract_data()
|
binary = hexfile.extract_data()
|
||||||
print("%d bytes (Intel HEX)" %len(binary))
|
print("%d bytes (Intel HEX)" %len(binary))
|
||||||
return binary
|
return binary
|
||||||
@ -115,55 +103,45 @@ class StcGal:
|
|||||||
def program_mcu(self):
|
def program_mcu(self):
|
||||||
"""Execute the standard programming flow."""
|
"""Execute the standard programming flow."""
|
||||||
|
|
||||||
if self.opts.option: self.emit_options(self.opts.option)
|
code_size = self.protocol.model.code
|
||||||
|
ee_size = self.protocol.model.eeprom
|
||||||
if self.protocol.split_code and self.protocol.model.iap:
|
|
||||||
code_size = self.protocol.split_code
|
|
||||||
ee_size = self.protocol.split_eeprom
|
|
||||||
else:
|
|
||||||
code_size = self.protocol.model.code
|
|
||||||
ee_size = self.protocol.model.eeprom
|
|
||||||
|
|
||||||
print("Loading flash: ", end="")
|
print("Loading flash: ", end="")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
bindata = self.load_file_auto(self.opts.code_image)
|
bindata = self.load_file_auto(self.opts.code_image)
|
||||||
|
|
||||||
if self.protocol.model.mcs251 and self.hexFileType != 32:
|
|
||||||
print("Invalid input file. MCU is an MCS-251, input file MUST specify a linear", file=sys.stderr)
|
|
||||||
print("base address, i.e. contain a type 04 record. More information at:", file=sys.stderr)
|
|
||||||
print("https://en.wikipedia.org/wiki/Intel_HEX", file=sys.stderr)
|
|
||||||
else:
|
|
||||||
# warn if it overflows
|
|
||||||
if len(bindata) > code_size:
|
|
||||||
print("WARNING: code_image overflows into eeprom segment!", file=sys.stderr)
|
|
||||||
if len(bindata) > (code_size + ee_size):
|
|
||||||
print("WARNING: code_image truncated!", file=sys.stderr)
|
|
||||||
bindata = bindata[0:code_size + ee_size]
|
|
||||||
|
|
||||||
# add eeprom data if supplied
|
# warn if it overflows
|
||||||
if self.opts.eeprom_image:
|
if len(bindata) > code_size:
|
||||||
print("Loading EEPROM: ", end="")
|
print("WARNING: code_image overflows into eeprom segment!", file=sys.stderr)
|
||||||
sys.stdout.flush()
|
if len(bindata) > (code_size + ee_size):
|
||||||
eedata = self.load_file_auto(self.opts.eeprom_image)
|
print("WARNING: code_image truncated!", file=sys.stderr)
|
||||||
if len(eedata) > ee_size:
|
bindata = bindata[0:code_size + ee_size]
|
||||||
print("WARNING: eeprom_image truncated!", file=sys.stderr)
|
|
||||||
eedata = eedata[0:ee_size]
|
|
||||||
if len(bindata) < code_size:
|
|
||||||
bindata += bytes([0xff] * (code_size - len(bindata)))
|
|
||||||
elif len(bindata) > code_size:
|
|
||||||
print("WARNING: eeprom_image overlaps code_image!", file=sys.stderr)
|
|
||||||
bindata = bindata[0:code_size]
|
|
||||||
bindata += eedata
|
|
||||||
|
|
||||||
# pad to 512 byte boundary
|
# add eeprom data if supplied
|
||||||
if len(bindata) % 512:
|
if self.opts.eeprom_image:
|
||||||
bindata += b'\xff' * (512 - len(bindata) % 512)
|
print("Loading EEPROM: ", end="")
|
||||||
|
sys.stdout.flush()
|
||||||
|
eedata = self.load_file_auto(self.opts.eeprom_image)
|
||||||
|
if len(eedata) > ee_size:
|
||||||
|
print("WARNING: eeprom_image truncated!", file=sys.stderr)
|
||||||
|
eedata = eedata[0:ee_size]
|
||||||
|
if len(bindata) < code_size:
|
||||||
|
bindata += bytes([0xff] * (code_size - len(bindata)))
|
||||||
|
elif len(bindata) > code_size:
|
||||||
|
print("WARNING: eeprom_image overlaps code_image!", file=sys.stderr)
|
||||||
|
bindata = bindata[0:code_size]
|
||||||
|
bindata += eedata
|
||||||
|
|
||||||
self.protocol.handshake()
|
# pad to 512 byte boundary
|
||||||
self.protocol.erase_flash(len(bindata), code_size)
|
if len(bindata) % 512:
|
||||||
self.protocol.program_flash(bindata)
|
bindata += b'\xff' * (512 - len(bindata) % 512)
|
||||||
self.protocol.program_options()
|
|
||||||
|
if self.opts.option: self.emit_options(self.opts.option)
|
||||||
|
|
||||||
|
self.protocol.handshake()
|
||||||
|
self.protocol.erase_flash(len(bindata), code_size)
|
||||||
|
self.protocol.program_flash(bindata)
|
||||||
|
self.protocol.program_options()
|
||||||
self.protocol.disconnect()
|
self.protocol.disconnect()
|
||||||
|
|
||||||
def erase_mcu(self):
|
def erase_mcu(self):
|
||||||
@ -183,7 +161,7 @@ class StcGal:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.protocol.connect(autoreset=self.opts.autoreset, resetcmd=self.opts.resetcmd, resetpin=self.opts.resetpin)
|
self.protocol.connect(autoreset=self.opts.autoreset, resetcmd=self.opts.resetcmd)
|
||||||
if isinstance(self.protocol, StcAutoProtocol):
|
if isinstance(self.protocol, StcAutoProtocol):
|
||||||
if not self.protocol.protocol_name:
|
if not self.protocol.protocol_name:
|
||||||
raise StcProtocolException("cannot detect protocol")
|
raise StcProtocolException("cannot detect protocol")
|
||||||
@ -203,8 +181,7 @@ class StcGal:
|
|||||||
except (StcFramingException, StcProtocolException) as ex:
|
except (StcFramingException, StcProtocolException) as ex:
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
print("Protocol error: %s" % ex, file=sys.stderr)
|
print("Protocol error: %s" % ex, file=sys.stderr)
|
||||||
if not isinstance(self.protocol, StcAutoProtocol):
|
self.protocol.disconnect()
|
||||||
self.protocol.disconnect()
|
|
||||||
return 1
|
return 1
|
||||||
except serial.SerialException as ex:
|
except serial.SerialException as ex:
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
@ -262,13 +239,11 @@ def cli():
|
|||||||
parser.add_argument("eeprom_image", help="eeprom segment file to flash (BIN/HEX)", type=argparse.FileType("rb"), nargs='?')
|
parser.add_argument("eeprom_image", help="eeprom segment file to flash (BIN/HEX)", type=argparse.FileType("rb"), nargs='?')
|
||||||
exclusives.add_argument("-e", "--erase", help="only erase flash memory", action="store_true")
|
exclusives.add_argument("-e", "--erase", help="only erase flash memory", action="store_true")
|
||||||
parser.add_argument("-a", "--autoreset", help="cycle power automatically by asserting DTR", action="store_true")
|
parser.add_argument("-a", "--autoreset", help="cycle power automatically by asserting DTR", action="store_true")
|
||||||
parser.add_argument("-A", "--resetpin", help="pin to hold down when using --autoreset (default: DTR)",
|
|
||||||
choices=["dtr", "rts", "dtr_inverted", "rts_inverted"], default="dtr")
|
|
||||||
parser.add_argument("-r", "--resetcmd", help="shell command for board power-cycling (instead of DTR assertion)", action="store")
|
parser.add_argument("-r", "--resetcmd", help="shell command for board power-cycling (instead of DTR assertion)", action="store")
|
||||||
parser.add_argument("-P", "--protocol", help="protocol version (default: auto)",
|
parser.add_argument("-P", "--protocol", help="protocol version (default: auto)",
|
||||||
choices=["stc89", "stc89a", "stc12a", "stc12b", "stc12", "stc15a", "stc15", "stc8", "stc8d", "stc8g", "usb15", "auto"], default="auto")
|
choices=["stc89", "stc12a", "stc12b", "stc12", "stc15a", "stc15", "stc8", "usb15", "auto"], default="auto")
|
||||||
parser.add_argument("-p", "--port", help="serial port device", default="/dev/ttyUSB0")
|
parser.add_argument("-p", "--port", help="serial port device", default="/dev/ttyUSB0")
|
||||||
parser.add_argument("-b", "--baud", help="transfer baud rate (default: 115200)", type=BaudType(), default=115200)
|
parser.add_argument("-b", "--baud", help="transfer baud rate (default: 19200)", type=BaudType(), default=19200)
|
||||||
parser.add_argument("-l", "--handshake", help="handshake baud rate (default: 2400)", type=BaudType(), default=2400)
|
parser.add_argument("-l", "--handshake", help="handshake baud rate (default: 2400)", type=BaudType(), default=2400)
|
||||||
parser.add_argument("-o", "--option", help="set option (can be used multiple times, see documentation)", action="append")
|
parser.add_argument("-o", "--option", help="set option (can be used multiple times, see documentation)", action="append")
|
||||||
parser.add_argument("-t", "--trim", help="RC oscillator frequency in kHz (STC15+ series only)", type=float, default=0.0)
|
parser.add_argument("-t", "--trim", help="RC oscillator frequency in kHz (STC15+ series only)", type=float, default=0.0)
|
||||||
|
@ -14,6 +14,7 @@ class IHex:
|
|||||||
"""Read Intel HEX data from string or lines"""
|
"""Read Intel HEX data from string or lines"""
|
||||||
ihex = cls()
|
ihex = cls()
|
||||||
|
|
||||||
|
segbase = 0
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line:
|
if not line:
|
||||||
@ -21,14 +22,14 @@ class IHex:
|
|||||||
|
|
||||||
t, a, d = ihex.parse_line(line)
|
t, a, d = ihex.parse_line(line)
|
||||||
if t == 0x00:
|
if t == 0x00:
|
||||||
ihex.insert_data(a, d)
|
ihex.insert_data(segbase + a, d)
|
||||||
|
|
||||||
elif t == 0x01:
|
elif t == 0x01:
|
||||||
break # Should we check for garbage after this?
|
break # Should we check for garbage after this?
|
||||||
|
|
||||||
elif t == 0x02:
|
elif t == 0x02:
|
||||||
ihex.set_mode(16)
|
ihex.set_mode(16)
|
||||||
ihex.linearBaseAddress = struct.unpack(">H", d[0:2])[0] << 4
|
segbase = struct.unpack(">H", d[0:2])[0] << 4
|
||||||
|
|
||||||
elif t == 0x03:
|
elif t == 0x03:
|
||||||
ihex.set_mode(16)
|
ihex.set_mode(16)
|
||||||
@ -38,7 +39,7 @@ class IHex:
|
|||||||
|
|
||||||
elif t == 0x04:
|
elif t == 0x04:
|
||||||
ihex.set_mode(32)
|
ihex.set_mode(32)
|
||||||
ihex.linearBaseAddress = struct.unpack(">H", d[0:2])[0] << 16
|
segbase = struct.unpack(">H", d[0:2])[0] << 16
|
||||||
|
|
||||||
elif t == 0x05:
|
elif t == 0x05:
|
||||||
ihex.set_mode(32)
|
ihex.set_mode(32)
|
||||||
@ -62,7 +63,6 @@ class IHex:
|
|||||||
self.start = None
|
self.start = None
|
||||||
self.mode = 8
|
self.mode = 8
|
||||||
self.row_bytes = 16
|
self.row_bytes = 16
|
||||||
self.linearBaseAddress = 0
|
|
||||||
|
|
||||||
def set_row_bytes(self, row_bytes):
|
def set_row_bytes(self, row_bytes):
|
||||||
"""Set output hex file row width (bytes represented per row)."""
|
"""Set output hex file row width (bytes represented per row)."""
|
||||||
@ -105,12 +105,6 @@ class IHex:
|
|||||||
def set_mode(self, mode):
|
def set_mode(self, mode):
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
|
|
||||||
def get_mode(self):
|
|
||||||
return self.mode
|
|
||||||
|
|
||||||
def get_linearBaseAddress(self):
|
|
||||||
return self.linearBaseAddress
|
|
||||||
|
|
||||||
def get_area(self, addr):
|
def get_area(self, addr):
|
||||||
for start, data in self.areas.items():
|
for start, data in self.areas.items():
|
||||||
end = start + len(data)
|
end = start + len(data)
|
||||||
@ -199,7 +193,6 @@ class IHex:
|
|||||||
output += self.make_line(
|
output += self.make_line(
|
||||||
0x04, 0, struct.pack(">H", newsegbase))
|
0x04, 0, struct.pack(">H", newsegbase))
|
||||||
segbase = newsegbase
|
segbase = newsegbase
|
||||||
segbase = newsegbase
|
|
||||||
|
|
||||||
output += self.make_line(0x00, addr, chunk)
|
output += self.make_line(0x00, addr, chunk)
|
||||||
|
|
||||||
|
2172
stcgal/models.py
2172
stcgal/models.py
File diff suppressed because it is too large
Load Diff
@ -788,4 +788,4 @@ class Stc8Option(BaseOption):
|
|||||||
num_val = Utils.to_int(val)
|
num_val = Utils.to_int(val)
|
||||||
if num_val < 512 or num_val > 65024 or (num_val % 512) != 0:
|
if num_val < 512 or num_val > 65024 or (num_val % 512) != 0:
|
||||||
raise ValueError("must be between 512 and 65024 bytes and a multiple of 512 bytes")
|
raise ValueError("must be between 512 and 65024 bytes and a multiple of 512 bytes")
|
||||||
self.msr[4] = num_val // 256
|
self.msr[4] = num_val // 256
|
File diff suppressed because it is too large
Load Diff
@ -99,7 +99,7 @@ class TestProgramFuzzed(unittest.TestCase):
|
|||||||
def single_fuzz(self, yml, serial_mock, fuzzer, read_mock, err, out, sleep_mock, write_mock):
|
def single_fuzz(self, yml, serial_mock, fuzzer, read_mock, err, out, sleep_mock, write_mock):
|
||||||
"""Test a single programming cycle with fuzzing"""
|
"""Test a single programming cycle with fuzzing"""
|
||||||
with open(yml) as test_file:
|
with open(yml) as test_file:
|
||||||
test_data = yaml.load(test_file.read(), Loader=yaml.SafeLoader)
|
test_data = yaml.load(test_file.read())
|
||||||
for _ in range(1000):
|
for _ in range(1000):
|
||||||
with self.subTest():
|
with self.subTest():
|
||||||
opts = get_default_opts()
|
opts = get_default_opts()
|
||||||
|
Loading…
Reference in New Issue
Block a user