Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added several comments on the stlink software structure #851

Merged
merged 1 commit into from
Feb 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
398 changes: 398 additions & 0 deletions doc/developer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,398 @@

=== Target Identification ===

The following information is available about the target:
- chip id: 0xE0042000 or 0x40015800, primary information to derive flash and sram architection
- core id: Result from the STLINK_DEBUGREADCOREID call, additionally used for flash/sram architection
- cpu id: 0xE000ED00 (CMSIS System Control Block CPU ID), not used in stlink


=== Backend ===

The "backend" implements the interface to the adapter hardware.
There are two backends for two different adapters: "sg" (stlink v1?) and "usb" (stlink v2?).



Include stlink/backend.h
typedef struct _stlink_backend {
void (*close) (stlink_t * sl);
int (*exit_debug_mode) (stlink_t * sl);
int (*enter_swd_mode) (stlink_t * sl);
int (*enter_jtag_mode) (stlink_t * stl);
int (*exit_dfu_mode) (stlink_t * stl);
int (*core_id) (stlink_t * stl);
int (*reset) (stlink_t * stl);
int (*jtag_reset) (stlink_t * stl, int value);
int (*run) (stlink_t * stl);
int (*status) (stlink_t * stl);
int (*version) (stlink_t *sl);
int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data);
int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len);
int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data);
int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len);
int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len);
int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp);
int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp);
int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp);
int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp);
int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp);
int (*write_reg) (stlink_t *sl, uint32_t reg, int idx);
int (*step) (stlink_t * stl);
int (*current_mode) (stlink_t * stl);
int (*force_debug) (stlink_t *sl);
int32_t (*target_voltage) (stlink_t *sl);
int (*set_swdclk) (stlink_t * stl, uint16_t divisor);
} stlink_backend_t;

Descriptions below describe the actions of the usb.h backend:

void (*close) (stlink_t * sl);
int (*exit_debug_mode) (stlink_t * sl);
__stlink_usb_exit_debug_mode: Send STLINK_DEBUG_EXIT
returns -1 or 0

int (*enter_swd_mode) (stlink_t * sl);
_stlink_usb_enter_swd_mode: Send STLINK_DEBUG_ENTER+STLINK_DEBUG_ENTER_SWD
returns -1 or 0

int (*enter_jtag_mode) (stlink_t * stl);

int (*exit_dfu_mode) (stlink_t * stl);
_stlink_usb_exit_dfu_mode: Send STLINK_DFU_EXIT
returns -1 or 0

int (*core_id) (stlink_t * stl);
_stlink_usb_core_id: Assign the result from STLINK_DEBUG_READCOREID to stl->core_id
returns -1 or 0

int (*reset) (stlink_t * stl);
_stlink_usb_reset: Send STLINK_DEBUG_RESETSYS and reset via AIRCR
AIRCR is part of the CMSIS System Control Block (SCB), which is located in
the System Control Space at 0xE000ED0C
returns -1 or 0 ?

int (*jtag_reset) (stlink_t * stl, int value);
_stlink_usb_jtag_reset: Send STLINK_JTAG_DRIVE_NRST.
"value" is sent as argument for STLINK_JTAG_DRIVE_NRST and probably contains
the status of the NRST line (0: low, 1: high). Also the value 2 is used in the software.
returns -1 or 0

int (*run) (stlink_t * stl);
_stlink_usb_run: Send STLINK_DEBUG_RUNCORE
returns -1 or 0

int (*status) (stlink_t * stl);
_stlink_usb_status: Assign the result from STLINK_DEBUG_GETSTATUS to stl->q_len
returns -1 or 0

int (*version) (stlink_t *sl);
_stlink_usb_version: Read version with STLINK_GET_VERSION.
Result is stored in sl->q_buf (6 bytes????)
returns -1 or 0

int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data);
_stlink_usb_read_debug32: Send STLINK_JTAG_READDEBUG_32BIT
to read 32 bits from "addr". The result data is stored at "*data".
returns -1 or 0

int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len);
_stlink_usb_read_mem32: Use STLINK_DEBUG_READMEM_32BIT
to read "len" bytes from "addr"
Result is returned in sl->q_buf, sl->q_len returns the size of the data (should be
equal to "len"???).
returns -1 or 0

int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data);
_stlink_usb_write_debug32: Use STLINK_JTAG_WRITEDEBUG_32BIT
to store "data" at "addr"
returns -1 or 0

