From 73624826b68c2b52f314f9d4a3d120994009bfb2 Mon Sep 17 00:00:00 2001 From: Koen De Vleeschauwer Date: Sat, 6 Nov 2021 10:09:53 +0100 Subject: [PATCH 01/22] semihosting exit code --- src/target/cortexm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 5ce3a3c6..f7ad4e0c 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -1217,8 +1217,8 @@ static int cortexm_hostio_request(target *t) t->tc->interrupted = false; target_regs_read(t, arm_regs); - target_mem_read(t, params, arm_regs[1], sizeof(params)); uint32_t syscall = arm_regs[0]; + if (syscall != SYS_EXIT) target_mem_read(t, params, arm_regs[1], sizeof(params)); int32_t ret = 0; DEBUG_INFO("syscall 0"PRIx32"%"PRIx32" (%"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32")\n", @@ -1608,7 +1608,7 @@ static int cortexm_hostio_request(target *t) #endif case SYS_EXIT: /* _exit() */ - tc_printf(t, "_exit(0x%x)\n", params[0]); + tc_printf(t, "_exit(0x%x)\n", arm_regs[1]); target_halt_resume(t, 1); break; From 92d6056711c33f2dda18aa7118ce0dc3d21b7c65 Mon Sep 17 00:00:00 2001 From: fabalthazar Date: Thu, 21 Jan 2021 21:08:19 +0100 Subject: [PATCH 02/22] STM32G0 OTP area programming --- src/target/stm32g0.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/target/stm32g0.c b/src/target/stm32g0.c index d5637901..43c58c30 100644 --- a/src/target/stm32g0.c +++ b/src/target/stm32g0.c @@ -52,6 +52,9 @@ #define FLASH_MEMORY_SIZE 0x1FFF75E0 #define FLASH_PAGE_SIZE 0x800 #define FLASH_BANK2_START_PAGE_NB 256U +#define FLASH_OTP_START 0x1FFF7000 +#define FLASH_OTP_SIZE 0x400 +#define FLASH_OTP_BLOCKSIZE 0x8 #define FLASH_SIZE_MAX_G03_4 (64U * 1024U) // 64 kiB #define FLASH_SIZE_MAX_G05_6 (64U * 1024U) // 64 kiB #define FLASH_SIZE_MAX_G07_8 (128U * 1024U) // 128 kiB @@ -189,7 +192,7 @@ static void stm32g0_add_flash(target *t, uint32_t addr, size_t length, f->blocksize = blocksize; f->erase = stm32g0_flash_erase; f->write = stm32g0_flash_write; - f->buf_size = FLASH_PAGE_SIZE; + f->buf_size = blocksize; f->erased = 0xFF; target_add_flash(t, f); } @@ -249,6 +252,9 @@ bool stm32g0_probe(target *t) priv_storage->irreversible_enabled = false; t->target_storage = (void*)priv_storage; + /* OTP Flash area */ + stm32g0_add_flash(t, FLASH_OTP_START, FLASH_OTP_SIZE, FLASH_OTP_BLOCKSIZE); + return true; } @@ -311,6 +317,7 @@ static void stm32g0_flash_lock(target *t) /* * Flash erasure function. + * OTP case: this function clears any previous error and returns. */ static int stm32g0_flash_erase(struct target_flash *f, target_addr addr, size_t len) @@ -328,11 +335,6 @@ static int stm32g0_flash_erase(struct target_flash *f, target_addr addr, if (len == (size_t)0U) goto exit_cleanup; - nb_pages_to_erase = (uint16_t)((len - 1U) / f->blocksize) + 1U; - if (t->idcode == STM32G0B_C) // Dual-bank devices - bank1_end_page_nb = ((f->length / 2U) - 1U) / f->blocksize; - page_nb = (uint16_t)((addr - f->start) / f->blocksize); - /* Wait for Flash ready */ while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY_MASK) { if (target_check_error(t)) @@ -342,6 +344,14 @@ static int stm32g0_flash_erase(struct target_flash *f, target_addr addr, /* Clear any previous programming error */ target_mem_write32(t, FLASH_SR, target_mem_read32(t, FLASH_SR)); + if (addr >= (target_addr)FLASH_OTP_START) + goto exit_cleanup; + + nb_pages_to_erase = (uint16_t)((len - 1U) / f->blocksize) + 1U; + if (t->idcode == STM32G0B_C) // Dual-bank devices + bank1_end_page_nb = ((f->length / 2U) - 1U) / f->blocksize; + page_nb = (uint16_t)((addr - f->start) / f->blocksize); + stm32g0_flash_unlock(t); do { @@ -392,12 +402,20 @@ exit_cleanup: * The SR is supposed to be ready and free of any error. * After a successful programming, the EMPTY bit is cleared to allow rebooting * in Main Flash memory without power cycle. + * OTP area is programmed as the "program" area. It can be programmed 8-bytes + * by 8-bytes. */ static int stm32g0_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len) { target *t = f->t; int ret = 0; + struct stm32g0_priv_s *ps = (struct stm32g0_priv_s*)t->target_storage; + + if ((dest >= (target_addr)FLASH_OTP_START) && !ps->irreversible_enabled) { + tc_printf(t, "Irreversible operations disabled\n"); + goto exit_error; + } stm32g0_flash_unlock(t); From 71b67beb98256c4a9ff25220357dc9968dda18e3 Mon Sep 17 00:00:00 2001 From: fabalthazar Date: Sun, 14 Nov 2021 16:25:15 +0100 Subject: [PATCH 03/22] Fix: assert flashing succeeded or failed (hosted) once the last buffer has been written --- src/platforms/pc/cl_utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index 88e16a0c..4271d990 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -510,6 +510,8 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) unsigned int flashed = target_flash_write(t, opt->opt_flash_start, map.data, map.size); /* Buffered write cares for padding*/ + if (!flashed) + flashed = target_flash_done(t); if (flashed) { DEBUG_WARN("Flashing failed!\n"); res = -1; @@ -518,7 +520,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) DEBUG_INFO("Success!\n"); } } - target_flash_done(t); uint32_t end_time = platform_time_ms(); DEBUG_WARN("Flash Write succeeded for %d bytes, %8.3f kiB/s\n", (int)map.size, (((map.size * 1.0)/(end_time - start_time)))); From b4ac52d1f55b74c10af6906e03182836f9fddc76 Mon Sep 17 00:00:00 2001 From: fabalthazar Date: Sun, 14 Nov 2021 18:37:21 +0100 Subject: [PATCH 04/22] Hosted monitor command allowed as preliminary command --- src/platforms/pc/cl_utils.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index 4271d990..7a438da1 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -290,7 +290,6 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) opt->opt_targetid = strtol(optarg, NULL, 0); break; case 'M': - opt->opt_mode = BMP_MODE_MONITOR; if (optarg) opt->opt_monitor = optarg; break; @@ -321,7 +320,11 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) if (opt->opt_mode == BMP_MODE_DEBUG) opt->opt_mode = BMP_MODE_FLASH_WRITE; opt->opt_flash_file = argv[optind]; + } else if ((opt->opt_mode == BMP_MODE_DEBUG) && + (opt->opt_monitor)) { + opt->opt_mode = BMP_MODE_MONITOR; // To avoid DEBUG mode } + /* Checks */ if ((opt->opt_flash_file) && ((opt->opt_mode == BMP_MODE_TEST ) || (opt->opt_mode == BMP_MODE_SWJ_TEST) || @@ -448,10 +451,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) default: DEBUG_WARN("No test for this core type yet\n"); } - } else if (opt->opt_mode == BMP_MODE_MONITOR) { - res = command_process(t, opt->opt_monitor); - if (res) - DEBUG_WARN("Command \"%s\" failed\n", opt->opt_monitor); } if ((opt->opt_mode == BMP_MODE_TEST) || (opt->opt_mode == BMP_MODE_SWJ_TEST)) @@ -480,9 +479,14 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) if (opt->opt_flash_size < map.size) /* restrict to size given on command line */ map.size = opt->opt_flash_size; + if (opt->opt_monitor) { + res = command_process(t, opt->opt_monitor); + if (res) + DEBUG_WARN("Command \"%s\" failed\n", opt->opt_monitor); + } if (opt->opt_mode == BMP_MODE_RESET) { target_reset(t); - } else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) { + } else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) { DEBUG_INFO("Erase %zu bytes at 0x%08" PRIx32 "\n", opt->opt_flash_size, opt->opt_flash_start); unsigned int erased = target_flash_erase(t, opt->opt_flash_start, From 5cb501049ab474a2c726f4a20bafe0eddaf459bb Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 18 Nov 2021 19:57:36 +0100 Subject: [PATCH 05/22] adiv5_swdp/scan: Handle parity errors, seen with NRF52 with SYSTEMOFF #381/#949 --- src/target/adiv5_swdp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 7565d241..04723ae1 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -252,8 +252,10 @@ uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, raise_exception(EXCEPTION_ERROR, "SWDP invalid ACK"); if(RnW) { - if(dp->seq_in_parity(&response, 32)) /* Give up on parity error */ + if (dp->seq_in_parity(&response, 32)) { /* Give up on parity error */ + dp->fault = 1; raise_exception(EXCEPTION_ERROR, "SWDP Parity error"); + } } else { dp->seq_out_parity(value, 32); /* ARM Debug Interface Architecture Specification ADIv5.0 to ADIv5.2 From 73b4612ec71b455ac71f1686f07160e155a840ad Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 20 Nov 2021 22:29:33 +0100 Subject: [PATCH 06/22] adiv5_swdp: Initialize a volatile variable GCC did not warn about possibly missing initialization and so for gdb target was not recognized. --- src/target/adiv5_swdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 04723ae1..d29d02ac 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -91,7 +91,7 @@ int adiv5_swdp_scan(uint32_t targetid) * 20 bits start of reset another reset sequence*/ initial_dp->seq_out(0x1a0, 12); uint32_t idcode = 0; - volatile uint32_t target_id; + volatile uint32_t target_id = 0; bool scan_multidrop = true; if (!targetid || !initial_dp->dp_low_write) { /* No targetID given on the command line or probe can not From d4cd81fa363270633c04942869a408f2a5167328 Mon Sep 17 00:00:00 2001 From: Koen De Vleeschauwer Date: Sun, 21 Nov 2021 11:48:56 +0100 Subject: [PATCH 07/22] start_time undeclared if ENABLE_DEBUG=1 --- src/target/adiv5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 403ecc99..4cc528fd 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -398,7 +398,7 @@ static uint32_t cortexm_initial_halt(ADIv5_AP_t *ap) */ static bool cortexm_prepare(ADIv5_AP_t *ap) { -#if PC_HOSTED == 1 +#if ((PC_HOSTED == 1) || (ENABLE_DEBUG == 1)) uint32_t start_time = platform_time_ms(); #endif uint32_t dhcsr = cortexm_initial_halt(ap); From bb4151377f447ae1a78294936e82b3d4d7a3bd03 Mon Sep 17 00:00:00 2001 From: Koen De Vleeschauwer Date: Mon, 22 Nov 2021 19:45:16 +0100 Subject: [PATCH 08/22] =?UTF-8?q?type=20of=20=E2=80=98assert=E2=80=99=20de?= =?UTF-8?q?faults=20to=20=E2=80=98int=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/platforms/hosted/cmsis_dap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/hosted/cmsis_dap.h b/src/platforms/hosted/cmsis_dap.h index ed5c6c78..cd834d8e 100644 --- a/src/platforms/hosted/cmsis_dap.h +++ b/src/platforms/hosted/cmsis_dap.h @@ -48,7 +48,7 @@ int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc) {return -1;} int dap_swdptap_init(ADIv5_DP_t *dp) {return -1;} int dap_jtag_dp_init(ADIv5_DP_t *dp) {return -1;} void dap_swd_configure(uint8_t cfg) {}; -void dap_srst_set_val(assert) {}; +void dap_srst_set_val(bool assert) {}; # pragma GCC diagnostic pop #endif From 98e3858f7cfc973cf26e169e685a3b8b76ed81af Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 23 Nov 2021 20:29:27 +0100 Subject: [PATCH 09/22] bmp_libusb: Exclude Wireless class too. --- src/platforms/hosted/bmp_libusb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platforms/hosted/bmp_libusb.c b/src/platforms/hosted/bmp_libusb.c index d2949320..21ed9542 100644 --- a/src/platforms/hosted/bmp_libusb.c +++ b/src/platforms/hosted/bmp_libusb.c @@ -169,7 +169,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info) continue; } /* Exclude hubs from testing. Probably more classes could be excluded here!*/ - if (desc.bDeviceClass == LIBUSB_CLASS_HUB) { + switch (desc.bDeviceClass) { + case LIBUSB_CLASS_HUB: + case LIBUSB_CLASS_WIRELESS: continue; } libusb_device_handle *handle; From 3f28e728e95bd89b630779abd5ae38e74fb102c8 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 12 Dec 2021 14:33:05 +0100 Subject: [PATCH 10/22] cdcacm: Lower usage of magic numbers. --- src/platforms/common/cdcacm.c | 102 ++++++++++++++++++++-------------- src/platforms/common/cdcacm.h | 1 + 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/platforms/common/cdcacm.c b/src/platforms/common/cdcacm.c index fc85b16d..399dd3d6 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -24,6 +24,18 @@ * field firmware upgrade. * * The device's unique id is used as the USB serial number string. + * + * Endpoint Usage + * + * 0 Control Endpoint + * IN 1 GDB CDC DATA + * OUT 1 GDB CDC DATA + * IN 2 GDB CDC CTR + * IN 3 UART CDC DATA + * OUT 3 UART CDC DATA + * OUT 4 UART CDC CTRL + * In 5 Trace Capture + * */ #include "general.h" @@ -42,7 +54,15 @@ #include #include -#define DFU_IF_NO 4 +#define GDB_IF_NO 0 +#define UART_IF_NO 2 +#define DFU_IF_NO 4 +#if defined(PLATFORM_HAS_TRACESWO) +# define TRACE_IF_NO 5 +# define TOTAL_INTERFACES 6 +#else +# define TOTAL_INTERFACES 5 +#endif usbd_device * usbdev; @@ -78,7 +98,7 @@ static const struct usb_device_descriptor dev_desc = { static const struct usb_endpoint_descriptor gdb_comm_endp[] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x82, + .bEndpointAddress = (CDCACM_GDB_ENDPOINT + 1) | USB_REQ_TYPE_IN, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 16, .bInterval = 255, @@ -87,14 +107,14 @@ static const struct usb_endpoint_descriptor gdb_comm_endp[] = {{ static const struct usb_endpoint_descriptor gdb_data_endp[] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x01, + .bEndpointAddress = CDCACM_GDB_ENDPOINT, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = CDCACM_PACKET_SIZE, .bInterval = 1, }, { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x81, + .bEndpointAddress = CDCACM_GDB_ENDPOINT | USB_REQ_TYPE_IN, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = CDCACM_PACKET_SIZE, .bInterval = 1, @@ -118,7 +138,7 @@ static const struct { .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, .bmCapabilities = 0, - .bDataInterface = 1, + .bDataInterface = GDB_IF_NO + 1, }, .acm = { .bFunctionLength = sizeof(struct usb_cdc_acm_descriptor), @@ -130,8 +150,8 @@ static const struct { .bFunctionLength = sizeof(struct usb_cdc_union_descriptor), .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_UNION, - .bControlInterface = 0, - .bSubordinateInterface0 = 1, + .bControlInterface = GDB_IF_NO, + .bSubordinateInterface0 = GDB_IF_NO + 1, } }; @@ -155,7 +175,7 @@ static const struct usb_interface_descriptor gdb_comm_iface[] = {{ static const struct usb_interface_descriptor gdb_data_iface[] = {{ .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 1, + .bInterfaceNumber = GDB_IF_NO + 1, .bAlternateSetting = 0, .bNumEndpoints = 2, .bInterfaceClass = USB_CLASS_DATA, @@ -169,7 +189,7 @@ static const struct usb_interface_descriptor gdb_data_iface[] = {{ static const struct usb_iface_assoc_descriptor gdb_assoc = { .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, - .bFirstInterface = 0, + .bFirstInterface = GDB_IF_NO, .bInterfaceCount = 2, .bFunctionClass = USB_CLASS_CDC, .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, @@ -181,7 +201,7 @@ static const struct usb_iface_assoc_descriptor gdb_assoc = { static const struct usb_endpoint_descriptor uart_comm_endp[] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x84, + .bEndpointAddress = (CDCACM_UART_ENDPOINT + 1) | USB_REQ_TYPE_IN, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 16, .bInterval = 255, @@ -190,14 +210,14 @@ static const struct usb_endpoint_descriptor uart_comm_endp[] = {{ static const struct usb_endpoint_descriptor uart_data_endp[] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x03, + .bEndpointAddress = CDCACM_UART_ENDPOINT, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = CDCACM_PACKET_SIZE / 2, .bInterval = 1, }, { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x83, + .bEndpointAddress = CDCACM_UART_ENDPOINT | USB_REQ_TYPE_IN, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = CDCACM_PACKET_SIZE, .bInterval = 1, @@ -221,7 +241,7 @@ static const struct { .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, .bmCapabilities = 0, - .bDataInterface = 3, + .bDataInterface = UART_IF_NO + 1, }, .acm = { .bFunctionLength = sizeof(struct usb_cdc_acm_descriptor), @@ -233,15 +253,15 @@ static const struct { .bFunctionLength = sizeof(struct usb_cdc_union_descriptor), .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_UNION, - .bControlInterface = 2, - .bSubordinateInterface0 = 3, + .bControlInterface = UART_IF_NO, + .bSubordinateInterface0 = UART_IF_NO + 1, } }; static const struct usb_interface_descriptor uart_comm_iface[] = {{ .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 2, + .bInterfaceNumber = UART_IF_NO, .bAlternateSetting = 0, .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_CDC, @@ -258,7 +278,7 @@ static const struct usb_interface_descriptor uart_comm_iface[] = {{ static const struct usb_interface_descriptor uart_data_iface[] = {{ .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 3, + .bInterfaceNumber = UART_IF_NO + 1, .bAlternateSetting = 0, .bNumEndpoints = 2, .bInterfaceClass = USB_CLASS_DATA, @@ -272,7 +292,7 @@ static const struct usb_interface_descriptor uart_data_iface[] = {{ static const struct usb_iface_assoc_descriptor uart_assoc = { .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, - .bFirstInterface = 2, + .bFirstInterface = UART_IF_NO, .bInterfaceCount = 2, .bFunctionClass = USB_CLASS_CDC, .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, @@ -307,7 +327,7 @@ const struct usb_interface_descriptor dfu_iface = { static const struct usb_iface_assoc_descriptor dfu_assoc = { .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, - .bFirstInterface = 4, + .bFirstInterface = DFU_IF_NO, .bInterfaceCount = 1, .bFunctionClass = 0xFE, .bFunctionSubClass = 1, @@ -319,7 +339,7 @@ static const struct usb_iface_assoc_descriptor dfu_assoc = { static const struct usb_endpoint_descriptor trace_endp[] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x85, + .bEndpointAddress = TRACE_ENDPOINT | USB_REQ_TYPE_IN, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = 64, .bInterval = 0, @@ -328,7 +348,7 @@ static const struct usb_endpoint_descriptor trace_endp[] = {{ const struct usb_interface_descriptor trace_iface = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 5, + .bInterfaceNumber = TRACE_IF_NO, .bAlternateSetting = 0, .bNumEndpoints = 1, .bInterfaceClass = 0xFF, @@ -342,7 +362,7 @@ const struct usb_interface_descriptor trace_iface = { static const struct usb_iface_assoc_descriptor trace_assoc = { .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, - .bFirstInterface = 5, + .bFirstInterface = TRACE_IF_NO, .bInterfaceCount = 1, .bFunctionClass = 0xFF, .bFunctionSubClass = 0xFF, @@ -381,11 +401,7 @@ static const struct usb_config_descriptor config = { .bLength = USB_DT_CONFIGURATION_SIZE, .bDescriptorType = USB_DT_CONFIGURATION, .wTotalLength = 0, -#if defined(PLATFORM_HAS_TRACESWO) - .bNumInterfaces = 6, -#else - .bNumInterfaces = 5, -#endif + .bNumInterfaces = TOTAL_INTERFACES, .bConfigurationValue = 1, .iConfiguration = 0, .bmAttributes = 0x80, @@ -435,7 +451,7 @@ static enum usbd_request_return_codes cdcacm_control_request(usbd_device *dev, case USB_CDC_REQ_SET_CONTROL_LINE_STATE: cdcacm_set_modem_state(dev, req->wIndex, true, true); /* Ignore if not for GDB interface */ - if(req->wIndex != 0) + if(req->wIndex != GDB_IF_NO) return USBD_REQ_HANDLED; cdcacm_gdb_dtr = req->wValue & 1; @@ -446,10 +462,10 @@ static enum usbd_request_return_codes cdcacm_control_request(usbd_device *dev, return USBD_REQ_NOTSUPP; switch(req->wIndex) { - case 2: + case UART_IF_NO: usbuart_set_line_coding((struct usb_cdc_line_coding*)*buf); return USBD_REQ_HANDLED; - case 0: + case GDB_IF_NO: return USBD_REQ_HANDLED; /* Ignore on GDB Port */ default: return USBD_REQ_NOTSUPP; @@ -499,6 +515,7 @@ static void cdcacm_set_modem_state(usbd_device *dev, int iface, bool dsr, bool d notif->wLength = 2; buf[8] = (dsr ? 2 : 0) | (dcd ? 1 : 0); buf[9] = 0; + /* FIXME: Remove magic numbers */ usbd_ep_write_packet(dev, 0x82 + iface, buf, 10); } @@ -508,26 +525,29 @@ static void cdcacm_set_config(usbd_device *dev, uint16_t wValue) /* GDB interface */ #if defined(STM32F4) || defined(LM4F) - usbd_ep_setup(dev, 0x01, USB_ENDPOINT_ATTR_BULK, + usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, gdb_usb_out_cb); #else - usbd_ep_setup(dev, 0x01, USB_ENDPOINT_ATTR_BULK, + usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL); #endif - usbd_ep_setup(dev, 0x81, USB_ENDPOINT_ATTR_BULK, - CDCACM_PACKET_SIZE, NULL); - usbd_ep_setup(dev, 0x82, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT | USB_REQ_TYPE_IN, + USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL); + usbd_ep_setup(dev, (CDCACM_GDB_ENDPOINT + 1) | USB_REQ_TYPE_IN, + USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); /* Serial interface */ - usbd_ep_setup(dev, 0x03, USB_ENDPOINT_ATTR_BULK, + usbd_ep_setup(dev, CDCACM_UART_ENDPOINT, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE / 2, usbuart_usb_out_cb); - usbd_ep_setup(dev, 0x83, USB_ENDPOINT_ATTR_BULK, + usbd_ep_setup(dev, CDCACM_UART_ENDPOINT | USB_REQ_TYPE_IN, + USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, usbuart_usb_in_cb); - usbd_ep_setup(dev, 0x84, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(dev, (CDCACM_UART_ENDPOINT + 1) | USB_REQ_TYPE_IN, + USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); #if defined(PLATFORM_HAS_TRACESWO) /* Trace interface */ - usbd_ep_setup(dev, 0x85, USB_ENDPOINT_ATTR_BULK, + usbd_ep_setup(dev, TRACE_ENDPOINT | USB_REQ_TYPE_IN, USB_ENDPOINT_ATTR_BULK, 64, trace_buf_drain); #endif @@ -539,8 +559,8 @@ static void cdcacm_set_config(usbd_device *dev, uint16_t wValue) /* Notify the host that DCD is asserted. * Allows the use of /dev/tty* devices on *BSD/MacOS */ - cdcacm_set_modem_state(dev, 0, true, true); - cdcacm_set_modem_state(dev, 2, true, true); + cdcacm_set_modem_state(dev, GDB_IF_NO, true, true); + cdcacm_set_modem_state(dev, UART_IF_NO, true, true); } /* We need a special large control buffer for this device: */ diff --git a/src/platforms/common/cdcacm.h b/src/platforms/common/cdcacm.h index f64399d2..7cdfe238 100644 --- a/src/platforms/common/cdcacm.h +++ b/src/platforms/common/cdcacm.h @@ -34,6 +34,7 @@ #define CDCACM_GDB_ENDPOINT 1 #define CDCACM_UART_ENDPOINT 3 +#define TRACE_ENDPOINT 5 extern usbd_device *usbdev; From 728e9551935173993c63ee0c61dee75c35b5e1d0 Mon Sep 17 00:00:00 2001 From: Piotr Esden-Tempski Date: Sun, 19 Dec 2021 12:35:35 -0800 Subject: [PATCH 11/22] scripts: Updated bootprog to run on python3 --- scripts/bootprog.py | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/scripts/bootprog.py b/scripts/bootprog.py index ab783259..5baf82b0 100755 --- a/scripts/bootprog.py +++ b/scripts/bootprog.py @@ -23,12 +23,12 @@ from time import sleep class stm32_boot: def __init__(self, port, baud=115200): - self.serial = serial.Serial(port, baud, 8, 'E', 1, + self.serial = serial.Serial(port, baud, 8, 'E', 1, timeout=1) # Turn on target device in SystemMemory boot mode self.serial.setDTR(1) - sleep(0.1); + sleep(0.1) self._sync() @@ -98,7 +98,6 @@ class stm32_boot: # Send data self._send(chr(len(data)-1) + data) self._checkack() - def write_protect(self, sectors): # Send WP cmd @@ -134,11 +133,11 @@ if __name__ == "__main__": from getopt import getopt if platform == "linux2": - print "\x1b\x5b\x48\x1b\x5b\x32\x4a" # clear terminal screen - print "STM32 SystemMemory Production Programmer -- version 1.1" - print "Copyright (C) 2011 Black Sphere Technologies" - print "License GPLv3+: GNU GPL version 3 or later " - print + print("\x1b\x5b\x48\x1b\x5b\x32\x4a") # clear terminal screen + print("STM32 SystemMemory Production Programmer -- version 1.1") + print("Copyright (C) 2011 Black Sphere Technologies") + print("License GPLv3+: GNU GPL version 3 or later ") + print() dev = "COM1" if platform == "win32" else "/dev/ttyUSB0" baud = 115200 @@ -152,38 +151,38 @@ if __name__ == "__main__": progfile = args[0] except: - print "Usage %s [-d ] [-b ] [-a
] " % argv[0] - print "\t-d : Use target on interface (default: %s)" % dev - print "\t-b : Set device baudrate (default: %d)" % baud - print "\t-a : Set programming address (default: 0x%X)" % addr - print + print("Usage %s [-d ] [-b ] [-a
] " % argv[0]) + print("\t-d : Use target on interface (default: %s)" % dev) + print("\t-b : Set device baudrate (default: %d)" % baud) + print("\t-a : Set programming address (default: 0x%X)" % addr) + print() exit(-1) prog = open(progfile, "rb").read() boot = stm32_boot(dev, baud) cmds = boot.get() - print "Target bootloader version: %d.%d\n" % (ord(cmds[0]) >> 4, ord(cmds[0]) % 0xf) + print("Target bootloader version: %d.%d\n" % (ord(cmds[0]) >> 4, ord(cmds[0]) % 0xf)) - print "Removing device protection..." + print("Removing device protection...") boot.read_unprotect() boot.write_unprotect() - print "Erasing target device..." + print("Erasing target device...") boot.eraseall() addr = 0x8000000 while prog: - print ("Programming address 0x%08X..0x%08X...\r" % (addr, addr + min(len(prog), 255))), - stdout.flush(); + print("Programming address 0x%08X..0x%08X...\r" % (addr, addr + min(len(prog), 255)), end=' ') + stdout.flush() boot.write(addr, prog[:256]) addr += 256 prog = prog[256:] print - print "Enabling device protection..." + print("Enabling device protection...") boot.write_protect(range(0,2)) #boot.read_protect() - print "All operations completed." + print("All operations completed.") print From fcb2a609fcbed64161842dfac49fd3a9c966e9f7 Mon Sep 17 00:00:00 2001 From: Piotr Esden-Tempski Date: Sun, 19 Dec 2021 12:36:04 -0800 Subject: [PATCH 12/22] scripts: Updated nrf51 id script for py3 and to parse newer oocd header. --- scripts/get_openocd_nrf51_ids.py | 62 +++++++++++++++----------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/scripts/get_openocd_nrf51_ids.py b/scripts/get_openocd_nrf51_ids.py index 5c90a296..33bdd60e 100755 --- a/scripts/get_openocd_nrf51_ids.py +++ b/scripts/get_openocd_nrf51_ids.py @@ -5,56 +5,52 @@ pasting into blackmagic's nrf51.c """ -import subprocess,re +import subprocess +import re +import io -cmd = 'git archive --remote=git://git.code.sf.net/p/openocd/code HEAD src/flash/nor/nrf51.c | tar -xO' +cmd = 'git archive --remote=git://git.code.sf.net/p/openocd/code HEAD src/flash/nor/nrf5.c | tar -xO' class Spec(): def __repr__(self): return "0x%04X: /* %s %s %s */"%(self.hwid,self.comment, self.variant,self.build_code) -fd = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE).stdout +proc = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE) -specdict={} -specs=[] -spec=Spec() -for line in fd.read().split('\n'): - m=re.search('/\*(.*)\*/',line) +specdict = {} +specs = [] +spec = Spec() +for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"): + m = re.search('/\*(.*)\*/',line) if m: lastcomment=m.group(1) - m=re.search('.hwid.*=\s*(0x[0-9A-F]*),',line) + m = re.search('NRF51_DEVICE_DEF\((0x[0-9A-F]*),\s*"(.*)",\s*"(.*)",\s*"(.*)",\s*([0-9]*)\s*\),', line) if m: - spec.hwid=int(m.group(1),base=0) - m=re.search('.variant.*=\s*"(.*)",',line) - if m: - spec.variant=m.group(1) - m=re.search('.build_code.*=\s*"(.*)",',line) - if m: - spec.build_code=m.group(1) - m=re.search('.flash_size_kb.*=\s*([0-9]*),',line) - if m: - spec.flash_size_kb=int(m.group(1),base=0) - ram,flash = {'AA':(16,256), - 'AB':(16,128), - 'AC':(32,256)}[spec.variant[-2:]] - assert flash==spec.flash_size_kb + spec.hwid = int(m.group(1), base=0) + spec.variant = m.group(3) + spec.build_code = m.group(4) + spec.flash_size_kb = int(m.group(5), base=0) + ram, flash = {'AA':(16,256), + 'AB':(16,128), + 'AC':(32,256)}[spec.variant[-2:]] + assert flash == spec.flash_size_kb spec.ram_size_kb = ram - nicecomment =lastcomment.strip().replace('IC ','').replace('Devices ','').replace('.','') - spec.comment=nicecomment + nicecomment = lastcomment.strip().replace('IC ','').replace('Devices ','').replace('.','') + spec.comment = nicecomment specdict.setdefault((ram,flash),[]).append(spec) specs.append(spec) spec=Spec() -for (ram,flash),specs in specdict.iteritems(): +for (ram,flash),specs in specdict.items(): specs.sort(key=lambda x:x.hwid) for spec in specs: - print "\tcase",spec - print '\t\tt->driver = "Nordic nRF51";' - print '\t\ttarget_add_ram(t, 0x20000000, 0x%X);'%(1024*ram) - print '\t\tnrf51_add_flash(t, 0x00000000, 0x%X, NRF51_PAGE_SIZE);'%(1024*flash) - print '\t\tnrf51_add_flash(t, NRF51_UICR, 0x100, 0x100);' - print '\t\ttarget_add_commands(t, nrf51_cmd_list, "nRF51");' - print '\t\treturn true;' + print("\tcase",spec) + print('\t\tt->driver = "Nordic nRF51";') + print('\t\ttarget_add_ram(t, 0x20000000, 0x%X);'%(1024*ram)) + print('\t\tnrf51_add_flash(t, 0x00000000, 0x%X, NRF51_PAGE_SIZE);'%(1024*flash)) + print('\t\tnrf51_add_flash(t, NRF51_UICR, 0x100, 0x100);') + print('\t\ttarget_add_commands(t, nrf51_cmd_list, "nRF51");') + print('\t\treturn true;') From f43101fd9fc4a9aa67e24a9b54f1780b39c7724b Mon Sep 17 00:00:00 2001 From: Mark Rages Date: Mon, 11 May 2020 01:51:06 -0500 Subject: [PATCH 13/22] Port gdb.py and hexprog.py to Python 3. Unfortunately, the serial data are not 7-bit clean (see write_mem()). So getpacket() and putpacket() use bytes objects rather than strings. --- scripts/gdb.py | 253 ++++++++++++++++++++++++++------------------- scripts/hexprog.py | 84 ++++++++------- 2 files changed, 196 insertions(+), 141 deletions(-) diff --git a/scripts/gdb.py b/scripts/gdb.py index 286627c2..6c6e02d0 100644 --- a/scripts/gdb.py +++ b/scripts/gdb.py @@ -3,7 +3,7 @@ # gdb.py: Python module for low level GDB protocol implementation # Copyright (C) 2009 Black Sphere Technologies # Written by Gareth McMullin -# +# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or @@ -24,24 +24,18 @@ import struct import time def hexify(s): - """Convert a binary string into hex representation""" - ret = '' - for c in s: - ret += "%02X" % ord(c) - return ret + """Convert a bytes object into hex bytes representation""" + return s.hex().encode() def unhexify(s): - """Convert a hex string into binary representation""" - ret = '' - for i in range(0, len(s), 2): - ret += chr(int(s[i:i+2], 16)) - return ret + """Convert a hex-encoded bytes into bytes object""" + return bytes.fromhex(s.decode()) class FakeSocket: """Emulate socket functions send and recv on a file object""" def __init__(self, file): self.file = file - + def send(self, data): self.file.write(data) @@ -52,148 +46,186 @@ class Target: def __init__(self, sock): if "send" in dir(sock): self.sock = sock - else: + else: self.sock = FakeSocket(sock) + self.PacketSize=0x100 # default + def getpacket(self): """Return the first correctly received packet from GDB target""" while True: - while self.sock.recv(1) != '$': pass + while self.sock.recv(1) != b'$': + pass + csum = 0 - packet = '' + packet = [] # list-of-small-int while True: - c = self.sock.recv(1) - if c == '#': break + c, = self.sock.recv(1) + if c == ord('#'): + break - if c == '$': - packet = '' + if c == ord('$'): + packet = [] csum = 0 continue - if c == '}': - c = self.sock.recv(1) - csum += ord(c) + ord('}') - packet += chr(ord(c) ^ 0x20) - continue + if c == ord('}'): + c, = self.sock.recv(1) + csum += c + ord('}') + packet.append(c ^ 0x20) + continue - packet += c - csum += ord(c) + packet.append(c) + csum += c - if (csum & 0xFF) == int(self.sock.recv(2),16): break + if (csum & 0xFF) == int(self.sock.recv(2),16): + break - self.sock.send('-') - - self.sock.send('+') - return packet + self.sock.send(b'-') + self.sock.send(b'+') + return bytes(packet) def putpacket(self, packet): - """Send packet to GDB target and wait for acknowledge""" + """Send packet to GDB target and wait for acknowledge + packet is bytes or string""" + + if type(packet) == str: + packet = packet.encode() + while True: - self.sock.send('$') - csum = 0 + out = [] + for c in packet: - if (c == '$') or (c == '#') or (c == '}'): - self.sock.send('}') - self.sock.send(chr(ord(c) ^ 0x20)) - csum += (ord(c) ^ 0x20) + ord('}') + if (c in b'$#}'): + out.append(ord('}')) + out.append(c ^ 0x20) else: - self.sock.send(c) - csum += ord(c) - self.sock.send('#') - self.sock.send("%02X" % (csum & 0xFF)) - if self.sock.recv(1) == '+': break + out.append(c) + + csum = sum(out) + outb = b'$'+bytes(out)+b'#%02X' % (csum & 0xff) + + self.sock.send(outb) + if self.sock.recv(1) == b'+': + break def monitor(self, cmd): """Send gdb "monitor" command to target""" + if type(cmd) == str: + cmd = cmd.encode() + ret = [] - self.putpacket("qRcmd," + hexify(cmd)) + self.putpacket(b"qRcmd," + hexify(cmd)) while True: s = self.getpacket() - if s == '': return None - if s == 'OK': return ret - if s.startswith('O'): ret.append(unhexify(s[1:])) + + if s == b'': + return None + if s == b'OK': + return ret + if s.startswith(b'O'): + ret.append(unhexify(s[1:])) else: - raise Exception('Invalid GDB stub response') + raise Exception('Invalid GDB stub response %r'%s.decode()) def attach(self, pid): """Attach to target process (gdb "attach" command)""" - self.putpacket("vAttach;%08X" % pid) + self.putpacket(b"vAttach;%08X" % pid) reply = self.getpacket() - if (len(reply) == 0) or (reply[0] == 'E'): + if (reply == b'') or (reply[:1] == b'E'): raise Exception('Failed to attach to remote pid %d' % pid) def detach(self): """Detach from target process (gdb "detach" command)""" - self.putpacket("D") - if self.getpacket() != 'OK': + self.putpacket(b"D") + if self.getpacket() != b'OK': raise Exception("Failed to detach from remote process") def reset(self): """Reset the target system""" - self.putpacket("r") + self.putpacket(b"r") def read_mem(self, addr, length): """Read length bytes from target at address addr""" - self.putpacket("m%08X,%08X" % (addr, length)) - reply = self.getpacket() - if (len(reply) == 0) or (reply[0] == 'E'): - raise Exception('Error reading memory at 0x%08X' % addr) - try: - data = unhexify(reply) - except Excpetion: - raise Exception('Invalid response to memory read packet: %r' % reply) - return data - + ret = b'' + while length: + # print "Read" + packlen = min(length,self.PacketSize//2) + self.putpacket(b"m%08X,%08X" % (addr, packlen)) + reply = self.getpacket() + if (reply == b'') or (reply[:1] == b'E'): + raise Exception('Error reading memory at 0x%08X' % addr) + try: + data = unhexify(reply) + except Exception: + raise Exception('Invalid response to memory read packet: %r' % reply) + ret += data + length -= packlen + addr += packlen + + return ret + def write_mem(self, addr, data): """Write data to target at address addr""" - self.putpacket("X%08X,%08X:%s" % (addr, len(data), data)) - if self.getpacket() != 'OK': - raise Exception('Error writing to memory at 0x%08X' % addr) + data = bytes(data) + + while data: + d = data[:self.PacketSize-44] + data = data[len(d):] + #print("Writing %d bytes at 0x%X" % (len(d), addr)) + pack = b"X%08X,%08X:%s" % (addr, len(d), d) + self.putpacket(pack) + + if self.getpacket() != b'OK': + raise Exception('Error writing to memory at 0x%08X' % addr) + addr += len(d) def read_regs(self): """Read target core registers""" - self.putpacket("g") + self.putpacket(b"g") reply = self.getpacket() - if (len(reply) == 0) or (reply[0] == 'E'): + if (reply == b'') or (reply[:1] == b'E'): raise Exception('Error reading memory at 0x%08X' % addr) try: data = unhexify(reply) - except Excpetion: + except Exception: raise Exception('Invalid response to memory read packet: %r' % reply) - return struct.unpack("=20L", data) + ret = array.array('I',data) + return ret def write_regs(self, *regs): """Write target core registers""" data = struct.pack("=%dL" % len(regs), *regs) - self.putpacket("G" + hexify(data)) - if self.getpacket() != 'OK': + self.putpacket(b"G" + hexify(data)) + if self.getpacket() != b'OK': raise Exception('Error writing to target core registers') def memmap_read(self): """Read the XML memory map from target""" offset = 0 - ret = '' + ret = b'' while True: - self.putpacket("qXfer:memory-map:read::%08X,%08X" % (offset, 512)) + self.putpacket(b"qXfer:memory-map:read::%08X,%08X" % (offset, 512)) reply = self.getpacket() - if (reply[0] == 'm') or (reply[0] == 'l'): + if (reply[0] in b'ml'): offset += len(reply) - 1 ret += reply[1:] else: - raise Exception("Invalid GDB stub response") + raise Exception('Invalid GDB stub response %r'%reply) + + if reply[:1] == b'l': + return ret - if reply[0] == 'l': return ret - def resume(self): """Resume target execution""" - self.putpacket("c") + self.putpacket(b'c') def interrupt(self): """Interrupt target execution""" - self.sock.send("\x03") + self.sock.send(b'\x03') def run_stub(self, stub, address, *args): """Execute a binary stub at address, passing args in core registers.""" @@ -205,11 +237,19 @@ class Target: regs[15] = address self.write_regs(*regs) self.resume() - reply = self.getpacket() + reply = None while not reply: reply = self.getpacket() - if not reply.startswith("T05"): - raise Exception("Invalid stop response: %r" % reply) + if not reply.startswith(b"T05"): + message = "Invalid stop response: %r" % reply + try: + message += {'T02':' (SIGINT)', + 'T05':' (SIGTRAP)', + 'T0B':' (SIGSEGV)', + 'T1D':' (SIGLOST)'}[reply] + except KeyError: + pass + raise Exception(message) class FlashMemory: def __init__(self, target, offset, length, blocksize): @@ -217,27 +257,30 @@ class Target: self.offset = offset self.length = length self.blocksize = blocksize - self.blocks = list(None for i in range(length / blocksize)) + self.blocks = list(None for i in range(length // blocksize)) def prog(self, offset, data): - assert ((offset >= self.offset) and + assert type(data)==bytes + + assert ((offset >= self.offset) and (offset + len(data) <= self.offset + self.length)) while data: - index = (offset - self.offset) / self.blocksize + index = (offset - self.offset) // self.blocksize bloffset = (offset - self.offset) % self.blocksize bldata = data[:self.blocksize-bloffset] data = data[len(bldata):]; offset += len(bldata) if self.blocks[index] is None: # Initialize a clear block - self.blocks[index] = "".join(chr(0xff) for i in range(self.blocksize)) - self.blocks[index] = (self.blocks[index][:bloffset] + bldata + + self.blocks[index] = bytes(0xff for i in range(self.blocksize)) + self.blocks[index] = (self.blocks[index][:bloffset] + bldata + self.blocks[index][bloffset+len(bldata):]) def commit(self, progress_cb=None): totalblocks = 0 for b in self.blocks: - if b is not None: totalblocks += 1 - + if b is not None: + totalblocks += 1 + block = 0 for i in range(len(self.blocks)): block += 1 @@ -247,35 +290,37 @@ class Target: # Erase the block data = self.blocks[i] addr = self.offset + self.blocksize * i - if data is None: continue + if data is None: + continue #print "Erasing flash at 0x%X" % (self.offset + self.blocksize*i) - self.target.putpacket("vFlashErase:%08X,%08X" % + self.target.putpacket(b"vFlashErase:%08X,%08X" % (self.offset + self.blocksize*i, self.blocksize)) - if self.target.getpacket() != 'OK': + if self.target.getpacket() != b'OK': raise Exception("Failed to erase flash") while data: d = data[0:980] data = data[len(d):] #print "Writing %d bytes at 0x%X" % (len(d), addr) - self.target.putpacket("vFlashWrite:%08X:%s" % (addr, d)) + self.target.putpacket(b"vFlashWrite:%08X:%s" % (addr, d)) addr += len(d) - if self.target.getpacket() != 'OK': + if self.target.getpacket() != b'OK': raise Exception("Failed to write flash") - - self.target.putpacket("vFlashDone") - if self.target.getpacket() != 'OK': + + self.target.putpacket(b"vFlashDone") + if self.target.getpacket() != b'OK': raise Exception("Failed to commit") - - self.blocks = list(None for i in range(self.length / self.blocksize)) - + + self.blocks = list(None for i in range(self.length // self.blocksize)) + def flash_probe(self): self.mem = [] xmldom = parseString(self.memmap_read()) - + for memrange in xmldom.getElementsByTagName("memory"): - if memrange.getAttribute("type") != "flash": continue + if memrange.getAttribute("type") != "flash": + continue offset = eval(memrange.getAttribute("start")) length = eval(memrange.getAttribute("length")) for property in memrange.getElementsByTagName("property"): @@ -297,5 +342,3 @@ class Target: def flash_commit(self, progress_cb=None): for m in self.mem: m.commit(progress_cb) - - diff --git a/scripts/hexprog.py b/scripts/hexprog.py index ccfb43c5..43f9693e 100755 --- a/scripts/hexprog.py +++ b/scripts/hexprog.py @@ -3,7 +3,7 @@ # hexprog.py: Python application to flash a target with an Intel hex file # Copyright (C) 2011 Black Sphere Technologies # Written by Gareth McMullin -# +# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or @@ -31,15 +31,16 @@ def flash_write_hex(target, hexfile, progress_cb=None): f = open(hexfile) addrhi = 0 for line in f: - if line[0] != ':': raise Exception("Error in hex file") + if line[0] != ':': + raise Exception("Error in hex file") reclen = int(line[1:3], 16) addrlo = int(line[3:7], 16) rectype = int(line[7:9], 16); - if sum(ord(x) for x in gdb.unhexify(line[1:11+reclen*2])) & 0xff != 0: - raise Exception("Checksum error in hex file") + if sum(x for x in bytes.fromhex(line[1:11+reclen*2])) & 0xff != 0: + raise Exception("Checksum error in hex file") if rectype == 0: # Data record addr = (addrhi << 16) + addrlo - data = gdb.unhexify(line[9:9+reclen*2]) + data = bytes.fromhex(line[9:9+reclen*2]) target.flash_write_prepare(addr, data) pass elif rectype == 4: # High address record @@ -48,16 +49,16 @@ def flash_write_hex(target, hexfile, progress_cb=None): elif rectype == 5: # Entry record pass elif rectype == 1: # End of file record - break + break else: raise Exception("Invalid record in hex file") try: target.flash_commit(progress_cb) except: - print "Flash write failed! Is device protected?\n" + print("Flash write failed! Is device protected?\n") exit(-1) - + if __name__ == "__main__": from serial import Serial, SerialException @@ -67,8 +68,8 @@ if __name__ == "__main__": if platform == "linux2": print ("\x1b\x5b\x48\x1b\x5b\x32\x4a") # clear terminal screen print("Black Magic Probe -- Target Production Programming Tool -- version 1.0") - print "Copyright (C) 2011 Black Sphere Technologies" - print "License GPLv3+: GNU GPL version 3 or later " + print("Copyright (C) 2011 Black Sphere Technologies") + print("License GPLv3+: GNU GPL version 3 or later ") print("") dev = "COM1" if platform == "win32" else "/dev/ttyACM0" @@ -80,13 +81,20 @@ if __name__ == "__main__": try: opts, args = getopt(argv[1:], "sd:b:t:rR") for opt in opts: - if opt[0] == "-s": scan = "swdp_scan" - elif opt[0] == "-b": baud = int(opt[1]) - elif opt[0] == "-d": dev = opt[1] - elif opt[0] == "-t": targetno = int(opt[1]) - elif opt[0] == "-r": unprot = True - elif opt[0] == "-R": prot = True - else: raise Exception() + if opt[0] == "-s": + scan = "swdp_scan" + elif opt[0] == "-b": + baud = int(opt[1]) + elif opt[0] == "-d": + dev = opt[1] + elif opt[0] == "-t": + targetno = int(opt[1]) + elif opt[0] == "-r": + unprot = True + elif opt[0] == "-R": + prot = True + else: + raise Exception() hexfile = args[0] except: @@ -101,39 +109,44 @@ if __name__ == "__main__": exit(-1) try: - s = Serial(dev, baud, timeout=3) - s.setDTR(1) - while s.read(1024): - pass + s = Serial(dev) #, baud, timeout=0.1) + #s.setDTR(1) + #s.flushInput() + + #while s.read(1024): + # pass target = gdb.Target(s) - - except SerialException, e: + + except SerialException as e: print("FATAL: Failed to open serial device!\n%s\n" % e[0]) exit(-1) try: r = target.monitor("version") - for s in r: print s, - except SerialException, e: + for s in r: + print(s.decode(), end=' ') + except SerialException as e: print("FATAL: Serial communication failure!\n%s\n" % e[0]) exit(-1) - except: pass + #except: pass - print "Target device scan:" + print("Target device scan:") targetlist = None r = target.monitor(scan) - for s in r: - print s, - print + for s in r: + print(s.decode(), end=' ') + print() r = target.monitor("targets") - for s in r: - if s.startswith("No. Att Driver"): targetlist = [] + for s in r: + if s.startswith(b"No. Att Driver"): + targetlist = [] try: - if type(targetlist) is list: + if type(targetlist) is list: targetlist.append(int(s[:2])) - except: pass + except: + pass #if not targetlist: # print("FATAL: No usable targets found!\n") @@ -161,7 +174,7 @@ if __name__ == "__main__": print("FLASH memory -- Offset: 0x%X BlockSize:0x%X\n" % (m.offset, m.blocksize)) def progress(percent): - print ("Progress: %d%%\r" % percent), + print("Progress: %d%%\r" % percent, end=' ') stdout.flush() print("Programming target") @@ -179,4 +192,3 @@ if __name__ == "__main__": target.detach() print("\nAll operations complete!\n") - From 8039e2b26aed1ccb7bc94e1abcec5f3164c3a700 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Tue, 28 Dec 2021 15:07:07 +0800 Subject: [PATCH 14/22] crc32: define `start_time` when debug is enabled The variable `start_time` indicates when a CRC32 operation began. This variable is used to benchmark the speed of the CRC32 function. Currently, this is tied to `PC_HOSTED`. However, the actual usage is tied to `DEBUG_WARN`. This means that the variable is undefined when `DEBUG_WARN` is defined and we're not configured for `PC_HOSTED` mode. Add macro guards around this variable so that it is defined when debugging is enabled, rather than only when building on `PC_HOSTED`. Signed-off-by: Sean Cross --- src/crc32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/crc32.c b/src/crc32.c index a56b9944..8ce25dff 100644 --- a/src/crc32.c +++ b/src/crc32.c @@ -106,9 +106,11 @@ int generic_crc32(target *t, uint32_t *crc_res, uint32_t base, size_t len) * 22 s @ 4k and 21 s @ 64k */ uint8_t bytes[0x1000]; - uint32_t start_time = platform_time_ms(); #else uint8_t bytes[128]; +#endif +#if defined(ENABLE_DEBUG) + uint32_t start_time = platform_time_ms(); #endif uint32_t last_time = platform_time_ms(); while (len) { From d00607f71aaef3c9dc6f1e27a699b0c4376820b4 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Wed, 29 Dec 2021 22:08:22 +0800 Subject: [PATCH 15/22] samd: parameterize memory and flash sizes Various SAMD devices have different amounts of memory. Up until now, all SAMD devices have had the same amount, and therefore this value was hardcoded to 32k of RAM and 256k of flash. Add a parameter to the description field and set it to default to the previous values. Use this description field when adding memories to the target definition. Signed-off-by: Sean Cross --- src/target/samd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/target/samd.c b/src/target/samd.c index 02879fbd..86acbaa9 100644 --- a/src/target/samd.c +++ b/src/target/samd.c @@ -341,6 +341,8 @@ struct samd_descr { uint8_t series; char revision; char pin; + uint32_t ram_size; + uint32_t flash_size; uint8_t mem; char variant; char package[3]; @@ -351,6 +353,8 @@ struct samd_descr samd_parse_device_id(uint32_t did) uint8_t i = 0; const struct samd_part *parts = samd_d21_parts; memset(samd.package, 0, 3); + samd.ram_size = 0x8000; + samd.flash_size = 0x40000; uint8_t family = (did >> SAMD_DID_FAMILY_POS) & SAMD_DID_FAMILY_MASK; @@ -513,8 +517,8 @@ bool samd_probe(target *t) t->attach = samd_protected_attach; } - target_add_ram(t, 0x20000000, 0x8000); - samd_add_flash(t, 0x00000000, 0x40000); + target_add_ram(t, 0x20000000, samd.ram_size); + samd_add_flash(t, 0x00000000, samd.flash_size); target_add_commands(t, samd_cmd_list, "SAMD"); /* If we're not in reset here */ From c832cb04e7a9acfcb3013b089f042aa5d7e56e9f Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Wed, 29 Dec 2021 22:10:18 +0800 Subject: [PATCH 16/22] samd: add support for SAMD09 The SAMD09 CPU is used in boards such as the Adafruit Seesaw. It has a smaller amount of memory and flash than other SAMD ports. This was tested with an Adafruit Seesaw. These boards come with preloaded firmware. As a test, the firmware was dumped and flash was erased. Then, flash was verified to be all zeroes. Finally, the firmware was loaded back in: (gdb) p/x *(unsigned int *)0@32 $8 = {0x20000f88, 0x1db, 0x1d1, 0x1d9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d9, 0x0, 0x0, 0xf5, 0x1081, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x0, 0x1d9, 0x1d9, 0x25e9, 0x0, 0x0, 0x1d9, 0x1d9, 0x1d9} (gdb) dump ihex memory flash.ihex 0 8192 (gdb) mon erase_mass Erase successful! (gdb) p/x *(unsigned int *)0@32 $9 = {0xffffffff } (gdb) load flash.ihex Loading section .sec1, size 0x2000 lma 0x0 Start address 0x00000000, load size 8192 Transfer rate: 5 KB/sec, 910 bytes/write. (gdb) p/x *(unsigned int *)0@32 $10 = {0x20000f88, 0x1db, 0x1d1, 0x1d9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d9, 0x0, 0x0, 0xf5, 0x1081, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x0, 0x1d9, 0x1d9, 0x25e9, 0x0, 0x0, 0x1d9, 0x1d9, 0x1d9} (gdb) Signed-off-by: Sean Cross --- src/target/samd.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/target/samd.c b/src/target/samd.c index 86acbaa9..f6134088 100644 --- a/src/target/samd.c +++ b/src/target/samd.c @@ -22,6 +22,7 @@ * programming. * * Tested with + * * SAMD09D14A (rev B) * * SAMD20E17A (rev C) * * SAMD20J18A (rev B) * * SAMD21J18A (rev B) @@ -128,7 +129,7 @@ const struct command_s samd_cmd_list[] = { #define SAMD_STATUSB_PROT (1 << 16) /* Device Identification Register (DID) */ -#define SAMD_DID_MASK 0xFF3C0000 +#define SAMD_DID_MASK 0xFF380000 #define SAMD_DID_CONST_VALUE 0x10000000 #define SAMD_DID_DEVSEL_MASK 0xFF #define SAMD_DID_DEVSEL_POS 0 @@ -384,6 +385,7 @@ struct samd_descr samd_parse_device_id(uint32_t did) } break; case 3: samd.series = 11; break; + case 4: samd.series = 9; break; default: samd.series = 0; break; } /* Revision */ @@ -423,6 +425,23 @@ struct samd_descr samd_parse_device_id(uint32_t did) samd.mem = 14 - (devsel % 3); samd.variant = 'A'; break; + case 9: /* SAM D09 */ + samd.ram_size = 4096; + switch (devsel) { + case 0: + samd.pin = 'D'; + samd.mem = 14; + samd.flash_size = 16384; + samd.package[0] = 'M'; + break; + case 7: + samd.pin = 'C'; + samd.mem = 13; + samd.flash_size = 8192; + break; + } + samd.variant = 'A'; + break; } return samd; @@ -479,14 +498,14 @@ bool samd_probe(target *t) /* Part String */ if (protected) { sprintf(priv_storage->samd_variant_string, - "Atmel SAM%c%d%c%d%c%s (rev %c) (PROT=1)", + "Atmel SAM%c%02d%c%d%c%s (rev %c) (PROT=1)", samd.family, samd.series, samd.pin, samd.mem, samd.variant, samd.package, samd.revision); } else { sprintf(priv_storage->samd_variant_string, - "Atmel SAM%c%d%c%d%c%s (rev %c)", + "Atmel SAM%c%02d%c%d%c%s (rev %c)", samd.family, samd.series, samd.pin, samd.mem, samd.variant, From 8def28dee990d2a8a66a9ac90bf35dc80f21428e Mon Sep 17 00:00:00 2001 From: Frank Kunz Date: Sun, 2 Jan 2022 10:02:09 +0100 Subject: [PATCH 17/22] Add option bit support for STM32WLxx Support for read/write/erase option bits. Signed-off-by: Frank Kunz --- src/target/stm32l4.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/target/stm32l4.c b/src/target/stm32l4.c index cdd9fdf2..b0f7f81d 100644 --- a/src/target/stm32l4.c +++ b/src/target/stm32l4.c @@ -671,8 +671,12 @@ static const uint8_t g4_i2offset[11] = { 0x20, 0x24, 0x28, 0x2c, 0x30, 0x70, 0x44, 0x48, 0x4c, 0x50, 0x74 }; +static const uint8_t wl_i2offset[7] = { + 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38 +}; + static bool stm32l4_option_write( - target *t,const uint32_t *values, int len, const uint8_t *i2offset) + target *t,const uint32_t *values, int len, const uint8_t *i2offset, uint32_t fpec_base) { tc_printf(t, "Device will lose connection. Rescan!\n"); stm32l4_flash_unlock(t); @@ -682,7 +686,7 @@ static bool stm32l4_option_write( if(target_check_error(t)) return true; for (int i = 0; i < len; i++) - target_mem_write32(t, L4_FPEC_BASE + i2offset[i], values[i]); + target_mem_write32(t, fpec_base + i2offset[i], values[i]); stm32l4_flash_write32(t, FLASH_CR, FLASH_CR_OPTSTRT); while (stm32l4_flash_read32(t, FLASH_SR) & FLASH_SR_BSY) if(target_check_error(t)) @@ -717,10 +721,6 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[]) tc_printf(t, "STM32L5 options not implemented!\n"); return false; } - if (t->idcode == ID_STM32WLXX) { - tc_printf(t, "STM32WLxx options not implemented!\n"); - return false; - } if (t->idcode == ID_STM32WBXX) { tc_printf(t, "STM32WBxx options not implemented!\n"); return false; @@ -733,12 +733,17 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[]) 0xFFFFFFFF, 0xFFFFFFFF, 0xFF00FFFF, 0xFF00FFFF, 0xFF00FF00 }; + static const uint32_t wl_values[11] = { + 0x3FEFF0AA, 0xFFFFFFFF, 0xFFFFFF00, 0xFF80FFFF, 0xFF80FFFF, 0xFFFFFFFF, + 0xFFFFFF00 + }; + uint32_t val; uint32_t values[11] = { 0xFFEFF8AA, 0xFFFFFFFF, 0, 0x000000ff, 0x000000ff, 0xffffffff, 0, 0x000000ff, 0x000000ff }; int len; bool res = false; - + uint32_t fpec_base = L4_FPEC_BASE; const uint8_t *i2offset = l4_i2offset; if (t->idcode == ID_STM32L43) {/* L43x */ len = 5; @@ -753,24 +758,30 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[]) len = 6; for (int i = 0; i < len; i++) values[i] = g4_values[i]; + } else if (t->idcode == ID_STM32WLXX) {/* WLxx */ + len = 7; + i2offset = wl_i2offset; + fpec_base = WL_FPEC_BASE; + for (int i = 0; i < len; i++) + values[i] = wl_values[i]; } else { len = 9; } if ((argc == 2) && !strcmp(argv[1], "erase")) { - res = stm32l4_option_write(t, values, len, i2offset); + res = stm32l4_option_write(t, values, len, i2offset, fpec_base); } else if ((argc > 2) && !strcmp(argv[1], "write")) { int i; for (i = 2; i < argc; i++) values[i - 2] = strtoul(argv[i], NULL, 0); for (i = i - 2; i < len; i++) { - uint32_t addr = L4_FPEC_BASE + i2offset[i]; + uint32_t addr = fpec_base + i2offset[i]; values[i] = target_mem_read32(t, addr); } if ((values[0] & 0xff) == 0xCC) { values[0]++; tc_printf(t, "Changing Level 2 request to Level 1!"); } - res = stm32l4_option_write(t, values, len, i2offset); + res = stm32l4_option_write(t, values, len, i2offset, fpec_base); } else { tc_printf(t, "usage: monitor option erase\n"); tc_printf(t, "usage: monitor option write ...\n"); @@ -780,8 +791,8 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[]) return false; } for (int i = 0; i < len; i ++) { - uint32_t addr = L4_FPEC_BASE + i2offset[i]; - val = target_mem_read32(t, L4_FPEC_BASE + i2offset[i]); + uint32_t addr = fpec_base + i2offset[i]; + val = target_mem_read32(t, fpec_base + i2offset[i]); tc_printf(t, "0x%08X: 0x%08X\n", addr, val); } return true; From ad6c1eb11bd31899713dc661c5fa5b33db36d279 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Tue, 4 Jan 2022 09:02:17 +0100 Subject: [PATCH 18/22] scripts: fix stm32_mem.py for python 3 Python 3 does not accept a characters string where a bytes string is needed. --- scripts/stm32_mem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stm32_mem.py b/scripts/stm32_mem.py index 51a8537b..18674884 100755 --- a/scripts/stm32_mem.py +++ b/scripts/stm32_mem.py @@ -72,7 +72,7 @@ def stm32_read(dev): return data def stm32_manifest(dev): - dev.download(0, "") + dev.download(0, b"") while True: try: status = dev.get_status() From 946ccab7780f1c64324d34317f9d1f69ce8f059e Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Tue, 4 Jan 2022 09:12:37 +0100 Subject: [PATCH 19/22] scripts: stm32_mem cosmetic changes Add a newline to avoid overwriting the last "Programming memory..." message. Remove inline tabs. --- scripts/stm32_mem.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/stm32_mem.py b/scripts/stm32_mem.py index 18674884..664b3df4 100755 --- a/scripts/stm32_mem.py +++ b/scripts/stm32_mem.py @@ -138,7 +138,7 @@ def stm32_scan(args, test): product = dfudev.handle.getString(dfudev.dev.iProduct, 96).decode('utf8') serial_no = dfudev.handle.getString(dfudev.dev.iSerialNumber, 30).decode('utf8') if args.serial_target: - if man == "Black Sphere Technologies" and serial_no == args.serial_target: + if man == "Black Sphere Technologies" and serial_no == args.serial_target: break else: if man == "Black Sphere Technologies": @@ -236,7 +236,7 @@ if __name__ == "__main__": bin = file.read() len = len(bin) addr = start - print("-") + print("\n-") while bin: try: stm32_set_address(dfudev, addr) @@ -251,7 +251,7 @@ if __name__ == "__main__": else : size = len if bin[:size] != bytearray(data[:size]) : - print ("\nMitmatch in block at 0x%08X" % addr) + print ("\nMismatch in block at 0x%08X" % addr) break; bin = bin[1024:] addr += 1024 From 5c07d6170fce8404ffd5cf841eb5ec9a1e36c222 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Tue, 4 Jan 2022 09:14:27 +0100 Subject: [PATCH 20/22] scripts: remove import from future which imports from the past There is no point to support Python 2. --- scripts/stm32_mem.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/stm32_mem.py b/scripts/stm32_mem.py index 664b3df4..9f47df31 100755 --- a/scripts/stm32_mem.py +++ b/scripts/stm32_mem.py @@ -18,7 +18,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from __future__ import print_function from time import sleep import struct import os From d6440d716cc8bcb03c6d9c78d4bf1ff8e0bf72cf Mon Sep 17 00:00:00 2001 From: Piotr Esden-Tempski Date: Fri, 21 Jan 2022 22:02:06 -0800 Subject: [PATCH 21/22] Updated github org references to blackmagic-debug. --- HACKING | 2 +- README.md | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/HACKING b/HACKING index f53c89ef..8f8cf385 100644 --- a/HACKING +++ b/HACKING @@ -1 +1 @@ -See https://github.com/blacksphere/blackmagic/wiki/Hacking +See https://github.com/blackmagic-debug/blackmagic/wiki/Hacking diff --git a/README.md b/README.md index 91c18004..0eac1e65 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,7 @@ Black Magic Probe ================= -[![Build Status](https://travis-ci.org/blacksphere/blackmagic.svg?branch=master)](https://travis-ci.org/blacksphere/blackmagic) [![Discord](https://img.shields.io/discord/613131135903596547?logo=discord)](https://discord.gg/P7FYThy) -[![Donate](https://img.shields.io/badge/paypal-donate-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N84QYNAM2JJQG) -[![Kickstarter](https://img.shields.io/badge/kickstarter-back%20us-14e16e.svg)](https://www.kickstarter.com/projects/esden/1bitsy-and-black-magic-probe-demystifying-arm-prog) Firmware for the Black Magic Debug Probe. @@ -18,11 +15,15 @@ standard USB interface. The user is able to control exactly what happens using the GNU source level debugging software, GDB. Serial Wire Output (SWO) allows the target to write tracing and logging to the host without using usb or serial port. Decoding SWO in the probe itself -makes [SWO viewing as simple as connecting to a serial port](https://github.com/blacksphere/blackmagic/wiki/Serial-Wire-Output). +makes [SWO viewing as simple as connecting to a serial port](https://github.com/blackmagic-debug/blackmagic/wiki/Serial-Wire-Output). -See online documentation at https://github.com/blacksphere/blackmagic/wiki -Binaries from the latest automated build are at http://builds.blacksphere.co.nz/blackmagic +Resources +========= + + * [Documentation](https://github.com/blackmagic-debug/blackmagic/wiki) + * [Binary builds](http://builds.blacksphere.co.nz/blackmagic) + Toolchain specific remarks ========================== @@ -95,7 +96,7 @@ Add "-P (position)" to the next invocation to select one. For the setup from the sample session above: In another terminal: ```console -> blackmagic +> blackmagic Using 1d50:6018 E2E489E7 Black Sphere Technologies Black Magic Probe (STLINK), (Firmware v1.6.1-477-g70bb131-dirty) Remote is Black Magic Probe (STLINK), (Firmware v1.6.1-477-g70bb131-dirty) v1.6.1-477-g70bb131-dirty Listening on TCP: 2000 From d594b42976e3b9640b64ef1cb2da3f74067930b8 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 13 Jan 2022 12:06:13 +0100 Subject: [PATCH 22/22] Cortexm: With connect under reset, keep the device halted until attach. --- src/target/adiv5.c | 12 +++++++++--- src/target/cortexm.c | 2 -- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 4cc528fd..7d167093 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -834,9 +834,15 @@ void adiv5_dp_init(ADIv5_DP_t *dp) adiv5_ap_unref(ap); } /* We halted at least CortexM for Romtable scan. - * Release the devices now. Attach() will halt them again.*/ - for (target *t = target_list; t; t = t->next) - target_halt_resume(t, false); + * With connect under reset, keep the devices halted. + * Otherwise, release the devices now. + * Attach() will halt them again. + */ + for (target *t = target_list; t; t = t->next) { + if (!connect_assert_srst) { + target_halt_resume(t, false); + } + } adiv5_dp_unref(dp); } diff --git a/src/target/cortexm.c b/src/target/cortexm.c index f7ad4e0c..2288063e 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -471,8 +471,6 @@ bool cortexm_probe(ADIv5_AP_t *ap) PROBE(lpc17xx_probe); } #undef PROBE - /* Restart the CortexM we stopped for Romtable scan. Allow pure debug.*/ - target_halt_resume(t, 0); return true; }