int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len);
_stlink_usb_write_mem32: Use STLINK_DEBUG_WRITEMEM_32BIT to
send data stored in sl->q_buf to the target at "addr".
"len" is the size data (???? not clear whether this are bytes )
returns -1 or 0

int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len);
_stlink_usb_write_mem8: Use STLINK_DEBUG_WRITEMEM_8BIT to
send data stored in sl->q_buf to the target at "addr".
"len" is the size in bytes (probably).
returns -1 or 0

int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp);
_stlink_usb_read_all_regs: Send STLINK_DEBUG_READALLREGS to read
all register values and store them into *regp;
returns -1 or 0

int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp);
_stlink_usb_read_reg: Send STLINK_DEBUG_READREG to read specific register "r_idx".
The result is then stored in *regp in the correct register.
Example if "r_idx" is 18, then the result is stored in regp->process_sp
returns -1 or 0

int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp);
_stlink_usb_read_all_unsupported_regs: Calls "_stlink_usb_read_unsupported_reg"
(see below) to read all registers.
returns -1 or 0

int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp);
_stlink_usb_read_unsupported_reg Use DCRSR and DCRDR to access some
of the internal registers (primask, basepri, faultmask, control, fpscr).
Also will fill regp->s (???) for some specific "r_idx" values.
WARNING: Some r_idx values may lead to a out of array bound problem in C.
returns -1 or 0

int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp);
_stlink_usb_write_unsupported_reg:
Updates one of the following registers:
primask (idx=0x1c), basepri (idx=0x1d), faultmask (idx=0x1e), control (idx=0x1f)
The new value is given as "value" as fn argument.
Corresponding values are refreshed in regp, however the old value for is kept in regp:
If basepri has to be updated (idx=0x1d), then all register values are fetched and
basepri is updated in the core, but not in *regp (BUG???).
returns -1 or 0

int (*write_reg) (stlink_t *sl, uint32_t reg, int idx);
_stlink_usb_write_reg: Use STLINK_DEBUG_WRITEREG to update register "idx"
with value "reg".
returns -1 or 0

int (*step) (stlink_t * stl);
_stlink_usb_step: Send STLINK_DEBUG_STEPCORE
returns -1 or 0

int (*current_mode) (stlink_t * stl);
_stlink_usb_current_mode: Send STLINK_GET_CURRENT_MODE and return
the current mode.
returns -1 or the value for the current mode.
Modes probably are:
STLINK_DEV_DFU_MODE 0x00
STLINK_DEV_MASS_MODE 0x01
STLINK_DEV_DEBUG_MODE 0x02

int (*force_debug) (stlink_t *sl);
_stlink_usb_force_debug: Sends STLINK_DEBUG_FORCEDEBUG. No other side effects
returns -1 or 0

int32_t (*target_voltage) (stlink_t *sl);
_stlink_usb_target_voltage: Send STLINK_GET_TARGET_VOLTAGE
returns -1 or the target voltage. (??? dimension is not clear...)

int (*set_swdclk) (stlink_t * stl, uint16_t divisor);
_stlink_usb_set_swdclk: Send STLINK_DEBUG_APIV2_SWD_SET_FREQ and "divisor" value
returns -1 or 0


=== Other Functions ===


Include: stlink.h


Prototype: void stlink_close(stlink_t *sl);
Include: inc/stlink.h
Definition: src/common.c
Description:
Calls the backend "close" procedure and frees 'sl'
Backend: "close"
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
Return: -

Include: inc/stlink.h
Prototype: int stlink_core_id(stlink_t *sl);
Definition: src/common.c
Description:
Calls the backend "core_id", calls stlink_print_data() on higher verbose levels.
Assigns the core id returned by STLINK_DEBUGREADCOREID to sl->core_id
Only some specific core ids are used: See include/stm32.h
Usage includes the selection of the correct flash algorithm.
Backend: "core_id"
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
Return: -1 for error. 0 for success.

Include: inc/stlink.h
Prototype: int stlink_reset(stlink_t *sl);
Definition: src/common.c
Description:
Just calls the backend "reset" procedure (reset via STLINK_DEBUG_RESETSYS
and reset via AIRCR register at 0xE000ED0C)
Backend: "reset"
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
Return: -1 for error. 0 for success.

Include: inc/stlink.h
Prototype: int stlink_jtag_reset(stlink_t *sl, int value);
Definition: src/common.c
Description:
Just calls the backend "jtag_reset" procedure
Backend: "jtag_reset"
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
value: 0: drive low, 1: drive high, 2: ????
Return: -1 for error. 0 for success.


Include: inc/stlink.h
Prototype: int stlink_run(stlink_t *sl);
Definition: src/common.c
Description:
Just calls the backend "run" procedure.
Backend: "run"
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
Return: -1 for error. 0 for success.

Include: inc/stlink.h
Prototype: int stlink_status(stlink_t *sl);
Definition: src/common.c
Description:
Calls the backend "status" procedure and the procedure "stlink_core_stat()" to
store the status in "sl->core_stat". Possible value for "sl->core_stat" are:
STLINK_CORE_RUNNING
STLINK_CORE_HALTED
STLINK_CORE_STAT_UNKNOWN
Backend: "status"
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
Return: -1 for error. 0 for success.


Include: inc/stlink.h
Prototype: int stlink_version(stlink_t *sl);
Definition: src/common.c
Description:
Calls the backend "version" procedure, parses the result and puts the result into sl->version
This version probably refers to the version of the adapter.
Backend: "version"
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
Return: -1 for error. 0 for success.


int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data);
int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len);
int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data);
int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len);
int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len);
int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp);
int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp);
int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp);
int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp);
int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp);
int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx);
int stlink_step(stlink_t *sl);
int stlink_current_mode(stlink_t *sl);
int stlink_force_debug(stlink_t *sl);
int stlink_target_voltage(stlink_t *sl);
int stlink_set_swdclk(stlink_t *sl, uint16_t divisor);

int stlink_erase_flash_mass(stlink_t* sl);
int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly);
int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin);
uint8_t stlink_get_erased_pattern(stlink_t *sl);
int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr);
int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr);
int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr);
int stlink_fwrite_option_bytes_32bit(stlink_t *sl,uint32_t val);
int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr);
int stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr);
int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length);

Include: inc/stlink.h
Prototype: int stlink_chip_id(stlink_t *sl, uint32_t *chip_id);
Definition: src/common.c
Description:
Tries to read out the chip id via memory read from the device.
Note: sl->chip_id is NOT updated by this procedure. Instead this happens in stlink_load_device_params():
Do not call this function, but instead call stlink_load_device_params()
Backend: -
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
chip_id: Pointer. Result is stored via this pointer.
Return: -1 for error. 0 for success.


Include: inc/stlink.h
Prototype: int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid);
Definition: src/common.c
Description:
Reads the CPU id from STLINK_REG_CM3_CPUID (0xE000ED00, first value of
the SCB, system control block) and splits this into
cpuid->implementer_id
cpuid->variant
cpuid->part
cpuid->revision
The result is not used in the tools, but only in the usb test program.
Backend: -
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
cpuid: Pointer. Result is stored via this pointer.
Return: -1 for error. 0 for success.




int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr);
uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr);
uint16_t read_uint16(const unsigned char *c, const int pt);
void stlink_core_stat(stlink_t *sl);


Include: inc/stlink.h
Prototype: void stlink_print_data(stlink_t *sl);
Definition: src/common.c
Description:
If debug logging is enabled: Print the HEX content of the q_buf array.
q_buf will contain the result of the last "backend" command.
Backend: -
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
Return: -


unsigned int is_bigendian(void);
uint32_t read_uint32(const unsigned char *c, const int pt);
void write_uint32(unsigned char* buf, uint32_t ui);
void write_uint16(unsigned char* buf, uint16_t ui);
bool stlink_is_core_halted(stlink_t *sl);
int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size);
int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size);
int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size);


Include: inc/stlink.h
Prototype: int stlink_load_device_params(stlink_t *sl);
Definition: src/common.c
Description:
This is one of the most important procedures. It will get all the device info
and store the results in the "sl" structure. Many other procedures will depend
on this information.
The identification is based on the stlink_chip_id() result and the flash_size register value
Backend: -
Arguments:
sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb()
Return: -1 for error. 0 for success.

int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte);
int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte);


Include "flash_loader.h"

int stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl);
int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size);
int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size);


Inlcude "sg.h"
stlink_t* stlink_v1_open(const int verbose, int reset);

Include "usb.h"

stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]);
size_t stlink_probe_usb(stlink_t **stdevs[]);
void stlink_probe_usb_free(stlink_t **stdevs[], size_t size);
Loading