├── .gitignore ├── BlackMagicProbe.pdf ├── CC-BY-NC-ND-legalcode.txt ├── LICENSE ├── README.md ├── doc ├── blackmagicprobe-book.jpg ├── bmdebug.png ├── bmflash.png ├── bmp-v23.jpg ├── bmprofile-top.png └── bmtrace.png ├── examples ├── assert.c ├── assert.h ├── function_trace.c ├── function_trace.tsdl ├── semihosting.c ├── semihosting.h ├── traceswo.c ├── traceswo.h ├── traceswo_spi.c ├── traceswo_spi.h ├── traceswo_uart.c └── traceswo_uart.h ├── source ├── .vscode │ └── launch.json ├── Makefile.linux ├── Makefile.mingw ├── Makefile.msvc ├── Makefile.watcom ├── armdisasm.c ├── armdisasm.h ├── bmcommon.c ├── bmcommon.h ├── bmdebug.c ├── bmdebug.rc ├── bmflash.c ├── bmflash.rc ├── bmflash_help.h ├── bmflash_help.md ├── bmp-scan.c ├── bmp-scan.h ├── bmp-script.c ├── bmp-script.h ├── bmp-support.c ├── bmp-support.h ├── bmprofile.c ├── bmprofile.rc ├── bmprofile_help.h ├── bmprofile_help.md ├── bmscan.c ├── bmscript ├── bmserial.c ├── bmserial.rc ├── bmserial_help.h ├── bmserial_help.md ├── bmtrace.c ├── bmtrace.rc ├── bmtrace_help.h ├── bmtrace_help.md ├── c11threads.h ├── c11threads_win32.c ├── c99_snprintf.h ├── calltree.c ├── cksum.c ├── cksum.h ├── crc32.c ├── crc32.h ├── decodectf.c ├── decodectf.h ├── demangle.c ├── demangle.h ├── dirent.c ├── dirent.h ├── dwarf.c ├── dwarf.h ├── elf-postlink.c ├── elf.c ├── elf.h ├── fileloader.c ├── fileloader.h ├── findfont.c ├── findfont.h ├── gdb-rsp.c ├── gdb-rsp.h ├── guidriver.c ├── guidriver.h ├── ident.c ├── ident.h ├── lodepng.c ├── lodepng.h ├── makefile.cfg ├── makefile.dep ├── mcu-info.c ├── mcu-info.h ├── memdump.c ├── memdump.h ├── minGlue.h ├── minIni.c ├── minIni.h ├── nuklear.c ├── nuklear.h ├── nuklear_config.h ├── nuklear_gdip.c ├── nuklear_gdip.h ├── nuklear_glfw_gl2.c ├── nuklear_glfw_gl2.h ├── nuklear_guide.c ├── nuklear_guide.h ├── nuklear_mousepointer.c ├── nuklear_mousepointer.h ├── nuklear_msgbox.c ├── nuklear_msgbox.h ├── nuklear_splitter.c ├── nuklear_splitter.h ├── nuklear_style.c ├── nuklear_style.h ├── nuklear_tooltip.c ├── nuklear_tooltip.h ├── osdialog.c ├── osdialog.h ├── osdialog_gtk2.c ├── osdialog_gtk3.c ├── osdialog_win.c ├── parsetsdl.c ├── parsetsdl.h ├── pathsearch.c ├── pathsearch.h ├── qglib.c ├── qglib.h ├── qoi.h ├── quickguide.h ├── res │ ├── icon_debug.ico │ ├── icon_debug_64.h │ ├── icon_debug_64.png │ ├── icon_download.ico │ ├── icon_download_32.png │ ├── icon_download_64.h │ ├── icon_download_64.png │ ├── icon_profile.ico │ ├── icon_profile_64.h │ ├── icon_profile_64.png │ ├── icon_serial.ico │ ├── icon_serial_64.h │ ├── icon_serial_64.png │ ├── icon_trace.ico │ ├── icon_trace_64.h │ └── icon_trace_64.png ├── rs232.c ├── rs232.h ├── serialmon.c ├── serialmon.h ├── specialfolder.c ├── specialfolder.h ├── strlcpy.c ├── strlcpy.h ├── strmatch.c ├── strmatch.h ├── svd-support.c ├── svd-support.h ├── svnrev.h ├── swotrace.c ├── swotrace.h ├── tcl.c ├── tcl.h ├── tcpip.c ├── tcpip.h ├── tracegen.c ├── usb-support.c ├── usb-support.h ├── xmltractor.c └── xmltractor.h └── support ├── .gdbinit ├── 55-blackmagicprobe.rules └── blackmagic.inf /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # Editor temp files 55 | *~* 56 | 57 | # Linux Executable Files 58 | source/tracegen 59 | source/elf-postlink 60 | source/calltree 61 | source/bmtrace 62 | source/bmserial 63 | source/bmscan 64 | source/bmprofile 65 | source/bmflash 66 | source/bmdebug 67 | 68 | # Environment specific Make files 69 | source/Makefile 70 | source/makefile.cfg 71 | -------------------------------------------------------------------------------- /BlackMagicProbe.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/BlackMagicProbe.pdf -------------------------------------------------------------------------------- /doc/blackmagicprobe-book.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/doc/blackmagicprobe-book.jpg -------------------------------------------------------------------------------- /doc/bmdebug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/doc/bmdebug.png -------------------------------------------------------------------------------- /doc/bmflash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/doc/bmflash.png -------------------------------------------------------------------------------- /doc/bmp-v23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/doc/bmp-v23.jpg -------------------------------------------------------------------------------- /doc/bmprofile-top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/doc/bmprofile-top.png -------------------------------------------------------------------------------- /doc/bmtrace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/doc/bmtrace.png -------------------------------------------------------------------------------- /examples/assert.c: -------------------------------------------------------------------------------- 1 | /* Implementation of assertions for ARM Cortex micro-controllers, based 2 | * on semihosting. 3 | * 4 | * Copyright 2020 CompuPhase 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 2. Altered source versions must be plainly marked as such, and must not be 19 | * misrepresented as being the original software. 20 | * 3. This notice may not be removed or altered from any source distribution. 21 | */ 22 | 23 | #include 24 | #include "assert.h" 25 | #include "semihosting.h" 26 | 27 | #ifndef NDEBUG 28 | 29 | #define __BKPT(value) __asm volatile ("bkpt "#value) 30 | 31 | __attribute__ ((always_inline)) static inline uint32_t __get_LR(void) 32 | { 33 | register uint32_t result; 34 | __asm volatile("mov %0, lr\n" : "=r" (result)); 35 | return result; 36 | } 37 | 38 | static void addr_to_string(uint32_t addr, char *str) 39 | { 40 | int i = sizeof(addr) * 2; /* always do 8 digits for a 32-bit value */ 41 | str[i]= '\0'; 42 | while (i > 0) { 43 | int digit = addr & 0x0f; 44 | str[--i] = (digit > 9) ? digit +('a' - 10) : digit + '0'; 45 | addr >>= 4; 46 | } 47 | } 48 | 49 | __attribute__ ((weak)) void assert_abort(void) 50 | { 51 | __BKPT(0); 52 | } 53 | 54 | void assert_fail(void) 55 | { 56 | register uint32_t addr = (__get_LR() & ~1) - 4; 57 | char buffer[] = "Assertion failed at *0x00000000\n"; 58 | addr_to_string(addr, buffer + 23); 59 | host_puts(STDERR, buffer); 60 | 61 | assert_abort(); 62 | } 63 | 64 | #endif /* NDEBUG */ 65 | -------------------------------------------------------------------------------- /examples/assert.h: -------------------------------------------------------------------------------- 1 | /* Implementation of assertions for ARM Cortex micro-controllers, based 2 | * on semihosting. 3 | * 4 | * Copyright 2020 CompuPhase 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 2. Altered source versions must be plainly marked as such, and must not be 19 | * misrepresented as being the original software. 20 | * 3. This notice may not be removed or altered from any source distribution. 21 | */ 22 | 23 | #ifndef __ASSERT_H 24 | #define __ASSERT_H 25 | 26 | #ifdef NDEBIG 27 | 28 | #define assert(condition) 29 | 30 | #else 31 | 32 | #define assert(condition) \ 33 | if (condition) \ 34 | {} \ 35 | else \ 36 | assert_fail() 37 | 38 | void assert_fail(void); 39 | 40 | #endif 41 | 42 | #endif /* __ASSERT_H */ 43 | -------------------------------------------------------------------------------- /examples/function_trace.c: -------------------------------------------------------------------------------- 1 | /* Example functions for function enter/exit tracing via GCC instrumentation. 2 | * It is based on SWO tracing, and should be used with the function_trace.tsdl 3 | * file. 4 | * 5 | * Routines for initializing the micro-controller for TRACESWO are not included, 6 | * as these are (in part) dependend on the particular micro-controller. 7 | * 8 | * 9 | * Copyright 2022 CompuPhase 10 | * 11 | * This software is provided 'as-is', without any express or implied 12 | * warranty. In no event will the authors be held liable for any damages 13 | * arising from the use of this software. 14 | * 15 | * Permission is granted to anyone to use this software for any purpose, 16 | * including commercial applications, and to alter it and redistribute it 17 | * freely, subject to the following restrictions: 18 | * 19 | * 1. The origin of this software must not be misrepresented; you must not 20 | * claim that you wrote the original software. If you use this software 21 | * in a product, an acknowledgment in the product documentation would be 22 | * appreciated but is not required. 23 | * 2. Altered source versions must be plainly marked as such, and must not be 24 | * misrepresented as being the original software. 25 | * 3. This notice may not be removed or altered from any source distribution. 26 | */ 27 | 28 | #include 29 | 30 | #if !defined ITM_TCR_ITMENA 31 | #define ITM_TCR_ITMENA ITM_TCR_ITMENA_Msk 32 | #endif 33 | 34 | __attribute__((no_instrument_function)) 35 | void trace_xmit(int stream_id, const unsigned char *data, unsigned size) 36 | { 37 | if ((ITM->TCR & ITM_TCR_ITMENA) != 0UL && /* ITM tracing enabled */ 38 | (ITM->TER & (1 << channel)) != 0UL) /* ITM channel enabled */ 39 | { 40 | /* collect and transmit bytes in packets of 4 bytes */ 41 | uint32_t value = 0, shift = 0; 42 | while (size-- > 0) { 43 | value |= (uint32_t)*data++ << shift; 44 | shift += 8; 45 | if (shift >= 32) { 46 | /* in the waiting loop, use an empty statement and not __NOP(); 47 | although __NOP() is an inline function, it would still be 48 | instrumented */ 49 | while (ITM->PORT[channel].u32 == 0UL) 50 | {} 51 | ITM->PORT[channel].u32 = value; 52 | value = shift = 0; 53 | } 54 | } 55 | /* transmit last collected bytes */ 56 | if (shift > 0) { 57 | while (ITM->PORT[channel].u32 == 0UL) 58 | {} 59 | ITM->PORT[channel].u32 = value; 60 | } 61 | } 62 | } 63 | 64 | __attribute__((no_instrument_function)) 65 | void __cyg_profile_func_enter(void *this_fn, void *call_site) 66 | { 67 | (void)call_site; 68 | trace_function_profile_enter((unsigned long)this_fn); 69 | } 70 | __attribute__((no_instrument_function)) 71 | void __cyg_profile_func_exit(void *this_fn, void *call_site) 72 | { 73 | (void)call_site; 74 | trace_function_profile_exit((unsigned long)this_fn); 75 | } 76 | 77 | -------------------------------------------------------------------------------- /examples/function_trace.tsdl: -------------------------------------------------------------------------------- 1 | /* TSDL file suitable for tracing function entries and exits. 2 | * 3 | * The source code must be compiled with GCC option -finstrument-functions. 4 | * The code must also supply a function trace_xmit(), as explained in the 5 | * book. An * important note is that trace_xmit() must be declared with 6 | * __attribute__((no_instrument_function)) 7 | */ 8 | trace { 9 | major = 1; 10 | minor = 8; 11 | packet.header := struct { 12 | uint16_t magic; 13 | }; 14 | }; 15 | 16 | stream function_profile { 17 | id = 31; 18 | event.header := struct { 19 | uint16_t id; 20 | }; 21 | }; 22 | 23 | typealias integer { 24 | size = 32; 25 | signed = false; 26 | base = symaddress; 27 | } := code_address; 28 | 29 | event function_profile::enter { 30 | attribute = "no_instrument_function"; 31 | fields := struct { 32 | code_address symbol; 33 | }; 34 | }; 35 | 36 | event function_profile::exit { 37 | attribute = "no_instrument_function"; 38 | fields := struct { 39 | code_address symbol; 40 | }; 41 | }; 42 | -------------------------------------------------------------------------------- /examples/semihosting.c: -------------------------------------------------------------------------------- 1 | /* Implementation of a simple semihosting interface (output only) for ARM Cortex 2 | * micro-controllers. This implementation is based on CMSIS, and restricted to 3 | * the semihosting calls supported by the Black Magic Probe. It is easily 4 | * adapted to libopencm3 or other micro-controller support libraries. Likewise, 5 | * it is easily extended with the few semihosting calls that the Black Magic 6 | * Probe does not support. 7 | * 8 | * Copyright 2020-2023 CompuPhase 9 | * 10 | * This software is provided 'as-is', without any express or implied 11 | * warranty. In no event will the authors be held liable for any damages 12 | * arising from the use of this software. 13 | * 14 | * Permission is granted to anyone to use this software for any purpose, 15 | * including commercial applications, and to alter it and redistribute it 16 | * freely, subject to the following restrictions: 17 | * 18 | * 1. The origin of this software must not be misrepresented; you must not 19 | * claim that you wrote the original software. If you use this software 20 | * in a product, an acknowledgment in the product documentation would be 21 | * appreciated but is not required. 22 | * 2. Altered source versions must be plainly marked as such, and must not be 23 | * misrepresented as being the original software. 24 | * 3. This notice may not be removed or altered from any source distribution. 25 | */ 26 | 27 | #include 28 | #include 29 | #include "semihosting.h" 30 | 31 | 32 | #if defined __ARM_ARCH && __ARM_ARCH == 6 33 | /* overrule HardFault handler for Cortex M0/M0+ 34 | for libopencm3: rename this function to hard_fault_handler */ 35 | __attribute__((naked)) 36 | void HardFault_Handler(void) 37 | { 38 | __asm__ ( 39 | "mov r0, #4\n" /* check bit 2 in LR */ 40 | "mov r1, lr\n" 41 | "tst r0, r1\n" 42 | "beq msp_stack\n" /* load either MSP or PSP in r0 */ 43 | "mrs r0, PSP\n" 44 | "b get_fault\n" 45 | "msp_stack:\n" 46 | "mrs r0, MSP\n" 47 | "get_fault:\n" 48 | "ldr r1, [r0,#24]\n" /* read program counter from the stack */ 49 | "ldrh r2, [r1]\n" /* read the instruction that caused the fault */ 50 | "ldr r3, =0xbeab\n" /* test for BKPT 0xAB (or 0xBEAB) */ 51 | "cmp r2, r3\n" 52 | "beq ignore\n" /* BKPT 0xAB found, ignore */ 53 | "b .\n" /* other reason for HardFault, infinite loop */ 54 | "ignore:\n" 55 | "add r1, #2\n" /* skip behind BKPT 0xAB */ 56 | "str r1, [r0,#24]\n" /* store this value on the stack */ 57 | "mov r0, #0 \n" /* set error code (r0 == -1) */ 58 | "sub r0, #1 \n" 59 | "bx lr" 60 | ); 61 | } 62 | #endif 63 | 64 | __attribute__((naked)) 65 | int semihosting(uint32_t command, void *params) 66 | { 67 | #if defined __ARM_ARCH && __ARM_ARCH == 7 68 | /* for Cortex M3/M4, test whether we are running under a debugger (for 69 | Cortex M0(+), the HardFault exception handler intercepts the call) */ 70 | # define CoreDebug_DHCSR *((uint32_t*)0xE000EDF0UL) 71 | if (CoreDebug_DHCSR & 1) { 72 | #endif 73 | 74 | __asm__ ( 75 | "mov r0, %0 \n" 76 | "mov r1, %1 \n" 77 | "bkpt #0xAB \n" 78 | "bx lr \n" 79 | : 80 | : "r" (command), "r" (params) 81 | : "r0", "r1", "memory" 82 | ); 83 | 84 | #if defined __ARM_ARCH && __ARM_ARCH == 7 85 | } 86 | #endif 87 | } 88 | 89 | int sys_open(const char *path, const char *mode) 90 | { 91 | uint32_t params[3] = { (uint32_t)path, 0, strlen(path) }; 92 | if (*mode == 'r') { 93 | mode++; 94 | } else if (*mode == 'w') { 95 | params[1] |= 0x04; 96 | mode++; 97 | } else if (*mode == 'a') { 98 | params[1] |= 0x08; 99 | mode++; 100 | } 101 | if (*mode == '+') { 102 | params[1] |= 0x02; 103 | mode++; 104 | } 105 | if (*mode == 'b') { 106 | params[1] |= 0x01; 107 | mode++; 108 | } 109 | return semihosting(SYS_OPEN, params); 110 | } 111 | 112 | int sys_close(int fd) 113 | { 114 | return semihosting(SYS_CLOSE, &fd); 115 | } 116 | 117 | void sys_writec(char c) 118 | { 119 | semihosting(SYS_WRITEC, &c); 120 | } 121 | 122 | void sys_write0(const char *text) 123 | { 124 | semihosting(SYS_WRITE0, (char*)text); 125 | } 126 | 127 | int sys_write(int fd, const unsigned char *buffer, size_t size) 128 | { 129 | uint32_t params[3] = { fd, (uint32_t)buffer, size }; 130 | return semihosting(SYS_WRITE, params); 131 | } 132 | 133 | int sys_read(int fd, char *buffer, size_t size) 134 | { 135 | uint32_t params[3] = { fd, (uint32_t)buffer, size }; 136 | return semihosting(SYS_READ, params); 137 | } 138 | 139 | int sys_readc(void) 140 | { 141 | return semihosting(SYS_READC, NULL); 142 | } 143 | 144 | int sys_iserror(uint32_t code) 145 | { 146 | return semihosting(SYS_ISERROR, &code); 147 | } 148 | 149 | int sys_istty(int fd) 150 | { 151 | return semihosting(SYS_ISTTY, &fd); 152 | } 153 | 154 | int sys_seek(int fd, size_t offset) 155 | { 156 | uint32_t params[2] = { fd, offset }; 157 | return semihosting(SYS_SEEK, params); 158 | } 159 | 160 | int sys_flen(int fd) 161 | { 162 | return semihosting(SYS_FLEN, &fd); 163 | } 164 | 165 | int sys_tmpnam(int id, char *buffer, size_t size) 166 | { 167 | uint32_t params[3] = { (uint32_t)buffer, (id & 0xff), size }; 168 | return semihosting(SYS_TMPNAM, params); 169 | } 170 | 171 | int sys_remove(const char *path) 172 | { 173 | uint32_t params[2] = { (uint32_t)path, strlen(path) }; 174 | return semihosting(SYS_REMOVE, params); 175 | } 176 | 177 | int sys_rename(const char *from, const char *to) 178 | { 179 | uint32_t params[4] = { (uint32_t)from, strlen(from), (uint32_t)to, strlen(to) }; 180 | return semihosting(SYS_RENAME, params); 181 | } 182 | 183 | int sys_clock(void) 184 | { 185 | return semihosting(SYS_CLOCK, NULL); 186 | } 187 | 188 | int sys_time(void) 189 | { 190 | return semihosting(SYS_TIME, NULL); 191 | } 192 | 193 | int sys_system(const char *command) 194 | { 195 | uint32_t params[2] = { (uint32_t)command, strlen(command) }; 196 | return semihosting(SYS_SYSTEM, params); 197 | } 198 | 199 | int sys_errno(void) 200 | { 201 | return semihosting(SYS_ERRNO, NULL); 202 | } 203 | 204 | void sys_get_cmdline(char *buffer, size_t size) 205 | { 206 | uint32_t params[2] = { (uint32_t)buffer, size }; 207 | semihosting(SYS_GET_CMDLINE, params); 208 | } 209 | 210 | void sys_heapinfo(struct heapinfo *info) 211 | { 212 | semihosting(SYS_HEAPINFO, &info); 213 | } 214 | 215 | void sys_exit(int trap) 216 | { 217 | semihosting(SYS_EXIT, (void*)trap); 218 | } 219 | 220 | void sys_exit_extended(int trap, int subcode) 221 | { 222 | uint32_t params[2] = { trap, subcode }; 223 | semihosting(SYS_EXIT_EXTENDED, params); 224 | } 225 | 226 | -------------------------------------------------------------------------------- /examples/traceswo.c: -------------------------------------------------------------------------------- 1 | /* Implementation of functions to transmit data or strings over the TRACESWO 2 | * wire of the ARM Cortex micro-controllers. 3 | * 4 | * These routines pack the bytes to transmit into 32-bit words, in order to 5 | * minimize overhead (each item that is transmitted over the TRACESWO pin is 6 | * prefixed with a 1-byte header, so that when tranmitting single bytes, each 7 | * byte has that 1-byte header overhead). 8 | * 9 | * Routines for initializing the micro-controller for TRACESWO are not included, 10 | * as these are (in part) dependend on the particular micro-controller. 11 | * 12 | * 13 | * Copyright 2020 CompuPhase 14 | * 15 | * This software is provided 'as-is', without any express or implied 16 | * warranty. In no event will the authors be held liable for any damages 17 | * arising from the use of this software. 18 | * 19 | * Permission is granted to anyone to use this software for any purpose, 20 | * including commercial applications, and to alter it and redistribute it 21 | * freely, subject to the following restrictions: 22 | * 23 | * 1. The origin of this software must not be misrepresented; you must not 24 | * claim that you wrote the original software. If you use this software 25 | * in a product, an acknowledgment in the product documentation would be 26 | * appreciated but is not required. 27 | * 2. Altered source versions must be plainly marked as such, and must not be 28 | * misrepresented as being the original software. 29 | * 3. This notice may not be removed or altered from any source distribution. 30 | */ 31 | 32 | #include 33 | #include 34 | #include "traceswo.h" 35 | 36 | void traceswo_sz(int channel, const char *msg) 37 | { 38 | traceswo_bin(channel, msg, strlen(msg)); 39 | } 40 | 41 | void traceswo_bin(int channel, const unsigned char *data, unsigned size) 42 | { 43 | if ((ITM->TCR & ITM_TCR_ITMENA) != 0UL && /* ITM tracing enabled */ 44 | (ITM->TER & (1 << channel)) != 0UL) /* ITM channel enabled */ 45 | { 46 | /* collect and transmit bytes in packets of 4 bytes */ 47 | uint32_t value = 0, shift = 0; 48 | while (size-- > 0) { 49 | value |= (uint32_t)*data++ << shift; 50 | shift += 8; 51 | if (shift >= 32) { 52 | while (ITM->PORT[channel].u32 == 0UL) 53 | __NOP(); 54 | ITM->PORT[channel].u32 = value; 55 | value = shift = 0; 56 | } 57 | } 58 | /* transmit last collected bytes */ 59 | if (shift > 0) { 60 | while (ITM->PORT[channel].u32 == 0UL) 61 | __NOP(); 62 | ITM->PORT[channel].u32 = value; 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /examples/traceswo.h: -------------------------------------------------------------------------------- 1 | /* Implementation of functions to transmit data or strings over the TRACESWO 2 | * wire of the ARM Cortex micro-controllers. 3 | * 4 | * These routines pack the bytes to * transmit into 32-bit words, in order to 5 | * minimize overhead (each item that is transmitted over the TRACESWO pin is 6 | * prefixed with a 1-byte header, so that when tranmitting single bytes, each 7 | * byte has that 1-byte header overhead). 8 | * 9 | * Routines for initializing the micro-controller for TRACESWO are not included, 10 | * as these are (in part) dependend on the particular micro-controller. 11 | * 12 | * 13 | * Copyright 2020 CompuPhase 14 | * 15 | * This software is provided 'as-is', without any express or implied 16 | * warranty. In no event will the authors be held liable for any damages 17 | * arising from the use of this software. 18 | * 19 | * Permission is granted to anyone to use this software for any purpose, 20 | * including commercial applications, and to alter it and redistribute it 21 | * freely, subject to the following restrictions: 22 | * 23 | * 1. The origin of this software must not be misrepresented; you must not 24 | * claim that you wrote the original software. If you use this software 25 | * in a product, an acknowledgment in the product documentation would be 26 | * appreciated but is not required. 27 | * 2. Altered source versions must be plainly marked as such, and must not be 28 | * misrepresented as being the original software. 29 | * 3. This notice may not be removed or altered from any source distribution. 30 | */ 31 | 32 | #ifndef __TRACESWO_H 33 | #define __TRACESWO_H 34 | 35 | /** traceswo_sz() transmits a zero-terminated string. This function is built 36 | * upon traceswo_bin(). 37 | * 38 | * \param channel The channel number (0..31). 39 | * \param msg A zero-terminated string. 40 | */ 41 | void traceswo_sz(int channel, const char *msg); 42 | 43 | /** traceswo_bin() transmits a buffer of data (which may contain embedded 44 | * zeros). The function trasmits four bytes at a time. If the size of the data 45 | * buffer is not a multiple of 4, the data is padded with zeros. 46 | * 47 | * \param channel The channel number (0..31). 48 | * \param data The buffer to transmit. The function transmits four bytes at 49 | * a time. 50 | * \param size The size of the data buffer. 51 | */ 52 | void traceswo_bin(int channel, const unsigned char *data, unsigned size); 53 | 54 | #endif /* __TRACESWO_H */ 55 | -------------------------------------------------------------------------------- /examples/traceswo_spi.c: -------------------------------------------------------------------------------- 1 | /* Implementation of functions to transmit data or strings to a debug probe 2 | * via a SPI. It emulates the Manchester protocol of SWO. This allows tracing 3 | * of Cortex M0/M0+ microcontrollers, which do not have TRACESWO support. 4 | * 5 | * These routines pack the bytes to transmit into 32-bit words, in order to 6 | * minimize overhead (each payload item is prefixed with a 1-byte header in the 7 | * SWO protocol and a payload item is 1 to 4 bytes). 8 | * 9 | * Routines for initializing the SPI peripheral of the micro-controller are not 10 | * included, as these are dependend on the particular micro-controller. In fact, 11 | * only the MOSI line is used (and connected to the debug probe); the SPI clock 12 | * line is not connected and neither are "slave select" and MISO lines. 13 | * 14 | * 15 | * Copyright 2020 CompuPhase 16 | * 17 | * This software is provided 'as-is', without any express or implied 18 | * warranty. In no event will the authors be held liable for any damages 19 | * arising from the use of this software. 20 | * 21 | * Permission is granted to anyone to use this software for any purpose, 22 | * including commercial applications, and to alter it and redistribute it 23 | * freely, subject to the following restrictions: 24 | * 25 | * 1. The origin of this software must not be misrepresented; you must not 26 | * claim that you wrote the original software. If you use this software 27 | * in a product, an acknowledgment in the product documentation would be 28 | * appreciated but is not required. 29 | * 2. Altered source versions must be plainly marked as such, and must not be 30 | * misrepresented as being the original software. 31 | * 3. This notice may not be removed or altered from any source distribution. 32 | */ 33 | 34 | #include 35 | #include 36 | #include "traceswo_spi.h" 37 | 38 | #define START 0x02 /* 0000 0010 (space for 3 periods, followed by a '1') */ 39 | #define SPACE 0x00 /* space code for at the end of a transfer */ 40 | 41 | static const uint8_t manchester_lookup[16] = { 42 | 0x55, /* 0000 -> 0101 0101 */ 43 | 0x95, /* 0001 -> 1001 0101 */ 44 | 0x65, /* 0010 -> 0110 0101 */ 45 | 0xa5, /* 0011 -> 1010 0101 */ 46 | 0x59, /* 0100 -> 0101 1001 */ 47 | 0x99, /* 0101 -> 1001 1001 */ 48 | 0x69, /* 0110 -> 0110 1001 */ 49 | 0xa9, /* 0111 -> 1010 1001 */ 50 | 0x56, /* 1000 -> 0101 0110 */ 51 | 0x96, /* 1001 -> 1001 0110 */ 52 | 0x66, /* 1010 -> 0110 0110 */ 53 | 0xa6, /* 1011 -> 1010 0110 */ 54 | 0x5a, /* 1100 -> 0101 1010 */ 55 | 0x9a, /* 1101 -> 1001 1010 */ 56 | 0x6a, /* 1110 -> 0110 1010 */ 57 | 0xaa, /* 1111 -> 1010 1010 */ 58 | }; 59 | 60 | #define M_EXPAND(buffer, byte) \ 61 | ( (buffer)[0] = manchester_lookup[(byte) & 0x0f], /* low bits */ \ 62 | (buffer)[1] = manchester_lookup[(uint8_t)(byte) >> 4] ) /* high bits */ 63 | 64 | uint32_t TRACESWO_TER = 0; 65 | 66 | uint32_t traceswo_enable(uint32_t channelmask, int enable) 67 | { 68 | if (enable) 69 | TRACESWO_TER |= channelmask; 70 | else 71 | TRACESWO_TER &= ~channelmask; 72 | return TRACESWO_TER; 73 | } 74 | 75 | void traceswo_sz(int channel, const char *msg) 76 | { 77 | traceswo_bin(channel, (const unsigned char*)msg, strlen(msg)); 78 | } 79 | 80 | void traceswo_bin(int channel, const unsigned char *data, unsigned size) 81 | { 82 | if (TRACESWO_TER & (1 << channel)) { /* if channel is enabled */ 83 | uint8_t buffer[12], hdr; 84 | while (size >= 4) { 85 | hdr = (channel << 3) | 3; 86 | buffer[0] = START; 87 | M_EXPAND(buffer + 1, hdr); 88 | M_EXPAND(buffer + 3, data[0]); 89 | M_EXPAND(buffer + 5, data[1]); 90 | M_EXPAND(buffer + 7, data[2]); 91 | M_EXPAND(buffer + 9, data[3]); 92 | buffer[11] = SPACE; 93 | __disable_irq(); 94 | ARM_SPI_Send(buffer, 11 + (size == 4)); 95 | __enable_irq(); 96 | data += 4; 97 | size -= 4; 98 | } 99 | if (size >= 2) { 100 | hdr = (channel << 3) | 2; 101 | buffer[0] = START; 102 | M_EXPAND(buffer + 1, hdr); 103 | M_EXPAND(buffer + 3, data[0]); 104 | M_EXPAND(buffer + 5, data[1]); 105 | buffer[7] = SPACE; 106 | __disable_irq(); 107 | ARM_SPI_Send(buffer, 7 + (size == 2)); 108 | __enable_irq(); 109 | data += 2; 110 | size -= 2; 111 | } 112 | if (size >= 1) { 113 | hdr = (channel << 3) | 1; 114 | buffer[0] = START; 115 | M_EXPAND(buffer + 1, hdr); 116 | M_EXPAND(buffer + 3, data[0]); 117 | buffer[5] = SPACE; 118 | __disable_irq(); 119 | ARM_SPI_Send(buffer, 6); 120 | __enable_irq(); 121 | } 122 | } 123 | } 124 | 125 | -------------------------------------------------------------------------------- /examples/traceswo_spi.h: -------------------------------------------------------------------------------- 1 | /* Implementation of functions to transmit data or strings to a debug probe 2 | * via a SPI. It emulates the Manchester protocol of SWO. This allows tracing 3 | * of Cortex M0/M0+ microcontrollers, which do not have TRACESWO support. 4 | * 5 | * These routines pack the bytes to transmit into 32-bit words, in order to 6 | * minimize overhead (each payload item is prefixed with a 1-byte header in the 7 | * SWO protocol and a payload item is 1 to 4 bytes). 8 | * 9 | * Routines for initializing the SPI peripheral of the micro-controller are not 10 | * included, as these are dependend on the particular micro-controller. 11 | * 12 | * 13 | * Copyright 2020 CompuPhase 14 | * 15 | * This software is provided 'as-is', without any express or implied 16 | * warranty. In no event will the authors be held liable for any damages 17 | * arising from the use of this software. 18 | * 19 | * Permission is granted to anyone to use this software for any purpose, 20 | * including commercial applications, and to alter it and redistribute it 21 | * freely, subject to the following restrictions: 22 | * 23 | * 1. The origin of this software must not be misrepresented; you must not 24 | * claim that you wrote the original software. If you use this software 25 | * in a product, an acknowledgment in the product documentation would be 26 | * appreciated but is not required. 27 | * 2. Altered source versions must be plainly marked as such, and must not be 28 | * misrepresented as being the original software. 29 | * 3. This notice may not be removed or altered from any source distribution. 30 | */ 31 | 32 | #ifndef __TRACESWO_H 33 | #define __TRACESWO_H 34 | 35 | /** traceswo_enable() allows you to enable or disable any of the 32 channels. 36 | * 37 | * \param channelmask A bit mask. Set the bits for the channels that you wish 38 | * to enabe or disable. Zero bits in the mask have no 39 | * effect. 40 | * \param enable If non-zero, the channels in the mask are enabled; if 41 | * zero, the channels in the mask are disabled. 42 | * 43 | * \return The updated channel mask. 44 | * 45 | * \note To read the current channel mask without changing it, call this 46 | * function with "channelmask" set to zero (the value of the "enable" 47 | * parameter does not matter if the mask is zero). 48 | */ 49 | uint32_t traceswo_enable(uint32_t channelmask, int enable); 50 | 51 | /** traceswo_sz() transmits a zero-terminated string. This function is built 52 | * upon traceswo_bin(). 53 | * 54 | * \param channel The channel number (0..31). 55 | * \param msg A zero-terminated string. 56 | */ 57 | void traceswo_sz(int channel, const char *msg); 58 | 59 | /** traceswo_bin() transmits a buffer of data (which may contain embedded 60 | * zeros). The function trasmits four bytes at a time. If the size of the data 61 | * buffer is not a multiple of 4, the data is padded with zeros. 62 | * 63 | * \param channel The channel number (0..31). 64 | * \param data The buffer to transmit. The function transmits four bytes at 65 | * a time. 66 | * \param size The size of the data buffer. 67 | */ 68 | void traceswo_bin(int channel, const unsigned char *data, unsigned size); 69 | 70 | #endif /* __TRACESWO_H */ 71 | -------------------------------------------------------------------------------- /examples/traceswo_uart.c: -------------------------------------------------------------------------------- 1 | /* Implementation of functions to transmit data or strings to a debug probe 2 | * via a UART (or USART). The UART emulates the NRZ protocol of SWO. This allows 3 | * tracing of Cortex M0/M0+ microcontrollers, which do not have TRACESWO 4 | * support. 5 | * 6 | * These routines pack the bytes to transmit into 32-bit words, in order to 7 | * minimize overhead (each payload item is prefixed with a 1-byte header in the 8 | * SWO protocol and a payload item is 1 to 4 bytes). 9 | * 10 | * Routines for initializing the UART/USART of the micro-controller are not 11 | * included, as these are dependend on the particular micro-controller. The 12 | * functions rely on ARM_USART_Send() to do the actual transmission; this is 13 | * the CMSIS name (you may need to change it for other USART driver libraries). 14 | * 15 | * 16 | * Copyright 2020 CompuPhase 17 | * 18 | * This software is provided 'as-is', without any express or implied 19 | * warranty. In no event will the authors be held liable for any damages 20 | * arising from the use of this software. 21 | * 22 | * Permission is granted to anyone to use this software for any purpose, 23 | * including commercial applications, and to alter it and redistribute it 24 | * freely, subject to the following restrictions: 25 | * 26 | * 1. The origin of this software must not be misrepresented; you must not 27 | * claim that you wrote the original software. If you use this software 28 | * in a product, an acknowledgment in the product documentation would be 29 | * appreciated but is not required. 30 | * 2. Altered source versions must be plainly marked as such, and must not be 31 | * misrepresented as being the original software. 32 | * 3. This notice may not be removed or altered from any source distribution. 33 | */ 34 | 35 | #include 36 | #include 37 | #include "traceswo_uart.h" 38 | 39 | uint32_t TRACESWO_TER = 0; 40 | uint32_t TRACESWO_BPS = 0; 41 | 42 | uint32_t traceswo_enable(uint32_t channelmask, int enable) 43 | { 44 | if (enable) 45 | TRACESWO_TER |= channelmask; 46 | else 47 | TRACESWO_TER &= ~channelmask; 48 | return TRACESWO_TER; 49 | } 50 | 51 | void traceswo_sz(int channel, const char *msg) 52 | { 53 | traceswo_bin(channel, (const unsigned char*)msg, strlen(msg)); 54 | } 55 | 56 | void traceswo_bin(int channel, const unsigned char *data, unsigned size) 57 | { 58 | if (TRACESWO_TER & (1 << channel)) { /* if channel is enabled */ 59 | uint8_t header; 60 | while (size >= 4) { 61 | header = (channel << 3) | 3; 62 | ARM_USART_Send(&header, 1); 63 | ARM_USART_Send(data, 4); 64 | data += 4; 65 | size -= 4; 66 | } 67 | if (size >= 2) { 68 | header = (channel << 3) | 2; 69 | ARM_USART_Send(&header, 1); 70 | ARM_USART_Send(data, 2); 71 | data += 2; 72 | size -= 2; 73 | } 74 | if (size >= 1) { 75 | header = (channel << 3) | 1; 76 | ARM_USART_Send(&header, 1); 77 | ARM_USART_Send(data, 1); 78 | } 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /examples/traceswo_uart.h: -------------------------------------------------------------------------------- 1 | /* Implementation of functions to transmit data or strings to a debug probe 2 | * via a UART (or USART). The UART emulates the NRZ protocol of SWO. This allows 3 | * tracing of Cortex M0/M0+ microcontrollers, which do not have TRACESWO 4 | * support. 5 | * 6 | * These routines pack the bytes to transmit into 32-bit words, in order to 7 | * minimize overhead (each payload item is prefixed with a 1-byte header in the 8 | * SWO protocol and a payload item is 1 to 4 bytes). 9 | * 10 | * Routines for initializing the UART/USART of the micro-controller are not 11 | * included, as these are dependend on the particular micro-controller. The 12 | * functions rely on ARM_USART_Send() to do the actual transmission; this is 13 | * the CMSIS name (you may need to change it for other USART driver libraries). 14 | * 15 | * 16 | * Copyright 2020 CompuPhase 17 | * 18 | * This software is provided 'as-is', without any express or implied 19 | * warranty. In no event will the authors be held liable for any damages 20 | * arising from the use of this software. 21 | * 22 | * Permission is granted to anyone to use this software for any purpose, 23 | * including commercial applications, and to alter it and redistribute it 24 | * freely, subject to the following restrictions: 25 | * 26 | * 1. The origin of this software must not be misrepresented; you must not 27 | * claim that you wrote the original software. If you use this software 28 | * in a product, an acknowledgment in the product documentation would be 29 | * appreciated but is not required. 30 | * 2. Altered source versions must be plainly marked as such, and must not be 31 | * misrepresented as being the original software. 32 | * 3. This notice may not be removed or altered from any source distribution. 33 | */ 34 | 35 | #ifndef __TRACESWO_H 36 | #define __TRACESWO_H 37 | 38 | /** traceswo_enable() allows you to enable or disable any of the 32 channels. 39 | * 40 | * \param channelmask A bit mask. Set the bits for the channels that you wish 41 | * to enabe or disable. Zero bits in the mask have no 42 | * effect. 43 | * \param enable If non-zero, the channels in the mask are enabled; if 44 | * zero, the channels in the mask are disabled. 45 | * 46 | * \return The updated channel mask. 47 | * 48 | * \note To read the current channel mask without changing it, call this 49 | * function with "channelmask" set to zero (the value of the "enable" 50 | * parameter does not matter if the mask is zero). 51 | */ 52 | uint32_t traceswo_enable(uint32_t channelmask, int enable); 53 | 54 | /** traceswo_sz() transmits a zero-terminated string. This function is built 55 | * upon traceswo_bin(). 56 | * 57 | * \param channel The channel number (0..31). 58 | * \param msg A zero-terminated string. 59 | */ 60 | void traceswo_sz(int channel, const char *msg); 61 | 62 | /** traceswo_bin() transmits a buffer of data (which may contain embedded 63 | * zeros). The function trasmits four bytes at a time. If the size of the data 64 | * buffer is not a multiple of 4, the data is padded with zeros. 65 | * 66 | * \param channel The channel number (0..31). 67 | * \param data The buffer to transmit. The function transmits four bytes at 68 | * a time. 69 | * \param size The size of the data buffer. 70 | */ 71 | void traceswo_bin(int channel, const unsigned char *data, unsigned size); 72 | 73 | #endif /* __TRACESWO_H */ 74 | -------------------------------------------------------------------------------- /source/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch bmdebug.exe", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/bmdebug.exe", 12 | "args": [], 13 | "stopAtEntry": true, 14 | "cwd": "${workspaceFolder}", 15 | "environment": [], 16 | "externalConsole": false, 17 | "MIMode": "gdb", 18 | "miDebuggerPath": "gdb.exe", 19 | "setupCommands": [ 20 | { 21 | "description": "Enable pretty-printing for gdb", 22 | "text": "-enable-pretty-printing", 23 | "ignoreFailures": true 24 | } 25 | ] 26 | }, 27 | { 28 | "name": "Linux bmdebug", 29 | "type": "cppdbg", 30 | "request": "launch", 31 | "program": "${workspaceFolder}/bmdebug", 32 | "args": [], 33 | "stopAtEntry": true, 34 | "cwd": "${workspaceFolder}", 35 | "environment": [], 36 | "externalConsole": false, 37 | "MIMode": "gdb", 38 | "miDebuggerPath": "gdb", 39 | "setupCommands": [ 40 | { 41 | "description": "Enable pretty-printing for gdb", 42 | "text": "-enable-pretty-printing", 43 | "ignoreFailures": true 44 | } 45 | ] 46 | }, 47 | { 48 | "name": "Launch bmtrace.exe", 49 | "type": "cppdbg", 50 | "request": "launch", 51 | "program": "${workspaceFolder}/bmtrace.exe", 52 | "args": [], 53 | "stopAtEntry": true, 54 | "cwd": "${workspaceFolder}", 55 | "environment": [], 56 | "externalConsole": false, 57 | "MIMode": "gdb", 58 | "miDebuggerPath": "gdb.exe", 59 | "setupCommands": [ 60 | { 61 | "description": "Enable pretty-printing for gdb", 62 | "text": "-enable-pretty-printing", 63 | "ignoreFailures": true 64 | } 65 | ] 66 | } 67 | ] 68 | } -------------------------------------------------------------------------------- /source/armdisasm.h: -------------------------------------------------------------------------------- 1 | /* ARM instruction decoder (disassembler) 2 | * Covers Thumb and Thumb2 (for Cortex-M series) 3 | * 4 | * Copyright 2022-2023, CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _ARMDISASM_H 19 | #define _ARMDISASM_H 20 | 21 | #include 22 | #include 23 | 24 | typedef struct { 25 | const char *name; 26 | uint32_t address; 27 | int mode; /**< ARM mode, Thumb mode, or data */ 28 | } ARMSYMBOL; 29 | 30 | typedef struct { 31 | uint32_t address; /**< start of the block */ 32 | uint16_t size; /**< size of the block (or zero if unknown) */ 33 | uint16_t type; /**< code, literal pool */ 34 | } ARMPOOL; 35 | 36 | typedef struct { 37 | char text[128]; /**< decoded instruction (optionally prefixed with address/hex values) */ 38 | uint32_t address; /**< address (used for branch labels) */ 39 | uint16_t size; /**< size of the instruction in bytes */ 40 | 41 | uint8_t arm_mode; /**< 1 for ARM mode, 0 for Thumb */ 42 | uint8_t add_addr; /**< option: prefix decoded instructions with the address */ 43 | uint8_t add_bin; /**< option: prefix decoded instructions with the hex code */ 44 | uint8_t add_cmt; /**< option: add comments with symbols or extra information */ 45 | 46 | uint16_t it_mask; /**< forward carried state for if-then instructions */ 47 | uint16_t it_cond; 48 | 49 | uint32_t ldr_addr; /**< target address of recent literal load, or ~0 if none */ 50 | 51 | ARMSYMBOL *symbols; /**< list of functions */ 52 | int symbolcount; /**< number of valid entries in the symbol list */ 53 | int symbolsize; /**< number of allocated entries in the symbol list */ 54 | 55 | ARMPOOL *codepool; /**< list of addresses with type */ 56 | int poolcount; /**< number of valid entries in the code map */ 57 | int poolsize; /**< number of allocated entries in the code map */ 58 | } ARMSTATE; 59 | 60 | #define DISASM_ADDRESS 0x0001 /**< prefix decoded instructions with the address */ 61 | #define DISASM_INSTR 0x0002 /**< prefix encoded values (hex) to the decoded instructions */ 62 | #define DISASM_COMMENT 0x0004 /**< for immediate values, add hex notation in a comment */ 63 | 64 | void disasm_init(ARMSTATE *state, int flags); 65 | void disasm_cleanup(ARMSTATE *state); 66 | 67 | void disasm_clear_codepool(ARMSTATE *state); 68 | void disasm_compact_codepool(ARMSTATE *state, uint32_t address, uint32_t size); 69 | 70 | enum { 71 | ARMMODE_UNKNOWN, /**< unknown mode for the symbol */ 72 | ARMMODE_ARM, /**< this symbol refers to code in ARM mode (function) */ 73 | ARMMODE_THUMB, /**< this symbol refers to code in Thumb mode (function) */ 74 | ARMMODE_DATA, /**< this symbol refers to a data object */ 75 | }; 76 | void disasm_symbol(ARMSTATE *state, const char *name, uint32_t address, int mode); 77 | void disasm_address(ARMSTATE *state, uint32_t address); 78 | 79 | bool disasm_thumb(ARMSTATE *state, uint16_t hw, uint16_t hw2); 80 | bool disasm_arm(ARMSTATE *state, uint32_t w); 81 | const char *disasm_result(ARMSTATE *state, int *size); 82 | 83 | typedef bool (*DISASM_CALLBACK)(uint32_t address, const char *text, void *user); 84 | bool disasm_buffer(ARMSTATE *state, const unsigned char *buffer, size_t buffersize, 85 | int mode, DISASM_CALLBACK callback, void *user); 86 | 87 | #endif /* _ARMDISASM_H */ 88 | 89 | -------------------------------------------------------------------------------- /source/bmcommon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Common functions for bmdebug, bmflash, bmprofile and bmtrace. 3 | * 4 | * Copyright 2021-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #if defined WIN32 || defined _WIN32 23 | # include 24 | # if defined __MINGW32__ || defined __MINGW64__ || defined _MSC_VER 25 | # include "strlcpy.h" 26 | # endif 27 | # if defined _MSC_VER 28 | # define strdup(s) _strdup(s) 29 | # define mkdir(p) _mkdir(p) 30 | # endif 31 | #elif defined __linux__ 32 | # include 33 | # include 34 | # include 35 | #endif 36 | #include "bmcommon.h" 37 | #include "bmp-scan.h" 38 | #include "specialfolder.h" 39 | 40 | #if defined FORTIFY 41 | # include 42 | #endif 43 | 44 | #if !defined sizearray 45 | # define sizearray(e) (sizeof(e) / sizeof((e)[0])) 46 | #endif 47 | 48 | const char **get_probelist(int *probe, int *netprobe) 49 | { 50 | int usbprobes = get_bmp_count(); 51 | assert(netprobe != NULL); 52 | *netprobe = (usbprobes > 0) ? usbprobes : 1; 53 | 54 | const char **probelist = malloc((*netprobe+1)*sizeof(char*)); 55 | if (probelist != NULL) { 56 | if (usbprobes == 0) { 57 | probelist[0] = strdup("-"); 58 | } else { 59 | for (int idx = 0; idx < usbprobes; idx++) { 60 | char portname[64]; 61 | find_bmp(idx, BMP_IF_GDB, portname, sizearray(portname)); 62 | probelist[idx] = strdup(portname); 63 | } 64 | } 65 | probelist[*netprobe] = strdup("TCP/IP"); 66 | } 67 | 68 | assert(probe != NULL); 69 | if (*probe == 99) 70 | *probe = *netprobe; 71 | else if (*probe > usbprobes) 72 | *probe = 0; 73 | 74 | return probelist; 75 | } 76 | 77 | void clear_probelist(const char **probelist, int netprobe) 78 | { 79 | if (probelist != NULL) { 80 | assert(netprobe >= 0); 81 | for (int idx = 0; idx < netprobe + 1; idx++) 82 | free((void*)probelist[idx]); 83 | free((void*)probelist); 84 | } 85 | } 86 | 87 | bool get_configfile(char *filename, size_t maxsize, const char *basename) 88 | { 89 | assert(filename != NULL); 90 | assert(maxsize > 0); 91 | *filename = '\0'; 92 | if (!folder_AppConfig(filename, maxsize)) 93 | return false; 94 | 95 | strlcat(filename, DIR_SEPARATOR "BlackMagic", maxsize); 96 | # if defined _WIN32 97 | mkdir(filename); 98 | # else 99 | mkdir(filename, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 100 | # endif 101 | strlcat(filename, DIR_SEPARATOR, maxsize); 102 | strlcat(filename, basename, maxsize); 103 | return true; 104 | } 105 | 106 | -------------------------------------------------------------------------------- /source/bmcommon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Common functions for bmdebug, bmflash, bmprofile and bmtrace. 3 | * 4 | * Copyright 2021-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _BMCOMMON_H 19 | #define _BMCOMMON_H 20 | 21 | const char **get_probelist(int *probe, int *netprobe); 22 | void clear_probelist(const char **probelist, int netprobe); 23 | 24 | bool get_configfile(char *filename, size_t maxsize, const char *basename); 25 | 26 | #endif /* _BMCOMMON_H */ 27 | -------------------------------------------------------------------------------- /source/bmdebug.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * GDB front-end with specific support for the Black Magic Probe. 3 | * This utility is built with Nuklear for a cross-platform GUI. 4 | * 5 | * Copyright 2019-2023 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #include 21 | #include 22 | #include "svnrev.h" 23 | 24 | AppIcon ICON "res/icon_debug.ico" 25 | 26 | /* Version information 27 | * 28 | * All strings MUST have an explicit \0. See the Windows SDK documentation 29 | * for details on version information and the VERSIONINFO structure. 30 | */ 31 | #define VERSION 1 32 | #define REVISION 2 33 | #define BUILD SVNREV_NUM 34 | #define VERSIONSTR SVNREV_STR 35 | #define VERSIONNAME "bmdebug.exe\0" 36 | #define VERSIONDESCRIPTION "BMDebug: GDB front-end\0" 37 | #define VERSIONCOMPANYNAME "CompuPhase\0" 38 | #define VERSIONPRODUCTNAME "bmdebug\0" 39 | #define VERSIONCOPYRIGHT "Copyright \251 CompuPhase 2019-2022\0" 40 | 41 | VS_VERSION_INFO VERSIONINFO 42 | FILEVERSION VERSION, REVISION, BUILD, 0 43 | PRODUCTVERSION VERSION, REVISION, BUILD, 0 44 | FILEFLAGSMASK 0x0000003FL 45 | FILEFLAGS 0 46 | #if defined(WIN32) 47 | FILEOS VOS__WINDOWS32 48 | #else 49 | FILEOS VOS__WINDOWS16 50 | #endif 51 | FILETYPE VFT_APP 52 | BEGIN 53 | BLOCK "StringFileInfo" 54 | BEGIN 55 | BLOCK "040904E4" 56 | BEGIN 57 | VALUE "CompanyName", VERSIONCOMPANYNAME 58 | VALUE "FileDescription", VERSIONDESCRIPTION 59 | VALUE "FileVersion", VERSIONSTR 60 | VALUE "InternalName", VERSIONNAME 61 | VALUE "LegalCopyright", VERSIONCOPYRIGHT 62 | VALUE "OriginalFilename", VERSIONNAME 63 | VALUE "ProductName", VERSIONPRODUCTNAME 64 | VALUE "ProductVersion", VERSIONSTR 65 | END 66 | END 67 | 68 | BLOCK "VarFileInfo" 69 | BEGIN 70 | VALUE "Translation", 0x409, 1252 71 | END 72 | END 73 | 74 | -------------------------------------------------------------------------------- /source/bmflash.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * Utility to download executable programs to the target micro-controller via 3 | * the Black Magic Probe on a system. This utility is built with Nuklear for a 4 | * cross-platform GUI. 5 | * 6 | * Copyright 2019-2023 CompuPhase 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #include 22 | #include 23 | #include "svnrev.h" 24 | 25 | AppIcon ICON "res/icon_download.ico" 26 | 27 | /* Version information 28 | * 29 | * All strings MUST have an explicit \0. See the Windows SDK documentation 30 | * for details on version information and the VERSIONINFO structure. 31 | */ 32 | #define VERSION 1 33 | #define REVISION 2 34 | #define BUILD SVNREV_NUM 35 | #define VERSIONSTR SVNREV_STR 36 | #define VERSIONNAME "bmflash.exe\0" 37 | #define VERSIONDESCRIPTION "BMFlash: Flash programming tool\0" 38 | #define VERSIONCOMPANYNAME "CompuPhase\0" 39 | #define VERSIONPRODUCTNAME "bmflash\0" 40 | #define VERSIONCOPYRIGHT "Copyright \251 CompuPhase 2019-2022\0" 41 | 42 | VS_VERSION_INFO VERSIONINFO 43 | FILEVERSION VERSION, REVISION, BUILD, 0 44 | PRODUCTVERSION VERSION, REVISION, BUILD, 0 45 | FILEFLAGSMASK 0x0000003FL 46 | FILEFLAGS 0 47 | #if defined(WIN32) 48 | FILEOS VOS__WINDOWS32 49 | #else 50 | FILEOS VOS__WINDOWS16 51 | #endif 52 | FILETYPE VFT_APP 53 | BEGIN 54 | BLOCK "StringFileInfo" 55 | BEGIN 56 | BLOCK "040904E4" 57 | BEGIN 58 | VALUE "CompanyName", VERSIONCOMPANYNAME 59 | VALUE "FileDescription", VERSIONDESCRIPTION 60 | VALUE "FileVersion", VERSIONSTR 61 | VALUE "InternalName", VERSIONNAME 62 | VALUE "LegalCopyright", VERSIONCOPYRIGHT 63 | VALUE "OriginalFilename", VERSIONNAME 64 | VALUE "ProductName", VERSIONPRODUCTNAME 65 | VALUE "ProductVersion", VERSIONSTR 66 | END 67 | END 68 | 69 | BLOCK "VarFileInfo" 70 | BEGIN 71 | VALUE "Translation", 0x409, 1252 72 | END 73 | END 74 | 75 | -------------------------------------------------------------------------------- /source/bmp-scan.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Utility functions to scan for the Black Magic Probe on a system, and return 3 | * the (virtual) serial ports that it is assigned to. Under Microsoft Windows, 4 | * it scans the registry for the Black Magic Probe device, under Linux, it 5 | * browses through sysfs. 6 | * 7 | * Copyright 2019-2024 CompuPhase 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | #ifndef _BMP_SCAN_H 22 | #define _BMP_SCAN_H 23 | 24 | #if defined __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define BMP_VID 0x1d50 29 | #define BMP_PID 0x6018 30 | #define BMP_PID_DFU 0x6017/* legacy versions, current version has DFU as an interface */ 31 | #define BMP_IF_GDB 0 /* interface 0 -> GDB server */ 32 | #define BMP_IF_UART 2 /* interface 2 -> 3.3V TTL UART */ 33 | #define BMP_IF_DFU 4 34 | #define BMP_IF_TRACE 5 35 | #define BMP_EP_TRACE 0x85 /* endpoint 5 is bulk data endpoint for trace interface on the original BMP; may be overruled */ 36 | 37 | #define BMP_IF_SERIAL 9 /* pseudo-interface for getting the serial number */ 38 | 39 | #define BMP_PORT_GDB 2159 /* TCP/IP port for gdbserver */ 40 | #define BMP_PORT_UART 2160 /* TCP/IP port for 3.3V TTL UART */ 41 | #define BMP_PORT_TRACE 2161 /* TCP/IP port for SWO trace */ 42 | 43 | enum { 44 | PROBE_UNKNOWN, 45 | PROBE_BMPv21, /* original BMP, hardware revision 3 */ 46 | PROBE_BMPv23, /* original BMP, hardware revision 6 */ 47 | PROBE_CTXLINK, /* ctxLink */ 48 | }; 49 | 50 | /* find_bmp() returns 1 on success and 0 on failure; the interface must be either 51 | BMP_IF_GDB, BMP_IF_UART or BMP_IF_TRACE (or BMP_IF_SERIAL to get the serial 52 | number of the attached Black Magic Probe) */ 53 | #if defined WIN32 || defined _WIN32 54 | #include 55 | int find_bmp(int seqnr, int iface, TCHAR *name, size_t namelen); 56 | #else 57 | int find_bmp(int seqnr, int iface, char *name, size_t namelen); 58 | #endif 59 | 60 | /* get_bmp_count() returns the number of detected probes (only probes on the 61 | USB port are detected) */ 62 | int get_bmp_count(void); 63 | 64 | /* check_versionstring() checks whether a string gives some indication on the 65 | exact type of probe; the input strings ought to be strings return by the 66 | "monitor version" command */ 67 | int check_versionstring(const char *string); 68 | 69 | /* scan_network() scans the network for TCP/IP connected gdbservers */ 70 | int scan_network(unsigned long *addresses, int address_count); 71 | 72 | #if defined __cplusplus 73 | } 74 | #endif 75 | 76 | #endif /* _BMP_SCAN_H */ 77 | -------------------------------------------------------------------------------- /source/bmp-script.h: -------------------------------------------------------------------------------- 1 | /* 2 | * General purpose "script" support for the Black Magic Probe, so that it can 3 | * automatically handle device-specific settings. It can use the GDB-RSP serial 4 | * interface, or the GDB-MI console interface. 5 | * 6 | * Copyright 2019-2023 CompuPhase 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | #ifndef _BMP_SCRIPT_H 21 | #define _BMP_SCRIPT_H 22 | 23 | #include 24 | 25 | #if defined __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | enum { 30 | OT_LITERAL, 31 | OT_ADDRESS, 32 | OT_PARAM, 33 | }; 34 | typedef struct tagOPERAND { 35 | uint32_t data; /* register or memory address, literal value, or parameter index */ 36 | uint8_t type; /* one of the OT_xxx values */ 37 | uint8_t size; /* operand size in bytes */ 38 | uint8_t pshift; /* for parameters: shift-left of parameter value */ 39 | uint32_t plit; /* for parameters: literal value added to parameter value */ 40 | } OPERAND; 41 | 42 | enum { 43 | OP_MOV, /* a = b */ 44 | OP_ORR, /* a |= b */ 45 | OP_AND, /* a &= b */ 46 | OP_AND_INV, /* a &= ~b */ 47 | }; 48 | 49 | int bmscript_load(const char *mcu, const char *architecture); 50 | void bmscript_clear(void); 51 | void bmscript_clearcache(void); 52 | 53 | bool bmscript_line(const char *name, uint16_t *oper, OPERAND *lvalue, OPERAND *rvalue); 54 | bool bmscript_line_fmt(const char *name, char *line, const unsigned long *params, size_t paramcount); 55 | 56 | int architecture_match(const char *architecture, const char *mcufamily); 57 | 58 | #if defined __cplusplus 59 | } 60 | #endif 61 | 62 | #endif /* _BMP_SCRIPT_H */ 63 | 64 | -------------------------------------------------------------------------------- /source/bmp-support.h: -------------------------------------------------------------------------------- 1 | /* 2 | * General purpose Black Magic Probe support routines, based on the GDB-RSP 3 | * serial interface. 4 | * 5 | * Copyright 2019-2023 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _BMP_SUPPORT_H 20 | #define _BMP_SUPPORT_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include "rs232.h" 26 | 27 | #if defined __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | enum { 32 | BMPSTAT_NOTICE = 0, 33 | BMPSTAT_SUCCESS = 1, 34 | 35 | BMPERR_PORTACCESS = -1, /* cannot access/open serial port */ 36 | BMPERR_NODETECT = -2, /* no BMP detected */ 37 | BMPERR_NORESPONSE = -3, /* no response on serial port */ 38 | BMPERR_NOCONNECT = -4, /* connection to BMP failed */ 39 | BMPERR_MONITORCMD = -5, /* "monitor" command failed */ 40 | BMPERR_ATTACHFAIL = -6, /* "attach" failed */ 41 | BMPERR_MEMALLOC = -7, /* memory allocation error */ 42 | BMPERR_NOFLASH = -8, /* no records of Flash memory */ 43 | BMPERR_FLASHERASE = -9, /* Flash erase failed */ 44 | BMPERR_FLASHREAD = -10,/* Flash read error */ 45 | BMPERR_FLASHWRITE = -11,/* Flash write failed */ 46 | BMPERR_FLASHDONE = -12,/* Flash programming completion failed */ 47 | BMPERR_FLASHCRC = -13,/* Flash CRC verification failed */ 48 | BMPERR_NOFILEDATA = -14,/* no file in memory for download/verify */ 49 | BMPERR_GENERAL = -15, 50 | }; 51 | 52 | int bmp_flashtotal(unsigned long *low_addr, unsigned long *high_addr); 53 | 54 | typedef int (*BMP_STATCALLBACK)(int code, const char *message); 55 | void bmp_setcallback(BMP_STATCALLBACK func); 56 | 57 | bool bmp_connect(int probe, const char *ipaddress); 58 | bool bmp_disconnect(void); 59 | bool bmp_isopen(void); 60 | void bmp_sethandle(HCOM *hcom); 61 | HCOM *bmp_comport(void); 62 | 63 | int bmp_is_ip_address(const char *address); 64 | int bmp_checkversionstring(void); 65 | uint32_t bmp_get_partid(void); 66 | const char *bmp_get_monitor_cmds(void); 67 | bool bmp_has_command(const char *name, const char *list); 68 | bool bmp_expand_monitor_cmd(char *buffer, size_t bufsize, const char *name, const char *list); 69 | 70 | bool bmp_attach(bool autopower, char *name, size_t namelength, char *arch, size_t archlength); 71 | bool bmp_detach(bool powerdown); 72 | 73 | bool bmp_monitor(const char *command); 74 | bool bmp_download(void); 75 | bool bmp_verify(void); 76 | bool bmp_fullerase(unsigned flashsize); 77 | bool bmp_blankcheck(unsigned flashsize); 78 | bool bmp_dumpflash(const char *path, unsigned flashsize); 79 | 80 | void bmp_progress_reset(unsigned long numsteps); 81 | void bmp_progress_step(unsigned long step); 82 | void bmp_progress_get(unsigned long *step, unsigned long *range); 83 | 84 | bool bmp_enabletrace(int async_bitrate, unsigned char *endpoint); 85 | 86 | int bmp_restart(void); 87 | int bmp_break(void); 88 | 89 | bool bmp_runscript(const char *name, const char *driver, const char *arch, unsigned long *params, size_t paramcount); 90 | bool bmp_writememory(uint32_t address, const uint8_t *data, size_t size); 91 | 92 | #if defined __cplusplus 93 | } 94 | #endif 95 | 96 | #endif /* _BMP_SUPPORT_H */ 97 | 98 | -------------------------------------------------------------------------------- /source/bmprofile.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * Statistical Profiler for the Black Magic Probe, using the PC sampler of the 3 | * DWT/ITM modules of the Cortex debug architecture. This utility is built with 4 | * Nuklear for a cross-platform GUI. 5 | * 6 | * Copyright 2022-2023 CompuPhase 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #include 22 | #include 23 | #include "svnrev.h" 24 | 25 | AppIcon ICON "res/icon_profile.ico" 26 | 27 | /* Version information 28 | * 29 | * All strings MUST have an explicit \0. See the Windows SDK documentation 30 | * for details on version information and the VERSIONINFO structure. 31 | */ 32 | #define VERSION 1 33 | #define REVISION 2 34 | #define BUILD SVNREV_NUM 35 | #define VERSIONSTR SVNREV_STR 36 | #define VERSIONNAME "bmprofile.exe\0" 37 | #define VERSIONDESCRIPTION "BMProfile: Statistical Profiler\0" 38 | #define VERSIONCOMPANYNAME "CompuPhase\0" 39 | #define VERSIONPRODUCTNAME "bmprofile\0" 40 | #define VERSIONCOPYRIGHT "Copyright \251 CompuPhase 2022\0" 41 | 42 | VS_VERSION_INFO VERSIONINFO 43 | FILEVERSION VERSION, REVISION, BUILD, 0 44 | PRODUCTVERSION VERSION, REVISION, BUILD, 0 45 | FILEFLAGSMASK 0x0000003FL 46 | FILEFLAGS 0 47 | #if defined(WIN32) 48 | FILEOS VOS__WINDOWS32 49 | #else 50 | FILEOS VOS__WINDOWS16 51 | #endif 52 | FILETYPE VFT_APP 53 | BEGIN 54 | BLOCK "StringFileInfo" 55 | BEGIN 56 | BLOCK "040904E4" 57 | BEGIN 58 | VALUE "CompanyName", VERSIONCOMPANYNAME 59 | VALUE "FileDescription", VERSIONDESCRIPTION 60 | VALUE "FileVersion", VERSIONSTR 61 | VALUE "InternalName", VERSIONNAME 62 | VALUE "LegalCopyright", VERSIONCOPYRIGHT 63 | VALUE "OriginalFilename", VERSIONNAME 64 | VALUE "ProductName", VERSIONPRODUCTNAME 65 | VALUE "ProductVersion", VERSIONSTR 66 | END 67 | END 68 | 69 | BLOCK "VarFileInfo" 70 | BEGIN 71 | VALUE "Translation", 0x409, 1252 72 | END 73 | END 74 | 75 | -------------------------------------------------------------------------------- /source/bmscript: -------------------------------------------------------------------------------- 1 | # Available scripts 2 | # 3 | # memremap - to map Flash memory to the base address 4 | # no parameters 5 | # 6 | # swo_device - for MCU-specific initialization of SWO tracing and profiling 7 | # no parameters 8 | # 9 | # swo_trace - to perform general initialization for SWO tracing 10 | # $0 = SWO mode: 1 = Manchester, 2 = Asynchronous 11 | # $1 = CPU clock divider (MCU clock / bitrate), to set the SWO bitrate 12 | # 13 | # swo_channels - to enable/disable SWO channels (SWO tracing) 14 | # $0 = enabled channel bit-mask 15 | # 16 | # swo_profile - to perform general initialization for sampling profiling 17 | # $0 = SWO mode: 1 = Manchester, 2 = Asynchronous 18 | # $1 = CPU clock divider (MCU clock / bitrate), to set the SWO bitrate 19 | # $2 = sampling interval divider (0=1K, 15=16K) 20 | # 21 | # swo_close - shut down SWO tracing and profiling 22 | # no parameters 23 | # 24 | # partid - to return the part-ID code (if any) 25 | # $ = return value 26 | # 27 | # flashsize - to return the size of Flash memory 28 | # $ = return value 29 | 30 | -------------------------------------------------------------------------------- /source/bmserial.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * Serial monitor/terminal. This is a general purpose utility, but developed as 3 | * part of * the "Black Magic" utilities (because an adequate serial terminal 4 | * was lacking). 5 | * This utility is built with Nuklear for a cross-platform GUI. 6 | * 7 | * Copyright 2022-2023 CompuPhase 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | 22 | #include 23 | #include 24 | #include "svnrev.h" 25 | 26 | AppIcon ICON "res/icon_serial.ico" 27 | 28 | /* Version information 29 | * 30 | * All strings MUST have an explicit \0. See the Windows SDK documentation 31 | * for details on version information and the VERSIONINFO structure. 32 | */ 33 | #define VERSION 1 34 | #define REVISION 2 35 | #define BUILD SVNREV_NUM 36 | #define VERSIONSTR SVNREV_STR 37 | #define VERSIONNAME "bmserial.exe\0" 38 | #define VERSIONDESCRIPTION "BMSerial: Serial Monitor/Terminal\0" 39 | #define VERSIONCOMPANYNAME "CompuPhase\0" 40 | #define VERSIONPRODUCTNAME "bmserial\0" 41 | #define VERSIONCOPYRIGHT "Copyright \251 CompuPhase 2022\0" 42 | 43 | VS_VERSION_INFO VERSIONINFO 44 | FILEVERSION VERSION, REVISION, BUILD, 0 45 | PRODUCTVERSION VERSION, REVISION, BUILD, 0 46 | FILEFLAGSMASK 0x0000003FL 47 | FILEFLAGS 0 48 | #if defined(WIN32) 49 | FILEOS VOS__WINDOWS32 50 | #else 51 | FILEOS VOS__WINDOWS16 52 | #endif 53 | FILETYPE VFT_APP 54 | BEGIN 55 | BLOCK "StringFileInfo" 56 | BEGIN 57 | BLOCK "040904E4" 58 | BEGIN 59 | VALUE "CompanyName", VERSIONCOMPANYNAME 60 | VALUE "FileDescription", VERSIONDESCRIPTION 61 | VALUE "FileVersion", VERSIONSTR 62 | VALUE "InternalName", VERSIONNAME 63 | VALUE "LegalCopyright", VERSIONCOPYRIGHT 64 | VALUE "OriginalFilename", VERSIONNAME 65 | VALUE "ProductName", VERSIONPRODUCTNAME 66 | VALUE "ProductVersion", VERSIONSTR 67 | END 68 | END 69 | 70 | BLOCK "VarFileInfo" 71 | BEGIN 72 | VALUE "Translation", 0x409, 1252 73 | END 74 | END 75 | 76 | -------------------------------------------------------------------------------- /source/bmtrace.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * Trace viewer utility for visualizing output on the TRACESWO pin via the 3 | * Black Magic Probe. The name stands for "Black Magic Serial Wire Viewer". 4 | * This utility is built with Nuklear for a cross-platform GUI. 5 | * 6 | * Copyright 2019-2023 CompuPhase 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #include 22 | #include 23 | #include "svnrev.h" 24 | 25 | AppIcon ICON "res/icon_trace.ico" 26 | 27 | /* Version information 28 | * 29 | * All strings MUST have an explicit \0. See the Windows SDK documentation 30 | * for details on version information and the VERSIONINFO structure. 31 | */ 32 | #define VERSION 1 33 | #define REVISION 2 34 | #define BUILD SVNREV_NUM 35 | #define VERSIONSTR SVNREV_STR 36 | #define VERSIONNAME "bmtrace.exe\0" 37 | #define VERSIONDESCRIPTION "BMTrace: Serial Wire Trace Viewer\0" 38 | #define VERSIONCOMPANYNAME "CompuPhase\0" 39 | #define VERSIONPRODUCTNAME "bmtrace\0" 40 | #define VERSIONCOPYRIGHT "Copyright \251 CompuPhase 2019-2022\0" 41 | 42 | VS_VERSION_INFO VERSIONINFO 43 | FILEVERSION VERSION, REVISION, BUILD, 0 44 | PRODUCTVERSION VERSION, REVISION, BUILD, 0 45 | FILEFLAGSMASK 0x0000003FL 46 | FILEFLAGS 0 47 | #if defined(WIN32) 48 | FILEOS VOS__WINDOWS32 49 | #else 50 | FILEOS VOS__WINDOWS16 51 | #endif 52 | FILETYPE VFT_APP 53 | BEGIN 54 | BLOCK "StringFileInfo" 55 | BEGIN 56 | BLOCK "040904E4" 57 | BEGIN 58 | VALUE "CompanyName", VERSIONCOMPANYNAME 59 | VALUE "FileDescription", VERSIONDESCRIPTION 60 | VALUE "FileVersion", VERSIONSTR 61 | VALUE "InternalName", VERSIONNAME 62 | VALUE "LegalCopyright", VERSIONCOPYRIGHT 63 | VALUE "OriginalFilename", VERSIONNAME 64 | VALUE "ProductName", VERSIONPRODUCTNAME 65 | VALUE "ProductVersion", VERSIONSTR 66 | END 67 | END 68 | 69 | BLOCK "VarFileInfo" 70 | BEGIN 71 | VALUE "Translation", 0x409, 1252 72 | END 73 | END 74 | 75 | -------------------------------------------------------------------------------- /source/c99_snprintf.h: -------------------------------------------------------------------------------- 1 | /* source: https://stackoverflow.com/a/8712996 */ 2 | #include 3 | #include 4 | 5 | #define snprintf c99_snprintf 6 | #define vsnprintf c99_vsnprintf 7 | 8 | __inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) 9 | { 10 | int count = -1; 11 | 12 | if (size != 0) 13 | count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); 14 | if (count == -1) 15 | count = _vscprintf(format, ap); 16 | 17 | return count; 18 | } 19 | 20 | __inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...) 21 | { 22 | int count; 23 | va_list ap; 24 | 25 | va_start(ap, format); 26 | count = c99_vsnprintf(outBuf, size, format, ap); 27 | va_end(ap); 28 | 29 | return count; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /source/cksum.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Calculates and prints the POSIX checksums and sizes of files. 3 | * This is a re-implementation of the cksum program provided with Unix 4 | * and Linux distributions. 5 | * 6 | * For the original, see: 7 | * - http://www.gnu.org/software/coreutils/ 8 | * - http://gnuwin32.sourceforge.net/packages/coreutils.htm 9 | * 10 | * In contrast to the original, this implementation: 11 | * - does not support any options, except --help 12 | * - has no option to read from stdin (so does not support calculating 13 | * a checksum from data "piped" in through redirection) 14 | * - does not support wild-cards (file globbing) on Windows 15 | * 16 | * Note that the FreeBSD implementation of cksum is different from the 17 | * version of Unix and Linux, in at least two ways: 18 | * - the FreeBSD implementation offers the choice of three checksum 19 | * algorithms (one of which is CRC32), whereas the Linux version only 20 | * offers CRC32 21 | * - the Linux version includes the value of the file length (in bytes) 22 | * in the CRC (exactly like Wikipedia describes the algorithm), but 23 | * the FreeBSD version only uses the file contents for the CRC32. 24 | * The net result is that the cksum program in FreeBSD gives a different 25 | * result than Linux, when run on the same file. 26 | * 27 | * Copyright 2021 CompuPhase 28 | * 29 | * Licensed under the Apache License, Version 2.0 (the "License"); 30 | * you may not use this file except in compliance with the License. 31 | * You may obtain a copy of the License at 32 | * 33 | * http://www.apache.org/licenses/LICENSE-2.0 34 | * 35 | * Unless required by applicable law or agreed to in writing, software 36 | * distributed under the License is distributed on an "AS IS" BASIS, 37 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 38 | * See the License for the specific language governing permissions and 39 | * limitations under the License. 40 | */ 41 | 42 | #ifndef _CKSUM_H 43 | #define _CKSUM_H 44 | 45 | #include 46 | #include 47 | 48 | #if defined __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | uint32_t cksum(FILE *fp); 53 | 54 | #if defined __cplusplus 55 | } 56 | #endif 57 | 58 | #endif /* _CKSUM_H */ 59 | 60 | -------------------------------------------------------------------------------- /source/crc32.c: -------------------------------------------------------------------------------- 1 | /* Implementation of CRC32 as used by GDB 2 | * GDB uses the ITU I.363.5 algorithm, see: https://github.com/Michaelangel007/crc32 3 | */ 4 | #include "crc32.h" 5 | 6 | /* CRC32 table is copied from the GDB source 7 | for details, see: https://github.com/Michaelangel007/crc32 */ 8 | static const unsigned long crc_table[256] = 9 | { 10 | 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 11 | 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 12 | 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 13 | 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 14 | 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 15 | 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 16 | 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 17 | 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 18 | 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 19 | 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 20 | 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 21 | 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 22 | 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 23 | 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 24 | 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 25 | 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 26 | 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 27 | 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 28 | 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 29 | 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 30 | 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 31 | 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 32 | 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 33 | 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 34 | 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 35 | 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 36 | 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 37 | 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 38 | 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 39 | 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 40 | 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 41 | 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 42 | 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 43 | 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 44 | 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 45 | 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 46 | 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 47 | 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 48 | 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 49 | 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 50 | 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 51 | 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 52 | 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 53 | 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 54 | 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 55 | 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 56 | 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 57 | 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 58 | 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 59 | 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 60 | 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 61 | 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 62 | 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 63 | 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 64 | 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 65 | 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 66 | 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 67 | 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 68 | 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 69 | 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 70 | 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 71 | 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 72 | 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 73 | 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 74 | }; 75 | 76 | /** gdb_crc32() 77 | * \param crc The initial CRC, set to ~0 on the first call. 78 | * \param data The data block to calculate the CRC on. 79 | * \param size The size of the data block in bytes. 80 | * 81 | * \return The updated CRC32 value. 82 | * 83 | * \note This is a non-standard CRC32 implementation. It is designed such that 84 | * you can call it iteratively in small blocks over a big buffer. On the 85 | * first call, the value of the crc param is set to ~0, on every next 86 | * call, it is set the the output of the previous call. 87 | */ 88 | uint32_t gdb_crc32(uint32_t crc, const unsigned char *data, unsigned size) 89 | { 90 | while (size--) 91 | crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff]; 92 | return crc; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /source/crc32.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined __cplusplus 4 | extern "C" 5 | #endif 6 | uint32_t gdb_crc32(uint32_t crc, const unsigned char *data, unsigned size); 7 | 8 | -------------------------------------------------------------------------------- /source/decodectf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Functions to decode a byte stream matching a trace stream description (TSDL 3 | * file). It uses data structures created by parsectf. 4 | * 5 | * Copyright 2019-2024 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _DECODECTF_H 20 | #define _DECODECTF_H 21 | 22 | #include "dwarf.h" 23 | 24 | int ctf_decode(const unsigned char *stream, size_t size, long channel); 25 | void ctf_decode_reset(void); 26 | void ctf_decode_cleanup(void); 27 | void ctf_set_symtable(const DWARF_SYMBOLLIST *symtable); 28 | void ctf_set_filter(unsigned long streammask, unsigned char severity); 29 | int msgstack_pop(uint16_t *streamid, double *timestamp, char *message, size_t size); 30 | int msgstack_peek(uint16_t *streamid, uint16_t *eventid, uint8_t *severity, double *timestamp, const char **message); 31 | 32 | #endif /* _DECODECTF_H */ 33 | 34 | -------------------------------------------------------------------------------- /source/demangle.h: -------------------------------------------------------------------------------- 1 | /* GNU C++ symbol name demangler 2 | * 3 | * Copyright 2022-2023, CompuPhase 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef _DEMANGLE_H 18 | #define _DEMANGLE_H 19 | 20 | int demangle(char *plain, size_t size, const char *mangled); 21 | 22 | #endif /* _DEMANGLE_H */ 23 | -------------------------------------------------------------------------------- /source/dirent.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Implementation of POSIX directory browsing functions and types for Win32. 4 | 5 | Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) 6 | History: Created March 1997. Updated June 2003 and July 2012. 7 | Updated August 2021 to use Windows API (instead of DOS) and add 8 | file attribute & size, by Thiadmer Riemersma 9 | Rights: See end of file. 10 | 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "dirent.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" 21 | { 22 | #endif 23 | 24 | 25 | struct DIR 26 | { 27 | HANDLE handle; /* INVALID_HANDLE_VALUE for failed rewind */ 28 | WIN32_FIND_DATA info; 29 | struct dirent result; /* d_name NULL iff first time */ 30 | char *name; /* null-terminated char string */ 31 | }; 32 | 33 | DIR *opendir(const char *name) 34 | { 35 | DIR *dir = NULL; 36 | 37 | if(name && name[0]) 38 | { 39 | size_t base_length = strlen(name); 40 | const char *all = /* search pattern must end with suitable wildcard */ 41 | strchr("/\\", name[base_length - 1]) ? "*" : "/*"; 42 | 43 | if((dir = (DIR *) malloc(sizeof *dir)) != 0 && 44 | (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) 45 | { 46 | strcat(strcpy(dir->name, name), all); 47 | 48 | if((dir->handle = 49 | FindFirstFile(dir->name, &dir->info)) != INVALID_HANDLE_VALUE) 50 | { 51 | dir->result.d_name = NULL; 52 | } 53 | else /* rollback */ 54 | { 55 | free(dir->name); 56 | free(dir); 57 | dir = NULL; 58 | } 59 | } 60 | else /* rollback */ 61 | { 62 | free(dir); 63 | dir = NULL; 64 | errno = ENOMEM; 65 | } 66 | } 67 | else 68 | { 69 | errno = EINVAL; 70 | } 71 | 72 | return dir; 73 | } 74 | 75 | int closedir(DIR *dir) 76 | { 77 | int result = -1; 78 | 79 | if(dir) 80 | { 81 | if(dir->handle != INVALID_HANDLE_VALUE) 82 | { 83 | result = FindClose(dir->handle) ? 0 : -1; /* closedir() returns 0 on success */ 84 | } 85 | 86 | free(dir->name); 87 | free(dir); 88 | } 89 | 90 | if(result == -1) /* map all errors to EBADF */ 91 | { 92 | errno = EBADF; 93 | } 94 | 95 | return result; 96 | } 97 | 98 | struct dirent *readdir(DIR *dir) 99 | { 100 | struct dirent *result = NULL; 101 | 102 | if(dir && dir->handle != INVALID_HANDLE_VALUE) 103 | { 104 | if(dir->result.d_name == NULL || FindNextFile(dir->handle, &dir->info)) 105 | { 106 | result = &dir->result; 107 | result->d_name = dir->info.cFileName; 108 | result->d_attr = (short)dir->info.dwFileAttributes & ~0x80; 109 | result->d_size = dir->info.nFileSizeLow; 110 | } 111 | } 112 | else 113 | { 114 | errno = EBADF; 115 | } 116 | 117 | return result; 118 | } 119 | 120 | void rewinddir(DIR *dir) 121 | { 122 | if(dir && dir->handle != INVALID_HANDLE_VALUE) 123 | { 124 | FindClose(dir->handle); 125 | dir->handle = FindFirstFile(dir->name, &dir->info); 126 | dir->result.d_name = NULL; 127 | } 128 | else 129 | { 130 | errno = EBADF; 131 | } 132 | } 133 | 134 | #ifdef __cplusplus 135 | } 136 | #endif 137 | 138 | /* 139 | 140 | Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. 141 | 142 | Permission to use, copy, modify, and distribute this software and its 143 | documentation for any purpose is hereby granted without fee, provided 144 | that this copyright and permissions notice appear in all copies and 145 | derivatives. 146 | 147 | This software is supplied "as is" without express or implied warranty. 148 | 149 | But that said, if there are any problems please get in touch. 150 | 151 | */ 152 | 153 | -------------------------------------------------------------------------------- /source/dirent.h: -------------------------------------------------------------------------------- 1 | #ifndef DIRENT_INCLUDED 2 | #define DIRENT_INCLUDED 3 | 4 | /* 5 | 6 | Declaration of POSIX directory browsing functions and types for Win32. 7 | 8 | Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) 9 | History: Created March 1997. Updated June 2003. 10 | Updated August 2021, by Thiadmer Riemersma. 11 | Rights: See end of file. 12 | 13 | */ 14 | 15 | #ifdef __cplusplus 16 | extern "C" 17 | { 18 | #endif 19 | 20 | typedef struct DIR DIR; 21 | 22 | struct dirent 23 | { 24 | char *d_name; /* file's name */ 25 | int d_attr; /* file's attribute */ 26 | unsigned long d_size; /* file's size */ 27 | }; 28 | 29 | DIR *opendir(const char *); 30 | int closedir(DIR *); 31 | struct dirent *readdir(DIR *); 32 | void rewinddir(DIR *); 33 | 34 | /* File attribute constants for d_attr field */ 35 | #define _A_NORMAL 0x00 /* Normal file - read/write permitted */ 36 | #define _A_RDONLY 0x01 /* Read-only file */ 37 | #define _A_HIDDEN 0x02 /* Hidden file */ 38 | #define _A_SYSTEM 0x04 /* System file */ 39 | #define _A_VOLID 0x08 /* Volume-ID entry */ 40 | #define _A_SUBDIR 0x10 /* Subdirectory */ 41 | #define _A_ARCH 0x20 /* Archive file */ 42 | 43 | /* 44 | 45 | Copyright Kevlin Henney, 1997, 2003. All rights reserved. 46 | 47 | Permission to use, copy, modify, and distribute this software and its 48 | documentation for any purpose is hereby granted without fee, provided 49 | that this copyright and permissions notice appear in all copies and 50 | derivatives. 51 | 52 | This software is supplied "as is" without express or implied warranty. 53 | 54 | But that said, if there are any problems please get in touch. 55 | 56 | */ 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | 64 | -------------------------------------------------------------------------------- /source/dwarf.h: -------------------------------------------------------------------------------- 1 | /* Routines to get the line number and symbol tables from the DWARF debug 2 | * information * in an ELF file. For the symbol table, only the function and 3 | * variable symbols are stored. 4 | * 5 | * Copyright (c) 2015,2019-2023 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _DWARF_H 20 | #define _DWARF_H 21 | 22 | #if defined __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct tagDWARF_PATHLIST { 27 | struct tagDWARF_PATHLIST *next; 28 | char *name; 29 | } DWARF_PATHLIST; 30 | 31 | enum { 32 | SCOPE_UNKNOWN, 33 | SCOPE_EXTERNAL, /* global variable or function */ 34 | SCOPE_UNIT, /* static variable/function declared at file scope (compilation unit) */ 35 | SCOPE_FUNCTION, /* local variable (including static locals & function arguments) */ 36 | }; 37 | 38 | #define DWARF_FLAG_INLINE 0x0001 39 | 40 | typedef struct tagDWARF_SYMBOLLIST { 41 | struct tagDWARF_SYMBOLLIST *next; 42 | char *name; 43 | unsigned code_addr; /* function address, 0 for a variable */ 44 | unsigned code_range; /* size of the code (functions only, 0 for variables) */ 45 | unsigned data_addr; /* variable address (globals & statics only), 0 for a function or a local variable */ 46 | int line; /* line number of the declaration/definition */ 47 | int line_limit; /* last line of the definition (functions) or line at which the scope ends (variables) */ 48 | short fileindex; /* file where the declaration/definition appears in */ 49 | short scope; 50 | unsigned flags; 51 | } DWARF_SYMBOLLIST; 52 | 53 | typedef struct tagDWARF_LINEENTRY { 54 | unsigned address; 55 | int line; 56 | int fileindex; 57 | int view; 58 | } DWARF_LINEENTRY; 59 | 60 | typedef struct tagDWARF_LINETABLE { 61 | DWARF_LINEENTRY *table; 62 | unsigned entries; /* number of valid entries in the table */ 63 | unsigned size; /* number of allocated entries */ 64 | } DWARF_LINETABLE; 65 | 66 | #define DWARF_IS_FUNCTION(sym) ((sym)->code_range>0 || ((sym)->flags & DWARF_FLAG_INLINE) != 0) 67 | #define DWARF_IS_VARIABLE(sym) ((sym)->code_range==0 && ((sym)->flags & DWARF_FLAG_INLINE) == 0) 68 | 69 | enum { 70 | DWARF_SORT_NAME, 71 | DWARF_SORT_ADDRESS, 72 | }; 73 | 74 | bool dwarf_read(FILE *fp,DWARF_LINETABLE *linetable,DWARF_SYMBOLLIST *symboltable,DWARF_PATHLIST *filetable,int *address_size); 75 | void dwarf_cleanup(DWARF_LINETABLE *linetable,DWARF_SYMBOLLIST *symboltable,DWARF_PATHLIST *filetable); 76 | 77 | const DWARF_SYMBOLLIST* dwarf_sym_from_name(const DWARF_SYMBOLLIST *symboltable,const char *name,int fileindex,int lineindex); 78 | const DWARF_SYMBOLLIST* dwarf_sym_from_address(const DWARF_SYMBOLLIST *symboltable,unsigned address,int exact); 79 | const DWARF_SYMBOLLIST* dwarf_sym_from_index(const DWARF_SYMBOLLIST *symboltable,unsigned index); 80 | unsigned dwarf_collect_functions_in_file(const DWARF_SYMBOLLIST *symboltable,int fileindex,int sort,const DWARF_SYMBOLLIST *list[],int numentries); 81 | const char* dwarf_path_from_fileindex(const DWARF_PATHLIST *filetable,int fileindex); 82 | int dwarf_fileindex_from_path(const DWARF_PATHLIST *filetable,const char *path); 83 | const DWARF_LINEENTRY* dwarf_line_from_address(const DWARF_LINETABLE *linetable,unsigned address); 84 | 85 | #if defined __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /* _DWARF_H */ 90 | -------------------------------------------------------------------------------- /source/elf-postlink.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A utility to post-process ELF files for requirements of specific 3 | * micro-controllers. At this moment, the utility supports various ranges 4 | * of the LPC family by NXP. 5 | * 6 | * Copyright 2019-2023 CompuPhase 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "elf.h" 27 | #include "svnrev.h" 28 | 29 | 30 | #define FLAG_HEADER 0x01 31 | #define FLAG_MCU_LIST 0x02 32 | #define FLAG_ALLINFO 0xff 33 | 34 | static void usage(int flags) 35 | { 36 | if (flags & FLAG_HEADER) 37 | printf("\nPostprocess an ELF file for requirements of specific micro-controllers.\n\n" 38 | "Usage: elf-postlink \n\n"); 39 | if (flags & FLAG_MCU_LIST) 40 | printf("MCU types:\n" 41 | "\tlpc8xx - NXP LPC800, LPC810, LPC820, LPC830, LPC840 and LPC860\n" 42 | "\t Cortex-M0/M0+ series\n" 43 | "\tlpc11xx - NXP LPC1100, LPC11A00, LPC11C00, LPC11E00 and LPC11U00\n" 44 | "\t Cortex-M0/M0+ series\n" 45 | "\tlpc15xx - NXP LPC1500 Cortex-M3 series\n" 46 | "\tlpc17xx - NXP LPC1700 Cortex-M3 series\n" 47 | "\tlpc18xx - NXP LPC1800 Cortex-M3 series\n" 48 | "\tlpc21xx - NXP LPC2100 ARM7TDMI series\n" 49 | "\tlpc22xx - NXP LPC2200 ARM7TDMI series\n" 50 | "\tlpc23xx - NXP LPC2300 ARM7TDMI series\n" 51 | "\tlpc24xx - NXP LPC2400 ARM7TDMI series\n" 52 | "\tlpc40xx - NXP LPC4000 Cortex-M4 series\n" 53 | "\tlpc43xx - NXP LPC4300 Cortex-M4/M0 series\n" 54 | "\tlpc546xx - NXP LPC546xx Cortex-M4 series\n" 55 | ); 56 | } 57 | 58 | static void version(void) 59 | { 60 | printf("elf-postlink version %s.\n", SVNREV_STR); 61 | printf("Copyright 2019-2023 CompuPhase\nLicensed under the Apache License version 2.0\n"); 62 | } 63 | 64 | int main(int argc, char *argv[]) 65 | { 66 | uint32_t chksum; 67 | int result, idx_file, idx_type; 68 | FILE *fp; 69 | 70 | if (argc == 2 && strcmp(argv[1], "-v") == 0) { 71 | version(); 72 | return EXIT_SUCCESS; 73 | } 74 | if (argc != 3) { 75 | usage(FLAG_ALLINFO); 76 | return EXIT_SUCCESS; 77 | } 78 | 79 | idx_type = 1; /* assume correct order of command-line options */ 80 | idx_file = 2; 81 | fp = fopen(argv[idx_file], "rb+"); 82 | if (fp == NULL) { 83 | /* test for inverted order of options */ 84 | fp = fopen(argv[idx_type], "rb+"); 85 | if (fp == NULL) { 86 | /* failed too, this must be some error */ 87 | printf("File \"%s\" could not be opened.\n\n", argv[idx_file]); 88 | usage(FLAG_ALLINFO); 89 | return 0; 90 | } 91 | /* file open worked at inverted order, assume inverted order then */ 92 | idx_type = 2; 93 | idx_file = 1; 94 | } 95 | 96 | result = elf_patch_vecttable(fp, argv[idx_type], &chksum); 97 | fclose(fp); 98 | switch (result) { 99 | case ELFERR_NONE: 100 | printf("Checksum set to 0x%08x\n", chksum); 101 | break; 102 | case ELFERR_CHKSUMSET: 103 | printf("Checksum already correct (0x%08x)\n", chksum); 104 | break; 105 | case ELFERR_UNKNOWNDRIVER: 106 | printf("Unsupported MCU type \"%s\".\n", argv[idx_type]); 107 | usage(FLAG_MCU_LIST); 108 | break; 109 | case ELFERR_FILEFORMAT: 110 | printf("File \"%s\" has an unsupported format. A 32-bit ELF file is required\n", argv[idx_file]); 111 | usage(FLAG_HEADER); 112 | break; 113 | } 114 | 115 | return EXIT_SUCCESS; 116 | } 117 | 118 | -------------------------------------------------------------------------------- /source/elf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Routines for querying information on ELF files and post-processing them 3 | * for requirements of specific micro-controllers. At this moment, the utility 4 | * supports various ranges of the LPC family by NXP. 5 | * 6 | * Copyright 2015,2019-2023 CompuPhase 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | #ifndef _ELF_H 21 | #define _ELF_H 22 | 23 | #if defined __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | enum { 28 | ELFERR_NONE = 0, 29 | ELFERR_CHKSUMSET, /* checksum was already the correct value (no error, but no change either) */ 30 | ELFERR_UNKNOWNDRIVER, /* unknown microcontroller driver name */ 31 | ELFERR_FILEFORMAT, /* unsupported file format */ 32 | ELFERR_NOMATCH, /* no matching section / segment */ 33 | ELFERR_MEMORY, /* insufficient memory */ 34 | ELFERR_CHKSUMERR, /* checksum failed */ 35 | }; 36 | 37 | /* segment types */ 38 | #define ELF_PT_NULL 0 39 | #define ELF_PT_LOAD 1 /* segment is loadable */ 40 | #define ELF_PT_DYNAMIC 2 /* segment specifies dynamic linking information */ 41 | #define ELF_PT_INTERP 3 /* segment is a path to an interpreter */ 42 | #define ELF_PT_NOTE 4 43 | #define ELF_PT_SHLIB 5 44 | #define ELF_PT_PHDR 6 45 | 46 | /* segment flags */ 47 | #define ELF_PF_X 0x01 /* execute */ 48 | #define ELF_PF_W 0x02 /* write */ 49 | #define ELF_PF_R 0x04 /* read */ 50 | 51 | 52 | typedef struct tagELF_SYMBOL { 53 | const char *name; /* symbol name */ 54 | unsigned long address;/* memory address */ 55 | unsigned long size; /* code size or data size (0 for unknown) */ 56 | unsigned char is_func;/* 1 for a function symbol, 0 for a variable/data */ 57 | unsigned char is_ext; /* 1 for external scope, 0 for file local scope */ 58 | } ELF_SYMBOL; 59 | 60 | int elf_info(FILE *fp,int *wordsize,int *bigendian,int *machine,unsigned long *entry_addr); 61 | 62 | int elf_segment_by_index(FILE *fp,int index, 63 | int *type, int *flags, 64 | unsigned long *offset,unsigned long *filesize, 65 | unsigned long *vaddr,unsigned long *paddr, 66 | unsigned long *memsize); 67 | 68 | int elf_section_by_name(FILE *fp,const char *sectionname,unsigned long *offset, 69 | unsigned long *address,unsigned long *length); 70 | 71 | int elf_section_by_address(FILE *fp,unsigned long baseaddr, 72 | char *sectionname,size_t namelength,unsigned long *offset, 73 | unsigned long *address,unsigned long *length); 74 | 75 | int elf_load_symbols(FILE *fp,ELF_SYMBOL *symbols,unsigned *number); 76 | void elf_clear_symbols(ELF_SYMBOL *symbols,unsigned number); 77 | 78 | int elf_check_vecttable(FILE *fp); 79 | int elf_patch_vecttable(FILE *fp,const char *driver,unsigned *checksum); 80 | int elf_check_crp(FILE *fp,int *crp); 81 | 82 | #if defined __cplusplus 83 | } 84 | #endif 85 | 86 | #endif /* _ELF_H */ 87 | 88 | -------------------------------------------------------------------------------- /source/fileloader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File loading support for binary (executable) files, with support for ELF, 3 | * Intel HEX and BIN formats. 4 | * 5 | * Copyright 2023 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _FILELOADER_H 20 | #define _FILELOADER_H 21 | 22 | #include 23 | 24 | #if defined __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | enum { 29 | FILETYPE_NONE, /* no file is loaded */ 30 | FILETYPE_ELF, 31 | FILETYPE_HEX, 32 | FILETYPE_UNKNOWN, 33 | }; 34 | 35 | enum { 36 | SECTIONTYPE_UNKNOWN, 37 | SECTIONTYPE_CODE, 38 | SECTIONTYPE_DATA, 39 | }; 40 | 41 | enum { 42 | FSERR_NONE, 43 | FSERR_CHKSUMSET, 44 | FSERR_NO_DRIVER, 45 | FSERR_NO_VECTTABLE, 46 | }; 47 | 48 | void filesection_clearall(void); 49 | bool hex_isvalid(FILE *fp); 50 | bool filesection_loadall(const char *filename); 51 | bool filesection_getdata(unsigned index, unsigned long *address, unsigned char **buffer, unsigned long *size, int *type); 52 | int filesection_filetype(void); 53 | void filesection_relocate(unsigned long offset); 54 | unsigned char *filesection_get_address(unsigned long address, size_t size); 55 | 56 | int filesection_patch_vecttable(const char *driver, unsigned int *checksum); 57 | int filesection_get_crp(void); 58 | bool filesection_set_crp(int crp); 59 | 60 | #if defined __cplusplus 61 | } 62 | #endif 63 | 64 | #endif /* _FILELOADER_H */ 65 | 66 | -------------------------------------------------------------------------------- /source/findfont.c: -------------------------------------------------------------------------------- 1 | // gcc -g -o findfont findfont.c -lfontconfig 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #if defined __linux__ 8 | #include 9 | #endif 10 | 11 | /** font_locate() returns the path to a font file matching the family name 12 | * and style. 13 | * 14 | * \param path The path of the font file is returned in this parameter. 15 | * \param maxlength The size (in characters) of parameter path (which must 16 | * include the zero-terminator. 17 | * \param family The font family name. 18 | * \param style A string with keywords for the style of the font, such as 19 | * "Regular", "Italic", "Bold" or "Bold Italic". 20 | * 21 | * \return 1 on success, 0 on failure. 22 | */ 23 | int font_locate(char *path, size_t maxlength, const char *family, const char *style) 24 | { 25 | #define MAX_STYLES 10 26 | FcPattern *pat; 27 | FcFontSet *fs; 28 | FcObjectSet *os; 29 | FcChar8 *s, *ptr; 30 | FcConfig *config; 31 | int i, match; 32 | char *style_copy; 33 | char *style_fields[MAX_STYLES]; 34 | 35 | assert(path != NULL); 36 | assert(maxlength > 0); 37 | assert(family != NULL); 38 | assert(style != NULL); 39 | 40 | /* split style into keywords */ 41 | style_copy = strdup(style); 42 | if (style_copy == NULL) 43 | return 0; 44 | memset(style_fields, 0, sizeof style_fields); 45 | style_fields[0] = strtok(style_copy, " "); 46 | for (i = 1; i < MAX_STYLES && style_fields[i - 1] != NULL; i++) 47 | style_fields[i] = strtok(NULL, " "); 48 | 49 | if (!FcInit()) 50 | return 0; 51 | config = FcConfigGetCurrent(); 52 | FcConfigSetRescanInterval(config, 0); 53 | 54 | pat = FcPatternCreate(); 55 | os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0); 56 | fs = FcFontList(config, pat, os); 57 | match = 0; 58 | for (i=0; fs && i < fs->nfont && !match; i++) { 59 | FcPattern *font = fs->fonts[i]; 60 | s = FcNameUnparse(font); 61 | match = 1; 62 | if (FcPatternGetString(font, FC_FAMILY, 0, &ptr) == FcResultMatch) { 63 | if (strcasecmp((const char*)ptr, family) != 0) 64 | match = 0; 65 | } else { 66 | match = 0; 67 | } 68 | if (FcPatternGetString(font, FC_STYLE, 0, &ptr) == FcResultMatch) { 69 | int styles_to_match, idx; 70 | char *style_string; 71 | /* compare words in the font's style with words in the requested style */ 72 | styles_to_match = 0; 73 | for (idx = 0; idx < MAX_STYLES && style_fields[idx] != NULL; idx++) 74 | if (strcasecmp(style_fields[idx], "Roman") != 0 && strcasecmp(style_fields[idx], "Regular") != 0 && strcasecmp(style_fields[idx], "Book") != 0) 75 | styles_to_match |= (1 << idx); 76 | style_string = strdup((const char*)ptr); 77 | if (style_string != NULL) { 78 | char *token; 79 | for (token = strtok(style_string, " "); token != NULL; token = strtok(NULL, " ")) { 80 | if (strcasecmp(token, "Roman") == 0 || strcasecmp(token, "Regular") == 0 || strcasecmp(token, "Book") == 0) 81 | continue; /* these are implied (unless Bold or Italic or Condensed are set) */ 82 | if (strcasecmp(token, "Oblique") == 0) 83 | token = "Italic"; 84 | for (idx = 0; idx < MAX_STYLES && style_fields[idx] != NULL; idx++) 85 | if (strcasecmp(token, style_fields[idx]) == 0) 86 | break; 87 | if (idx < MAX_STYLES && style_fields[idx] != NULL) 88 | styles_to_match &= ~(1 << match); /* font style found in styles to match */ 89 | else 90 | match = 0; /* font style not found in styles to match, this font has a different style */ 91 | } 92 | free(style_string); 93 | } 94 | if (styles_to_match != 0) 95 | match = 0; /* not all styles to match were present in the font style */ 96 | } else { 97 | match = 0; 98 | } 99 | if (match && FcPatternGetString(font, FC_FILE, 0, &ptr) == FcResultMatch) { 100 | strlcpy(path, (const char*)ptr, maxlength); 101 | path[maxlength - 1] = '\0'; 102 | } else { 103 | match = 0; 104 | } 105 | free(s); 106 | } 107 | free(style_copy); 108 | if (fs) 109 | FcFontSetDestroy(fs); 110 | FcObjectSetDestroy(os); 111 | FcPatternDestroy(pat); 112 | 113 | return match; 114 | } 115 | 116 | #if 0 117 | int main(int argc,char *argv[]) 118 | { 119 | char path[256]; 120 | 121 | if (font_locate(path, sizeof path, "DejaVu Sans Mono", "")) 122 | printf("Found: %s\n", path); 123 | else 124 | printf("Not found\n"); 125 | } 126 | #endif 127 | -------------------------------------------------------------------------------- /source/findfont.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FINDFONT_H 3 | #define _FINDFONT_H 4 | 5 | #include 6 | 7 | #if defined __cplusplus 8 | extern "C" 9 | #endif 10 | int font_locate(char *path, size_t maxlength, const char *family, const char *style); 11 | 12 | #endif /* _FINDFONT_H */ 13 | -------------------------------------------------------------------------------- /source/gdb-rsp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The GDB "Remote Serial Protocol" support. 3 | * 4 | * Copyright 2019-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _GDB_RSP_H 19 | #define _GDB_RSP_H 20 | 21 | #if defined __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | bool gdbrsp_hex2array(const char *hex, unsigned char *byte, size_t size); 26 | void gdbrsp_packetsize(size_t size); 27 | size_t gdbrsp_recv(char *buffer, size_t size, int timeout); 28 | bool gdbrsp_xmit(const char *buffer, int size); 29 | void gdbrsp_clear(void); 30 | 31 | #if defined __cplusplus 32 | } 33 | #endif 34 | 35 | #endif /* _GDB_RSP_H */ 36 | 37 | -------------------------------------------------------------------------------- /source/guidriver.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Helper functions for the back-end driver for the Nuklear GUI. Currently, GDI+ 3 | * (for Windows) and GLFW with OpenGL (for Linux) are supported. 4 | * 5 | * Copyright 2019-2024 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _GUIDRIVER_H 20 | #define _GUIDRIVER_H 21 | 22 | #include 23 | #include "nuklear.h" 24 | 25 | #define GUIDRV_RESIZEABLE 0x0001 26 | #define GUIDRV_CENTER 0x0002 27 | #define GUIDRV_TIMER 0x0004 28 | 29 | enum { 30 | FONT_STD = 0, 31 | FONT_BOLD, 32 | FONT_MONO, 33 | FONT_HEADING1, 34 | FONT_HEADING2, 35 | FONT_SMALL, 36 | }; 37 | enum { 38 | NK_FONTREGULAR = 0, 39 | NK_FONTBOLD = 1, 40 | NK_FONTITALIC = 2, 41 | NK_FONTBOLDITALIC = 3, 42 | NK_FONTUNDERLINE = 4, 43 | NK_FONTSTRIKEOUT = 8 44 | }; 45 | 46 | enum { 47 | DEVICE_INSERT = 1, 48 | DEVICE_REMOVE, 49 | }; 50 | 51 | struct nk_context* guidriver_init(const char *caption, int width, int height, int flags, 52 | const char *fontstd, const char *fontmono, float fontsize); 53 | void guidriver_close(void); 54 | bool guidriver_appsize(int *width, int *height); 55 | void guidriver_render(struct nk_color clear); 56 | bool guidriver_poll(bool waitidle); 57 | void *guidriver_apphandle(void); 58 | 59 | int guidriver_setfont(struct nk_context *ctx, int type); 60 | struct nk_image guidriver_image_from_memory(const unsigned char *data, unsigned size); 61 | 62 | int guidriver_monitor_usb(unsigned short vid, unsigned short pid); 63 | 64 | #endif /* _GUIDRIVER_H */ 65 | -------------------------------------------------------------------------------- /source/ident.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Basic re-implementation of the "ident" utility of the RCS suite, to extract 3 | * RCS identification strings from source and binary files. This implementation 4 | * only supports the keywords "Author", "Date", "Id", and "Revision" (which may 5 | * be abbreviated to "Rev"). 6 | * 7 | * Copyright 2021 CompuPhase 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "ident.h" 28 | 29 | #if defined FORTIFY 30 | # include 31 | #endif 32 | 33 | #if defined _MSC_VER 34 | # define stricmp(s1,s2) _stricmp((s1),(s2)) 35 | #elif defined __linux__ 36 | # define stricmp(s1,s2) strcasecmp((s1),(s2)) 37 | #endif 38 | 39 | #if !defined sizearray 40 | # define sizearray(e) (sizeof(e) / sizeof((e)[0])) 41 | #endif 42 | #if !defined STREQ 43 | # define STREQ(s1, s2) (stricmp((s1), (s2)) == 0) 44 | #endif 45 | 46 | enum { 47 | STATE_SCAN, 48 | STATE_KEY, 49 | STATE_VALUE, 50 | }; 51 | 52 | int ident(FILE *fp, int skip, char *key, size_t key_size, char *value, size_t value_size) 53 | { 54 | int ch, state; 55 | int key_idx, val_idx; 56 | 57 | assert(fp != NULL); 58 | assert(skip >= 0); 59 | assert(key != NULL && key_size > 0); 60 | assert(value != NULL && value_size > 0); 61 | 62 | rewind(fp); 63 | state = STATE_SCAN; 64 | while ((ch = fgetc(fp)) >= 0) { 65 | switch (state) { 66 | case STATE_SCAN: 67 | /* state 0: search for '$' as a start point */ 68 | if (ch == '$') { 69 | key_idx = 0; 70 | state = STATE_KEY; 71 | } 72 | break; 73 | 74 | case STATE_KEY: 75 | if (ch == ':') { 76 | while (key_idx > 0 && key[key_idx - 1] <= ' ') 77 | key_idx--; /* strip trailing spaces */ 78 | key[key_idx]= '\0'; /* terminate key */ 79 | val_idx = 0; 80 | state = (key_idx > 0) ? STATE_VALUE : STATE_SCAN; 81 | } else if (!isalpha(ch) && ch != ' ') { 82 | /* accept only alphabetic characters in the key; on invalid character, 83 | drop back to start */ 84 | state = STATE_SCAN; 85 | } else if (key_idx >= key_size) { 86 | /* if length of key exceeded, drop back to start */ 87 | state = STATE_SCAN; 88 | } else { 89 | key[key_idx++] = (char)ch; 90 | } 91 | break; 92 | 93 | case STATE_VALUE: 94 | if (ch == '$') { 95 | /* found a key/value pair */ 96 | while (val_idx > 0 && value[val_idx - 1] <= ' ') 97 | val_idx--; /* strip trailing spaces */ 98 | value[val_idx] = '\0'; 99 | if (val_idx > 0) { 100 | assert(strlen(key) > 0); 101 | /* both key and value have non-zero length, so appear to be valid, 102 | filter for standard keywords */ 103 | if (STREQ(key, "Author") || STREQ(key, "Date") || STREQ(key, "Id") 104 | || STREQ(key, "Rev") || STREQ(key, "Revision") || STREQ(key, "Header") 105 | || STREQ(key, "URL")) 106 | if (skip-- == 0) 107 | return 1; 108 | } 109 | state = STATE_SCAN; 110 | } else if (ch < ' ' || ch > 127) { 111 | state = STATE_SCAN; /* on invalid character, drop back to start */ 112 | } else if (val_idx >= value_size) { 113 | /* if length of value exceeded, drop back to start */ 114 | state = STATE_SCAN; 115 | } else if (val_idx > 0 || ch != ' ') { 116 | value[val_idx++] = (char)ch; 117 | } 118 | break; 119 | } 120 | } 121 | 122 | /* on failure to find (another) RCS identification, clear the output parameters */ 123 | assert(key != NULL && value != NULL); 124 | *key = '\0'; 125 | *value = '\0'; 126 | return 0; /* no (more) RCS identification strings found */ 127 | } 128 | 129 | #if defined STANDALONE 130 | 131 | static void usage(int status) 132 | { 133 | printf("ident - show RCS identification strings in the file.\n\n" 134 | "Usage: ident [filename] [...]\n\n"); 135 | exit(status); 136 | } 137 | 138 | int main(int argc, char *argv[]) 139 | { 140 | int i; 141 | 142 | if (argc <= 1) 143 | usage(EXIT_FAILURE); 144 | 145 | for (i = 1; i < argc; i++) { 146 | if (STREQ(argv[i], "-?") || STREQ(argv[i], "-h") || STREQ(argv[i], "--help")) { 147 | usage(EXIT_SUCCESS); 148 | } else if (argv[i][0] == '-') { 149 | fprintf(stderr, "Invalid option \"%s\", use --help to see the syntax\n\n", argv[i]); 150 | usage(EXIT_FAILURE); 151 | } else { 152 | FILE *fpElf = fopen(argv[i], "rb"); 153 | if (fpElf != NULL) { 154 | char key[32], value[128]; 155 | int count; 156 | printf("%s\n", argv[i]); 157 | for (count = 0; ident(fpElf, count, key, sizearray(key), value, sizearray(value)); count++) 158 | printf("\t%s: %s\n", key, value); 159 | fclose(fpElf); 160 | } else { 161 | fprintf(stderr, "Failed to open \"%s\", error %d\n", argv[i], errno); 162 | return EXIT_FAILURE; 163 | } 164 | } 165 | } 166 | 167 | return EXIT_SUCCESS; 168 | } 169 | 170 | #endif /* STANDALONE */ 171 | 172 | -------------------------------------------------------------------------------- /source/ident.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Basic re-implementation of the "ident" utility of the RCS suite, to extract 3 | * RCS identification strings from source and binary files. This implementation 4 | * only supports the keywords "Author", "Date", "Id", and "Revision" (which may 5 | * be abbreviated to "Rev"). 6 | * 7 | * Copyright 2021 CompuPhase 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | 22 | #ifndef _IDENT_H 23 | #define _IDENT_H 24 | 25 | #include 26 | 27 | #if defined __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | int ident(FILE *fp, int skip, char *key, size_t key_size, char *value, size_t value_size); 32 | 33 | #if defined __cplusplus 34 | } 35 | #endif 36 | 37 | #endif /* _IDENT_H */ 38 | 39 | -------------------------------------------------------------------------------- /source/makefile.cfg: -------------------------------------------------------------------------------- 1 | # Add macros with paths or options specific for your set-up in this file. 2 | # See the README on the GitHub project, as well as the Makefile, for details. 3 | -------------------------------------------------------------------------------- /source/mcu-info.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Microcontroller description lookup, based on brand and part id. 3 | * 4 | * Copyright 2022-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _MCU_INFO_H 19 | #define _MCU_INFO_H 20 | 21 | #include 22 | 23 | #if defined __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | typedef struct tagMCUINFO { 28 | uint32_t partid; 29 | const char *prefix; /* brand/family prefix (part of Black Magic Probe "driver" name), may be NULL */ 30 | uint32_t flash; 31 | uint32_t sram; /* main SRAM (not including buffers, caches & FIFOs for peripherals) */ 32 | const char *description; 33 | } MCUINFO; 34 | 35 | const MCUINFO *mcuinfo_data(const char *family, uint32_t id); 36 | const char *mcuinfo_lookup(const char *family, uint32_t id); 37 | 38 | #if defined __cplusplus 39 | } 40 | #endif 41 | 42 | #endif /* _MCU_INFO_H */ 43 | 44 | -------------------------------------------------------------------------------- /source/memdump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Memory Dump widget and support functions, for the Black Magic Debugger 3 | * front-end based on the Nuklear GUI. 4 | * 5 | * Copyright 2021-2023 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _MEMDUMP_H 20 | #define _MEMDUMP_H 21 | 22 | #include "nuklear.h" 23 | 24 | typedef struct tagMEMDUMP { 25 | char *expr; /* number or expression that evaluates to an address */ 26 | unsigned short count; 27 | char fmt; /* default = x -> hexadecimal */ 28 | unsigned char size; /* default = 1 (byte) */ 29 | unsigned long address; /* returned address */ 30 | char *message; /* error message (or NULL) */ 31 | char *data; /* current data */ 32 | char *prev; /* old data (for checking changes) */ 33 | int columns; /* reset to 0 on parsing a new memory block */ 34 | float addr_width, item_width; 35 | } MEMDUMP; 36 | 37 | void memdump_init(MEMDUMP *memdump); 38 | void memdump_cleanup(MEMDUMP *memdump); 39 | int memdump_validate(MEMDUMP *memdump); 40 | int memdump_parse(const char *gdbresult, MEMDUMP *memdump); 41 | void memdump_widget(struct nk_context *ctx, MEMDUMP *memdump, float widgetheight, float rowheight); 42 | 43 | #endif /* _MEMDUMP_H*/ 44 | -------------------------------------------------------------------------------- /source/minGlue.h: -------------------------------------------------------------------------------- 1 | /* Glue functions for the minIni library, based on the C/C++ stdio library 2 | * 3 | * Or better said: this file contains macros that maps the function interface 4 | * used by minIni to the standard C/C++ file I/O functions. 5 | * 6 | * By CompuPhase, 2008-2014 7 | * This "glue file" is in the public domain. It is distributed without 8 | * warranties or conditions of any kind, either express or implied. 9 | */ 10 | 11 | /* map required file I/O types and functions to the standard C library */ 12 | #include 13 | 14 | #define INI_FILETYPE FILE* 15 | #define ini_openread(filename,file) ((*(file) = fopen((filename),"rb")) != NULL) 16 | #define ini_openwrite(filename,file) ((*(file) = fopen((filename),"wb")) != NULL) 17 | #define ini_openrewrite(filename,file) ((*(file) = fopen((filename),"r+b")) != NULL) 18 | #define ini_close(file) (fclose(*(file)) == 0) 19 | #define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL) 20 | #define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0) 21 | #define ini_rename(source,dest) (rename((source), (dest)) == 0) 22 | #define ini_remove(filename) (remove(filename) == 0) 23 | 24 | #define INI_FILEPOS long int 25 | #define ini_tell(file,pos) (*(pos) = ftell(*(file))) 26 | #define ini_seek(file,pos) (fseek(*(file), *(pos), SEEK_SET) == 0) 27 | 28 | /* for floating-point support, define additional types and functions */ 29 | #define INI_REAL float 30 | #define ini_ftoa(string,value) sprintf((string),"%f",(value)) 31 | #define ini_atof(string) (INI_REAL)strtod((string),NULL) 32 | -------------------------------------------------------------------------------- /source/nuklear_config.h: -------------------------------------------------------------------------------- 1 | //#define NK_BUTTON_TRIGGER_ON_RELEASE // gives problems with dragging scroll bars 2 | #define NK_INCLUDE_FIXED_TYPES 3 | #define NK_INCLUDE_STANDARD_VARARGS 4 | #define NK_INCLUDE_DEFAULT_ALLOCATOR 5 | #define NK_INCLUDE_STRING 6 | 7 | #if defined _WIN32 8 | #define NK_SIN 9 | #define NK_COS 10 | #endif 11 | 12 | #if defined __linux__ || defined __FreeBSD__ || defined __APPLE__ 13 | #define NK_INCLUDE_STANDARD_IO 14 | #define NK_INCLUDE_VERTEX_BUFFER_OUTPUT 15 | #define NK_INCLUDE_FONT_BAKING 16 | #define NK_KEYSTATE_BASED_INPUT 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /source/nuklear_gdip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Nuklear - 1.40.8 - public domain 3 | * no warrenty implied; use at your own risk. 4 | * authored from 2015-2017 by Micha Mettke 5 | */ 6 | /* 7 | * ============================================================== 8 | * 9 | * API 10 | * 11 | * =============================================================== 12 | */ 13 | #ifndef NK_GDIP_H_ 14 | #define NK_GDIP_H_ 15 | 16 | #define WIN32_LEAN_AND_MEAN 17 | #include 18 | #include 19 | 20 | #if defined __WATCOMC__ 21 | #define _In_ 22 | #endif 23 | 24 | /* font */ 25 | typedef struct GdipFont GdipFont; 26 | NK_API GdipFont* nk_gdipfont_create(const char *name, float size, int style); 27 | NK_API GdipFont* nk_gdipfont_create_from_file(const WCHAR* filename, float size, int style); 28 | NK_API GdipFont* nk_gdipfont_create_from_memory(const void* membuf, int membufSize, float size, int style); 29 | NK_API void nk_gdipfont_set_voffset(GdipFont *font, int voffset); 30 | NK_API void nk_gdipfont_del(GdipFont *font); 31 | 32 | NK_API struct nk_context* nk_gdip_init(HWND hwnd, unsigned int width, unsigned int height); 33 | NK_API void nk_gdip_set_font(GdipFont *font); 34 | NK_API int nk_gdip_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); 35 | NK_API void nk_gdip_render(enum nk_anti_aliasing AA, struct nk_color clear); 36 | NK_API void nk_gdip_shutdown(void); 37 | 38 | /* image */ 39 | NK_API struct nk_image nk_gdip_load_image_from_file(const WCHAR* filename); 40 | NK_API struct nk_image nk_gdip_load_image_from_memory(const void* membuf, nk_uint membufSize); 41 | NK_API void nk_gdip_image_free(struct nk_image image); 42 | 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /source/nuklear_glfw_gl2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Nuklear - v1.32.0 - public domain 3 | * no warrenty implied; use at your own risk. 4 | * authored from 2015-2017 by Micha Mettke 5 | */ 6 | /* 7 | * ============================================================== 8 | * 9 | * API 10 | * 11 | * =============================================================== 12 | */ 13 | #ifndef NK_GLFW_GL2_H_ 14 | #define NK_GLFW_GL2_H_ 15 | 16 | #include 17 | 18 | enum nk_glfw_init_state{ 19 | NK_GLFW3_DEFAULT = 0, 20 | NK_GLFW3_INSTALL_CALLBACKS 21 | }; 22 | NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state); 23 | NK_API void nk_glfw3_shutdown(void); 24 | NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas); 25 | NK_API void nk_glfw3_font_stash_end(void); 26 | 27 | NK_API void nk_glfw3_new_frame(void); 28 | NK_API void nk_glfw3_render(enum nk_anti_aliasing); 29 | 30 | NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint); 31 | NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /source/nuklear_guide.h: -------------------------------------------------------------------------------- 1 | /* 2 | * A basic control for displaying help texts. 3 | * 4 | * Copyright 2022-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _NK_GUIDE_H 20 | #define _NK_GUIDE_H 21 | 22 | #include 23 | #include "nuklear.h" 24 | 25 | bool nk_guide(struct nk_context *ctx, struct nk_rect *viewport, float fontsize, 26 | const char *content, uint32_t topic); 27 | void nk_guide_cleanup(void); 28 | 29 | #endif /* _NK_GUIDE_H */ 30 | 31 | 32 | -------------------------------------------------------------------------------- /source/nuklear_mousepointer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Setting the mouse pointer shape in Windows and in GLFW. 3 | * 4 | * Copyright 2020-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #if defined WIN32 || defined _WIN32 20 | # define STRICT 21 | # define WIN32_LEAN_AND_MEAN 22 | # include 23 | #elif defined __linux__ 24 | # include 25 | #endif 26 | 27 | #include 28 | #include "nuklear_mousepointer.h" 29 | 30 | #if defined __linux__ 31 | static GLFWcursor *cursor_hresize = NULL, *cursor_vresize = NULL, *cursor_wait = NULL; 32 | static GLFWwindow *cursor_window = NULL; 33 | #endif 34 | 35 | void pointer_init(void *window) 36 | { 37 | # if defined __linux__ 38 | cursor_window = (GLFWwindow*)window; 39 | cursor_hresize = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); 40 | cursor_vresize = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR); 41 | # if defined GLFW_NOT_ALLOWED_CURSOR 42 | cursor_wait = glfwCreateStandardCursor(GLFW_NOT_ALLOWED_CURSOR); 43 | # endif 44 | # else 45 | (void)window; 46 | # endif 47 | } 48 | 49 | void pointer_cleanup(void) 50 | { 51 | # if defined __linux__ 52 | glfwDestroyCursor(cursor_hresize); 53 | glfwDestroyCursor(cursor_vresize); 54 | if (cursor_wait != NULL) 55 | glfwDestroyCursor(cursor_wait); 56 | # endif 57 | } 58 | 59 | void pointer_setstyle(int style) 60 | { 61 | # if defined WIN32 || defined _WIN32 62 | switch (style) { 63 | case CURSOR_UPDOWN: 64 | SetCursor(LoadCursor(NULL, IDC_SIZENS)); 65 | break; 66 | case CURSOR_LEFTRIGHT: 67 | SetCursor(LoadCursor(NULL, IDC_SIZEWE)); 68 | break; 69 | case CURSOR_WAIT: 70 | SetCursor(LoadCursor(NULL, IDC_WAIT)); 71 | break; 72 | default: 73 | SetCursor(LoadCursor(NULL, IDC_ARROW)); 74 | } 75 | # elif defined __linux__ 76 | switch (style) { 77 | case CURSOR_UPDOWN: 78 | glfwSetCursor(cursor_window, cursor_vresize); 79 | break; 80 | case CURSOR_LEFTRIGHT: 81 | glfwSetCursor(cursor_window, cursor_hresize); 82 | break; 83 | case CURSOR_WAIT: 84 | glfwSetCursor(cursor_window, cursor_wait); /* resets to default it undefined */ 85 | break; 86 | default: 87 | glfwSetCursor(cursor_window, NULL); /* reset to default */ 88 | } 89 | # endif 90 | } 91 | 92 | -------------------------------------------------------------------------------- /source/nuklear_mousepointer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Setting the mouse pointer shape in Windows and in GLFW. 3 | * 4 | * Copyright 2020-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _MOUSECURSOR_h 19 | #define _MOUSECURSOR_h 20 | 21 | enum { 22 | CURSOR_NORMAL = 0, 23 | CURSOR_UPDOWN = 0x01, 24 | CURSOR_LEFTRIGHT = 0x02, 25 | CURSOR_WAIT = 0x04, 26 | }; 27 | 28 | void pointer_init(void *window); 29 | void pointer_cleanup(void); 30 | void pointer_setstyle(int style); 31 | 32 | #endif /* _MOUSECURSOR_h */ 33 | 34 | -------------------------------------------------------------------------------- /source/nuklear_msgbox.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A Nuklear control for a g_message box (which, by the design of Nuklear, is not 3 | * truly modal). 4 | * 5 | * Copyright 2024 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include "guidriver.h" 24 | #include "nuklear_msgbox.h" 25 | #include "nuklear_style.h" 26 | 27 | #define BTN_WIDTH 48 28 | #define NK_SPACING 4 29 | #define ROW_SPACING 2 30 | #define MIN_WIDTH (3 * BTN_WIDTH) 31 | 32 | static bool is_active = false; 33 | static char *g_message = NULL; 34 | static char *g_caption = NULL; 35 | static float row_height = 0; 36 | static float font_height = 0; 37 | static struct nk_rect popup_rc; 38 | 39 | /** nk_msgbox() sets up a message box. To show the message box, you must call 40 | * nk_msgbox_popup() from within the GUI loop. 41 | */ 42 | bool nk_msgbox(struct nk_context *ctx, const char *message, const char *caption) 43 | { 44 | assert(ctx != NULL); 45 | assert(message != NULL); 46 | assert(caption != NULL); 47 | 48 | /* initialize fields */ 49 | const struct nk_style *style = &ctx->style; 50 | struct nk_vec2 padding = style->window.padding; 51 | font_height = style->font->height; 52 | row_height = 1.6f * font_height; 53 | g_message = strdup(message); 54 | if (g_message == NULL) 55 | return false; 56 | g_caption = strdup(caption); 57 | if (g_caption == NULL) { 58 | free(g_message); 59 | return false; 60 | } 61 | 62 | /* calculate text size */ 63 | float text_width = 0; 64 | int num_lines = 0; 65 | char *head, *tail; 66 | for (head = g_message; *head != '\0'; head = tail) { 67 | tail = strchr(head, '\n'); 68 | if (!tail) 69 | tail = strchr(head, '\0'); 70 | float width = style->font->width(style->font->userdata, 71 | style->font->height, head, 72 | (int)(tail - head)); 73 | if (width > text_width) 74 | text_width = width; 75 | if (*tail == '\n') 76 | tail++; 77 | num_lines++; 78 | } 79 | 80 | int canvas_width, canvas_height; 81 | guidriver_appsize(&canvas_width, &canvas_height); 82 | 83 | float contents_width = text_width + 3 * NK_SPACING; 84 | if (contents_width < MIN_WIDTH) 85 | contents_width = MIN_WIDTH; 86 | float contents_height = num_lines * (font_height + 2 * padding.y) + row_height + ROW_SPACING + 5 * NK_SPACING; 87 | if (caption != NULL) 88 | contents_height += font_height + NK_SPACING + ROW_SPACING + 4 * NK_SPACING; 89 | popup_rc = nk_rect((canvas_width - contents_width) / 2, 90 | (canvas_height - contents_height) / 2, 91 | contents_width, contents_height); 92 | is_active = true; 93 | 94 | return true; 95 | } 96 | 97 | /** nk_msgbox_popup() displays a message box, if one was set up and active. 98 | * \return While the message box is active, the return value is MSGBOX_ACTIVE. 99 | * When the message box is closed, the function returns the 100 | * MSGBOX_CLOSE once, and after that it returns MSGBOX_INACTIVE. 101 | */ 102 | int nk_msgbox_popup(struct nk_context *ctx) 103 | { 104 | if (!is_active) 105 | return MSGBOX_INACTIVE; 106 | 107 | int msgbox_result = MSGBOX_ACTIVE; 108 | 109 | nk_style_push_color(ctx, &ctx->style.window.fixed_background.data.color, COLOUR_BG0_S); 110 | nk_style_push_color(ctx, &ctx->style.window.popup_border_color, COLOUR_BG_YELLOW); 111 | nk_style_push_float(ctx, &ctx->style.window.popup_border, 2); 112 | if (nk_popup_begin(ctx, NK_POPUP_STATIC, "MsgBox", NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BORDER, popup_rc)) { 113 | struct nk_rect widgetbounds = nk_layout_widget_bounds(ctx); 114 | 115 | if (g_caption != NULL) { 116 | nk_layout_row_dynamic(ctx, font_height + NK_SPACING, 1); 117 | nk_layout_row_background(ctx, COLOUR_BG_BLUE); 118 | int font = guidriver_setfont(ctx, FONT_BOLD); 119 | nk_text_colored(ctx, g_caption, strlen(g_caption), NK_TEXT_ALIGN_BOTTOM|NK_TEXT_ALIGN_CENTERED, COLOUR_BG0); 120 | guidriver_setfont(ctx, font); 121 | nk_layout_row_dynamic(ctx, ROW_SPACING, 1); 122 | nk_spacing(ctx, 1); 123 | } 124 | 125 | const char *head, *tail; 126 | for (head = g_message; *head != '\0'; head = tail) { 127 | tail = strchr(head, '\n'); 128 | if (!tail) 129 | tail = strchr(head, '\0'); 130 | nk_layout_row_dynamic(ctx, font_height, 1); 131 | nk_text(ctx, head, (int)(tail - head), NK_TEXT_LEFT); 132 | if (*tail == '\n') 133 | tail++; 134 | } 135 | 136 | nk_layout_row_dynamic(ctx, ROW_SPACING, 1); 137 | nk_spacing(ctx, 1); 138 | nk_layout_row_begin(ctx, NK_STATIC, row_height, 2); 139 | float spacewidth = widgetbounds.w - BTN_WIDTH - NK_SPACING; 140 | nk_layout_row_push(ctx, spacewidth); 141 | nk_spacing(ctx, 1); 142 | nk_layout_row_push(ctx, BTN_WIDTH); 143 | if (nk_button_label(ctx, "Close") || nk_input_is_key_pressed(&ctx->input, NK_KEY_ESCAPE)) { 144 | is_active = false; 145 | msgbox_result = MSGBOX_CLOSE; 146 | free(g_message); 147 | g_message = NULL; 148 | free(g_caption); 149 | g_caption = NULL; 150 | nk_popup_close(ctx); 151 | } 152 | nk_layout_row_end(ctx); 153 | 154 | nk_popup_end(ctx); 155 | } 156 | nk_style_pop_float(ctx); 157 | nk_style_pop_color(ctx); 158 | nk_style_pop_color(ctx); 159 | 160 | return msgbox_result; 161 | } 162 | 163 | -------------------------------------------------------------------------------- /source/nuklear_msgbox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * A Nuklear control for a message box (which, by the design of Nuklear, is not 3 | * truly modal). 4 | * 5 | * Copyright 2024 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #ifndef _NK_MSGBOX_H 21 | #define _NK_MSGBOX_H 22 | 23 | #include 24 | #include "nuklear.h" 25 | 26 | enum { 27 | MSGBOX_INACTIVE = -1, 28 | MSGBOX_ACTIVE, 29 | MSGBOX_CLOSE, 30 | }; 31 | 32 | bool nk_msgbox(struct nk_context *ctx, const char *message, const char *caption); 33 | int nk_msgbox_popup(struct nk_context *ctx); 34 | 35 | #endif /* _NK_MSGBOX_H */ 36 | -------------------------------------------------------------------------------- /source/nuklear_splitter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Support functions for splitter bars. 3 | * 4 | * Copyright 2021-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _NK_SPLITTER_H 20 | #define _NK_SPLITTER_H 21 | 22 | #include "nuklear.h" 23 | 24 | #define RESIZE_PROPORTIONAL 0 25 | #define RESIZE_TOPLEFT 1 26 | #define RESIZE_BOTTOMRIGHT 2 27 | 28 | typedef struct tagSPLITTERBAR { 29 | float size; /* total width/height */ 30 | float ratio; /* position of the splitter bar, in percentage of the total size */ 31 | float barsize; /* width/height of the splitter bar */ 32 | nk_bool hover; 33 | nk_bool dragging; 34 | /* ----- */ 35 | float ratio_new;/* updated ratio after dragging, copied to "ratio" on a resize */ 36 | float parts[3]; /* internal use: column widths, Nuklear keeps a pointer to this array, so it must stay valid */ 37 | } SPLITTERBAR; 38 | 39 | void nk_splitter_init(SPLITTERBAR *splitter, float size, float bar_width, float ratio); 40 | void nk_splitter_resize(SPLITTERBAR *splitter, float size, int resize_part); 41 | 42 | void nk_hsplitter_layout(struct nk_context *ctx, SPLITTERBAR *splitter, float height); 43 | float nk_hsplitter_colwidth(SPLITTERBAR *splitter, int column); 44 | void nk_hsplitter(struct nk_context *ctx, SPLITTERBAR *splitter); 45 | 46 | float nk_vsplitter_rowheight(SPLITTERBAR *splitter, int row); 47 | void nk_vsplitter(struct nk_context *ctx, SPLITTERBAR *splitter); 48 | 49 | typedef struct tagSIZERBAR { 50 | float size; /* content width/height */ 51 | float minsize; /* minimum size for the content */ 52 | float barsize; /* width/height of the splitter bar */ 53 | nk_bool hover; 54 | nk_bool dragging; 55 | /* ----- */ 56 | float size_new;/* updated size after dragging, copied to "size" on a refresh */ 57 | } SIZERBAR; 58 | 59 | void nk_sizer_init(SIZERBAR *sizer, float size, float minsize, float bar_width); 60 | void nk_sizer_refresh(SIZERBAR *sizer); 61 | void nk_sizer(struct nk_context *ctx, SIZERBAR *sizer); 62 | 63 | #endif /* _NK_SPLITTER_H */ 64 | 65 | 66 | -------------------------------------------------------------------------------- /source/nuklear_style.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Common styling & layout functions for the Nuklear GUI. 3 | * 4 | * Copyright 2021-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include "nuklear_style.h" 23 | 24 | void nuklear_style(struct nk_context *ctx) 25 | { 26 | struct nk_color table[NK_COLOR_COUNT]; 27 | 28 | assert(ctx != NULL); 29 | 30 | /* adapted from gruvbox palette */ 31 | table[NK_COLOR_TEXT] = nk_rgb_hex("#ebdbb2"); /* fg */ 32 | table[NK_COLOR_TEXT_GRAY]= nk_rgb_hex("#a89984"); /* gray-b */ 33 | table[NK_COLOR_WINDOW] = nk_rgb_hex("#32302f"); /* bg0_s */ 34 | table[NK_COLOR_HEADER] = nk_rgb_hex("#076678"); /* blue-b */ 35 | table[NK_COLOR_BORDER] = nk_rgb_hex("#928374"); /* gray-f */ 36 | table[NK_COLOR_BUTTON] = nk_rgb_hex("#104b5b"); 37 | table[NK_COLOR_BUTTON_HOVER] = nk_rgb_hex("#076678"); /* blue-f in light mode */ 38 | table[NK_COLOR_BUTTON_ACTIVE] = nk_rgb_hex("#076678"); /* blue-f in light mode */ 39 | table[NK_COLOR_TOGGLE] = nk_rgb_hex("#1d2021"); /* bg0_h */ 40 | table[NK_COLOR_TOGGLE_HOVER] = nk_rgb_hex("#928374"); /* gray-f */ 41 | table[NK_COLOR_TOGGLE_CURSOR] = nk_rgb_hex("#458588"); /* blue-b */ 42 | table[NK_COLOR_SELECT] = nk_rgb_hex("#1d2021"); /* bg0_h */ 43 | table[NK_COLOR_SELECT_ACTIVE] = nk_rgb_hex("#fabd2f"); /* yellow-f */ 44 | table[NK_COLOR_SLIDER] = nk_rgb_hex("#1d2021"); /* bg0_h */ 45 | table[NK_COLOR_SLIDER_CURSOR] = nk_rgb_hex("#d79921"); /* yellow-b */ 46 | table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgb_hex("#fabd2f"); /* yellow-f */ 47 | table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgb_hex("#fabd2f"); /* yellow-f */ 48 | table[NK_COLOR_PROPERTY] = nk_rgb_hex("#1d2021"); /* bg0_h */ 49 | table[NK_COLOR_EDIT] = nk_rgb_hex("#1d2021"); /* bg0_h */ 50 | table[NK_COLOR_EDIT_CURSOR] = nk_rgb_hex("#fbf1c7"); /* fg0 (bg0 in light mode) */ 51 | table[NK_COLOR_COMBO] = nk_rgb_hex("#1d2021"); /* bg0_h */ 52 | table[NK_COLOR_CHART] = nk_rgb_hex("#1d2021"); /* bg0_h */ 53 | table[NK_COLOR_CHART_COLOR] = nk_rgb_hex("#cc241d"); /* red-b */ 54 | table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgb_hex("#fb4934"); /* red-f */ 55 | table[NK_COLOR_SCROLLBAR] = nk_rgb_hex("#1d2021"); /* bg0_h */ 56 | table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgb_hex("#928374"); /* gray-f */ 57 | table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgb_hex("#a899a4"); /* gray-b */ 58 | table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgb_hex("#a899a4");/* gray-b */ 59 | table[NK_COLOR_TAB_HEADER] = nk_rgb_hex("#104b5b"); 60 | table[NK_COLOR_TOOLTIP] = nk_rgb_hex("#fbf1c7"); /* bg0 in light mode, also fg0 */ 61 | table[NK_COLOR_TOOLTIP_TEXT] = nk_rgb_hex("#3c3836"); /* fg in light mode, also bg1 */ 62 | 63 | nk_style_from_table(ctx, table); 64 | 65 | /* button */ 66 | ctx->style.button.rounding = 0; 67 | ctx->style.button.padding.x = 2; 68 | } 69 | 70 | float *nk_ratio(int count, ...) 71 | { 72 | # define MAX_ROW_FIELDS 10 73 | static float r_array[MAX_ROW_FIELDS]; 74 | va_list ap; 75 | int i; 76 | 77 | assert(count < MAX_ROW_FIELDS); 78 | va_start(ap, count); 79 | for (i = 0; i < count; i++) 80 | r_array[i] = (float) va_arg(ap, double); 81 | va_end(ap); 82 | return r_array; 83 | } 84 | 85 | /** editctrl_cond_color() sets the background colour of an edit control if 86 | * the condition is true. The original colours are pushed on the Nuklear stack, 87 | * and must be restored with editctrl_reset_color(). 88 | * 89 | * The function returns the "condition" parameter. 90 | */ 91 | bool editctrl_cond_color(struct nk_context *ctx, bool condition, struct nk_color color) 92 | { 93 | if (condition) { 94 | nk_style_push_color(ctx, &ctx->style.edit.normal.data.color, color); 95 | nk_style_push_color(ctx, &ctx->style.edit.hover.data.color, color); 96 | nk_style_push_color(ctx, &ctx->style.edit.active.data.color, color); 97 | } 98 | return condition; 99 | } 100 | 101 | void editctrl_reset_color(struct nk_context *ctx, bool condition) 102 | { 103 | if (condition) { 104 | nk_style_pop_color(ctx); 105 | nk_style_pop_color(ctx); 106 | nk_style_pop_color(ctx); 107 | } 108 | } 109 | 110 | struct nk_color default_channel_colour(int channel) 111 | { 112 | channel %= 8; 113 | switch (channel) { 114 | case 0: 115 | return COLOUR_BG_GRAY; 116 | case 1: 117 | return COLOUR_BG_AQUA; 118 | case 2: 119 | return COLOUR_BG_PURPLE; 120 | case 3: 121 | return COLOUR_BG_BLUE; 122 | case 4: 123 | return COLOUR_BG_YELLOW; 124 | case 5: 125 | return COLOUR_BG_GREEN; 126 | case 6: 127 | return COLOUR_BG_RED; 128 | case 7: 129 | return COLOUR_BG_ORANGE; 130 | } 131 | return COLOUR_BG_GRAY; 132 | } 133 | 134 | struct nk_color severity_bkgnd(int severity) 135 | { 136 | switch (severity) { 137 | case 0: 138 | return COLOUR_BG_BLUE; /* debug */ 139 | case 2: 140 | return COLOUR_BG_AQUA; /* notice */ 141 | case 3: 142 | return COLOUR_BG_YELLOW; /* warning */ 143 | case 4: 144 | return COLOUR_BG_ORANGE; /* error */ 145 | case 5: 146 | return COLOUR_BG_RED; /* critical */ 147 | } 148 | return COLOUR_BG0_S; /* info, or parameter out of range */ 149 | } 150 | -------------------------------------------------------------------------------- /source/nuklear_style.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Common styling & layout functions for the Nuklear GUI. 3 | * 4 | * Copyright 2021-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _NUKLEAR_STYLE_H 20 | #define _NUKLEAR_STYLE_H 21 | 22 | #include 23 | #include "nuklear.h" 24 | 25 | void nuklear_style(struct nk_context *ctx); 26 | float *nk_ratio(int count, ...); 27 | bool editctrl_cond_color(struct nk_context *ctx, bool condition, struct nk_color color); 28 | void editctrl_reset_color(struct nk_context *ctx, bool condition); 29 | struct nk_color default_channel_colour(int channel); 30 | struct nk_color severity_bkgnd(int severity); 31 | 32 | #define COLOUR_BG0_S nk_rgb_hex("#32302f") /* window background colour */ 33 | #define COLOUR_BG0 nk_rgb_hex("#1d2021") /* background colour for controls near black) */ 34 | #define COLOUR_BG_DARKRED nk_rgb_hex("#9d0006") 35 | #define COLOUR_BG_RED nk_rgb_hex("#cc241d") 36 | #define COLOUR_BG_GREEN nk_rgb_hex("#78a71a") 37 | #define COLOUR_BG_YELLOW nk_rgb_hex("#d79921") 38 | #define COLOUR_BG_BLUE nk_rgb_hex("#458588") 39 | #define COLOUR_BG_PURPLE nk_rgb_hex("#b16286") 40 | #define COLOUR_BG_AQUA nk_rgb_hex("#689d6a") 41 | #define COLOUR_BG_GRAY nk_rgb_hex("#a89984") 42 | #define COLOUR_BG_ORANGE nk_rgb_hex("#d65d0e") 43 | #define COLOUR_BG_BUTTON nk_rgb_hex("#104b5b") 44 | #define COLOUR_TEXT nk_rgb_hex("#ebdbb2") 45 | #define COLOUR_HIGHLIGHT nk_rgb_hex("#abcfff") /* highlighted text */ 46 | #define COLOUR_FG_GRAY nk_rgb_hex("#928374") /* disabled text */ 47 | #define COLOUR_FG_RED nk_rgb_hex("#fb4934") 48 | #define COLOUR_FG_YELLOW nk_rgb_hex("#fabd2f") 49 | #define COLOUR_FG_GREEN nk_rgb_hex("#0ad074") 50 | #define COLOUR_FG_CYAN nk_rgb_hex("#83a598") 51 | #define COLOUR_FG_PURPLE nk_rgb_hex("#d3869b") 52 | #define COLOUR_FG_AQUA nk_rgb_hex("#8ec07c") 53 | 54 | #define CONTRAST_COLOUR(c) (((3*(c).r + 5*(c).g + 2*(c).b) >= 1100) ? COLOUR_BG0 : COLOUR_HIGHLIGHT) 55 | 56 | #endif /* _NUKLEAR_STYLE_H */ 57 | -------------------------------------------------------------------------------- /source/nuklear_tooltip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tooltip with delay for the Nuklear GUI. 3 | * 4 | * Copyright 2019-2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _NK_TOOLTIP_H 20 | #define _NK_TOOLTIP_H 21 | 22 | #include "nuklear.h" 23 | 24 | #define TOOLTIP_DELAY 1000 /* in ms, time that the mouse pointer must hover 25 | over the control before the tooltip pops up */ 26 | #define TOOLTIP_TIMEOUT 6000 /* in ms, time that the tooltip stays visible */ 27 | 28 | unsigned long timestamp(void); 29 | int tooltip(struct nk_context *ctx, struct nk_rect bounds, const char *text); 30 | 31 | void label_tooltip(struct nk_context *ctx, const char *label, nk_flags align, const char *tiptext); 32 | nk_bool button_tooltip(struct nk_context *ctx, const char *label, 33 | enum nk_keys hotkey, nk_bool enabled, 34 | const char *tiptext); 35 | nk_bool button_styled_tooltip(struct nk_context *ctx, const char *label, 36 | enum nk_keys hotkey, const struct nk_style_button *style, 37 | const char *tiptext); 38 | nk_bool button_symbol_tooltip(struct nk_context *ctx, enum nk_symbol_type symbol, 39 | enum nk_keys hotkey, nk_bool enabled, const char *tiptext); 40 | nk_bool checkbox_tooltip(struct nk_context *ctx, const char *label, 41 | nk_bool *active, nk_flags align, const char *tiptext); 42 | nk_bool option_tooltip(struct nk_context *ctx, const char *label, nk_bool active, 43 | nk_flags align, const char *tiptext); 44 | nk_flags editctrl_tooltip(struct nk_context *ctx, nk_flags flags, 45 | char *buffer, int max, nk_plugin_filter filter, 46 | const char *tiptext); 47 | 48 | #endif /* _NK_TOOLTIP_H */ 49 | 50 | -------------------------------------------------------------------------------- /source/osdialog.c: -------------------------------------------------------------------------------- 1 | /* Written by Andrew Belt 2 | * https://github.com/AndrewBelt/osdialog 3 | * Distributed under the Creative Commons CC0 Public Domain license 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include "osdialog.h" 9 | 10 | #if defined _MSC_VER 11 | # if _MSC_VER < 1900 12 | # include "c99_snprintf.h" 13 | # endif 14 | #endif 15 | 16 | #if defined FORTIFY 17 | # include 18 | #endif 19 | 20 | 21 | char* osdialog_strdup(const char* s) { 22 | return osdialog_strndup(s, strlen(s)); 23 | } 24 | 25 | char* osdialog_strndup(const char* s, size_t n) { 26 | char* d = OSDIALOG_MALLOC(n + 1); 27 | memcpy(d, s, n); 28 | d[n] = '\0'; 29 | return d; 30 | } 31 | 32 | osdialog_filters* osdialog_filters_parse(const char* str) { 33 | osdialog_filters* filters_head = OSDIALOG_MALLOC(sizeof(osdialog_filters)); 34 | filters_head->next = NULL; 35 | 36 | osdialog_filters* filters = filters_head; 37 | osdialog_filter_patterns* patterns = NULL; 38 | 39 | const char* text = str; 40 | while (1) { 41 | switch (*str) { 42 | case ':': { 43 | filters->name = osdialog_strndup(text, str - text); 44 | filters->patterns = OSDIALOG_MALLOC(sizeof(osdialog_filter_patterns)); 45 | patterns = filters->patterns; 46 | patterns->next = NULL; 47 | text = str + 1; 48 | } break; 49 | case ',': { 50 | assert(patterns); 51 | patterns->pattern = osdialog_strndup(text, str - text); 52 | patterns->next = OSDIALOG_MALLOC(sizeof(osdialog_filter_patterns)); 53 | patterns = patterns->next; 54 | patterns->next = NULL; 55 | text = str + 1; 56 | } break; 57 | case ';': { 58 | assert(patterns); 59 | patterns->pattern = osdialog_strndup(text, str - text); 60 | filters->next = OSDIALOG_MALLOC(sizeof(osdialog_filters)); 61 | filters = filters->next; 62 | filters->next = NULL; 63 | patterns = NULL; 64 | text = str + 1; 65 | } break; 66 | case '\0': { 67 | assert(patterns); 68 | patterns->pattern = osdialog_strndup(text, str - text); 69 | } break; 70 | default: break; 71 | } 72 | if (!*str) 73 | break; 74 | str++; 75 | } 76 | 77 | return filters_head; 78 | } 79 | 80 | void osdialog_filter_patterns_free(osdialog_filter_patterns* patterns) { 81 | if (!patterns) 82 | return; 83 | OSDIALOG_FREE(patterns->pattern); 84 | osdialog_filter_patterns* next = patterns->next; 85 | OSDIALOG_FREE(patterns); 86 | osdialog_filter_patterns_free(next); 87 | } 88 | 89 | void osdialog_filters_free(osdialog_filters* filters) { 90 | if (!filters) 91 | return; 92 | OSDIALOG_FREE(filters->name); 93 | osdialog_filter_patterns_free(filters->patterns); 94 | osdialog_filters* next = filters->next; 95 | OSDIALOG_FREE(filters); 96 | osdialog_filters_free(next); 97 | } 98 | -------------------------------------------------------------------------------- /source/osdialog.h: -------------------------------------------------------------------------------- 1 | /* Written by Andrew Belt 2 | * https://github.com/AndrewBelt/osdialog 3 | * Distributed under the Creative Commons CC0 Public Domain license 4 | */ 5 | #ifndef _OSDIALOG_H 6 | #define _OSDIALOG_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | 13 | #include 14 | #include 15 | 16 | 17 | #ifndef OSDIALOG_MALLOC 18 | #define OSDIALOG_MALLOC malloc 19 | #endif 20 | 21 | #ifndef OSDIALOG_FREE 22 | #define OSDIALOG_FREE free 23 | #endif 24 | 25 | 26 | char* osdialog_strdup(const char* s); 27 | char* osdialog_strndup(const char* s, size_t n); 28 | 29 | 30 | typedef enum { 31 | OSDIALOG_INFO, 32 | OSDIALOG_WARNING, 33 | OSDIALOG_ERROR, 34 | } osdialog_message_level; 35 | 36 | typedef enum { 37 | OSDIALOG_OK, 38 | OSDIALOG_OK_CANCEL, 39 | OSDIALOG_YES_NO, 40 | } osdialog_message_buttons; 41 | 42 | /** Launches a message box. 43 | 44 | Returns 1 if the "OK" or "Yes" button was pressed. 45 | */ 46 | int osdialog_message(osdialog_message_level level, osdialog_message_buttons buttons, const char* message); 47 | 48 | /** Launches an input prompt with an "OK" and "Cancel" button. 49 | 50 | `text` is the default string to fill the input box. 51 | 52 | Returns the entered text, or NULL if the dialog was cancelled. 53 | If the returned result is not NULL, caller must free() it. 54 | 55 | TODO: Implement on Windows and GTK2. 56 | */ 57 | char* osdialog_prompt(osdialog_message_level level, const char* message, const char* text); 58 | 59 | 60 | /** Linked list of patterns. */ 61 | typedef struct osdialog_filter_patterns { 62 | char* pattern; 63 | struct osdialog_filter_patterns* next; 64 | } osdialog_filter_patterns; 65 | 66 | /** Linked list of file filters. */ 67 | typedef struct osdialog_filters { 68 | char* name; 69 | osdialog_filter_patterns* patterns; 70 | struct osdialog_filters* next; 71 | } osdialog_filters; 72 | 73 | /** Parses a filter string. 74 | Example: "Source:c,cpp,m;Header:h,hpp" 75 | Caller must eventually free with osdialog_filters_free(). 76 | */ 77 | osdialog_filters* osdialog_filters_parse(const char* str); 78 | void osdialog_filter_patterns_free(osdialog_filter_patterns* patterns); 79 | void osdialog_filters_free(osdialog_filters* filters); 80 | 81 | 82 | typedef enum { 83 | OSDIALOG_OPEN, 84 | OSDIALOG_OPEN_DIR, 85 | OSDIALOG_SAVE, 86 | } osdialog_file_action; 87 | 88 | /** Launches a file dialog and returns the selected path or NULL if nothing was selected. 89 | * 90 | * \param action `OSDIALOG_OPEN_DIR`, `OSDIALOG_OPEN_DIR` or `OSDIALOG_SAVE`. 91 | * \param title The caption of the dialog, or NULL for the default. 92 | * \param path The *default* folder the file dialog will attempt to open 93 | * in, or NULL for the OS's default. 94 | * \param filename The default text that will appear in the filename. input,or 95 | * NULL for the OS's default. Relevant to save dialog only. 96 | * \param filters A list of patterns to filter the file selection, or NULL. 97 | * 98 | * \return The selected file, or NULL if the dialog was cancelled. 99 | If the return result is not NULL, caller must free() it. 100 | */ 101 | char* osdialog_file(osdialog_file_action action, const char* title, const char* path, const char* filename, osdialog_filters* filters); 102 | 103 | 104 | typedef struct { 105 | uint8_t r, g, b, a; 106 | } osdialog_color; 107 | 108 | /** Launches an RGBA color picker dialog and sets `color` to the selected color. 109 | Returns 1 if "OK" was pressed. 110 | 111 | `color` should be set to the initial color before calling. It is only overwritten if the user selects "OK". 112 | `opacity` enables the opacity slider by setting to 1. Not supported on Windows. 113 | 114 | TODO Implement on Mac. 115 | */ 116 | int osdialog_color_picker(osdialog_color* color, int opacity); 117 | 118 | 119 | #ifdef __cplusplus 120 | } 121 | #endif 122 | 123 | #endif /* _OSDIALOG_H */ 124 | 125 | -------------------------------------------------------------------------------- /source/osdialog_gtk2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "osdialog.h" 4 | 5 | #if defined FORTIFY 6 | # include 7 | #endif 8 | 9 | 10 | int osdialog_message(osdialog_message_level level, osdialog_message_buttons buttons, const char* message) { 11 | if (!gtk_init_check(NULL, NULL)) 12 | return 0; 13 | 14 | GtkMessageType messageType; 15 | switch (level) { 16 | default: 17 | case OSDIALOG_INFO: messageType = GTK_MESSAGE_INFO; break; 18 | case OSDIALOG_WARNING: messageType = GTK_MESSAGE_WARNING; break; 19 | case OSDIALOG_ERROR: messageType = GTK_MESSAGE_ERROR; break; 20 | } 21 | 22 | GtkButtonsType buttonsType; 23 | switch (buttons) { 24 | default: 25 | case OSDIALOG_OK: buttonsType = GTK_BUTTONS_OK; break; 26 | case OSDIALOG_OK_CANCEL: buttonsType = GTK_BUTTONS_OK_CANCEL; break; 27 | case OSDIALOG_YES_NO: buttonsType = GTK_BUTTONS_YES_NO; break; 28 | } 29 | 30 | GtkWidget* dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, messageType, buttonsType, "%s", message); 31 | 32 | gint result = gtk_dialog_run(GTK_DIALOG(dialog)); 33 | gtk_widget_destroy(dialog); 34 | 35 | while (gtk_events_pending()) 36 | gtk_main_iteration(); 37 | 38 | return (result == GTK_RESPONSE_OK || result == GTK_RESPONSE_YES); 39 | } 40 | 41 | 42 | char* osdialog_prompt(osdialog_message_level level, const char* message, const char* text) { 43 | if (!gtk_init_check(NULL, NULL)) 44 | return 0; 45 | 46 | GtkMessageType messageType; 47 | switch (level) { 48 | default: 49 | case OSDIALOG_INFO: messageType = GTK_MESSAGE_INFO; break; 50 | case OSDIALOG_WARNING: messageType = GTK_MESSAGE_WARNING; break; 51 | case OSDIALOG_ERROR: messageType = GTK_MESSAGE_ERROR; break; 52 | } 53 | 54 | GtkWidget* dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, messageType, GTK_BUTTONS_OK_CANCEL, "%s", message); 55 | 56 | GtkWidget* entry = gtk_entry_new(); 57 | gtk_entry_set_text(GTK_ENTRY(entry), text); 58 | 59 | GtkWidget* content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); 60 | gtk_container_add(GTK_CONTAINER(content_area), entry); 61 | gtk_widget_show_all(dialog); 62 | 63 | gint button = gtk_dialog_run(GTK_DIALOG(dialog)); 64 | const char* result_str = gtk_entry_get_text(GTK_ENTRY(entry)); 65 | 66 | char* result = NULL; 67 | if (button == GTK_RESPONSE_OK) { 68 | result = osdialog_strndup(result_str, strlen(result_str)); 69 | } 70 | gtk_widget_destroy(dialog); 71 | 72 | while (gtk_events_pending()) 73 | gtk_main_iteration(); 74 | 75 | return result; 76 | } 77 | 78 | 79 | char* osdialog_file(osdialog_file_action action, const char* title, const char* dir, const char* filename, osdialog_filters* filters) { 80 | if (!gtk_init_check(NULL, NULL)) 81 | return 0; 82 | 83 | GtkFileChooserAction gtkAction; 84 | const char* acceptText; 85 | if (action == OSDIALOG_OPEN) { 86 | if (title == NULL) 87 | title = "Open File"; 88 | acceptText = "Open"; 89 | gtkAction = GTK_FILE_CHOOSER_ACTION_OPEN; 90 | } 91 | else if (action == OSDIALOG_OPEN_DIR) { 92 | if (title == NULL) 93 | title = "Open Folder"; 94 | acceptText = "Open Folder"; 95 | gtkAction = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; 96 | } 97 | else { 98 | if (title == NULL) 99 | title = "Save File"; 100 | acceptText = "Save"; 101 | gtkAction = GTK_FILE_CHOOSER_ACTION_SAVE; 102 | } 103 | 104 | GtkWidget* dialog = gtk_file_chooser_dialog_new( 105 | title, 106 | NULL, 107 | gtkAction, 108 | "_Cancel", GTK_RESPONSE_CANCEL, 109 | acceptText, GTK_RESPONSE_ACCEPT, 110 | NULL); 111 | 112 | for (; filters; filters = filters->next) { 113 | GtkFileFilter* fileFilter = gtk_file_filter_new(); 114 | gtk_file_filter_set_name(fileFilter, filters->name); 115 | for (osdialog_filter_patterns* patterns = filters->patterns; patterns; patterns = patterns->next) { 116 | char patternBuf[1024]; 117 | if (patterns->pattern[0] == '*' && patterns->pattern[1] == '\0') 118 | strcpy(patternBuf, "*"); /* avoid *.* on Linux */ 119 | else 120 | snprintf(patternBuf, sizeof(patternBuf), "*.%s", patterns->pattern); 121 | gtk_file_filter_add_pattern(fileFilter, patternBuf); 122 | } 123 | gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), fileFilter); 124 | } 125 | 126 | if (action == OSDIALOG_SAVE) 127 | gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); 128 | 129 | if (dir) 130 | gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir); 131 | 132 | if (action == OSDIALOG_SAVE && filename) 133 | gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename); 134 | 135 | char* chosen_filename = NULL; 136 | if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { 137 | chosen_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); 138 | } 139 | gtk_widget_destroy(dialog); 140 | 141 | char* result = NULL; 142 | if (chosen_filename) { 143 | result = osdialog_strndup(chosen_filename, strlen(chosen_filename)); 144 | g_free(chosen_filename); 145 | } 146 | 147 | while (gtk_events_pending()) 148 | gtk_main_iteration(); 149 | return result; 150 | } 151 | 152 | 153 | int osdialog_color_picker(osdialog_color* color, int opacity) { 154 | if (!color) 155 | return 0; 156 | if (!gtk_init_check(NULL, NULL)) 157 | return 0; 158 | 159 | #ifdef OSDIALOG_GTK3 160 | GtkWidget* dialog = gtk_color_chooser_dialog_new("Color", NULL); 161 | GtkColorChooser* colorsel = GTK_COLOR_CHOOSER(dialog); 162 | gtk_color_chooser_set_use_alpha(colorsel, opacity); 163 | #else 164 | GtkWidget* dialog = gtk_color_selection_dialog_new("Color"); 165 | GtkColorSelection* colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog))); 166 | gtk_color_selection_set_has_opacity_control(colorsel, opacity); 167 | #endif 168 | 169 | int result = 0; 170 | if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { 171 | #ifdef OSDIALOG_GTK3 172 | GdkRGBA c; 173 | gtk_color_chooser_get_rgba(colorsel, &c); 174 | color->r = c.red * 65535 + 0.5; 175 | color->g = c.green * 65535 + 0.5; 176 | color->b = c.blue * 65535 + 0.5; 177 | color->a = c.alpha * 65535 + 0.5; 178 | #else 179 | GdkColor c; 180 | gtk_color_selection_get_current_color(colorsel, &c); 181 | color->r = c.red >> 8; 182 | color->g = c.green >> 8; 183 | color->b = c.blue >> 8; 184 | color->a = gtk_color_selection_get_current_alpha(colorsel) >> 8; 185 | #endif 186 | 187 | result = 1; 188 | } 189 | 190 | gtk_widget_destroy(dialog); 191 | 192 | while (gtk_events_pending()) 193 | gtk_main_iteration(); 194 | return result; 195 | } 196 | -------------------------------------------------------------------------------- /source/osdialog_gtk3.c: -------------------------------------------------------------------------------- 1 | #define OSDIALOG_GTK3 2 | #include "osdialog_gtk2.c" -------------------------------------------------------------------------------- /source/pathsearch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Searching the path for a filename. 3 | * 4 | * Copyright 2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #if defined WIN32 || defined _WIN32 19 | # define STRICT 20 | # define WIN32_LEAN_AND_MEAN 21 | # include 22 | # include 23 | # if defined __MINGW32__ || defined __MINGW64__ || defined _MSC_VER 24 | # include "strlcpy.h" 25 | # endif 26 | #elif defined __linux__ 27 | # include 28 | # include 29 | #endif 30 | #include 31 | #include 32 | #include 33 | #include "pathsearch.h" 34 | 35 | #if defined _MSC_VER 36 | # define access(p,m) _access((p),(m)) 37 | # define strdup(s) _strdup(s) 38 | #endif 39 | 40 | #if defined FORTIFY 41 | # include 42 | #endif 43 | 44 | #if !defined sizearray 45 | # define sizearray(e) (sizeof(e) / sizeof((e)[0])) 46 | #endif 47 | 48 | #if !defined _MAX_PATH 49 | # define _MAX_PATH 260 50 | #endif 51 | 52 | #if defined WIN32 || defined _WIN32 53 | # define SEPARATOR ";" 54 | # define DIRSEP_CHAR '\\' 55 | # define DIRSEP_STR "\\" 56 | #else 57 | # define SEPARATOR ":" 58 | # define DIRSEP_CHAR '/' 59 | # define DIRSEP_STR "/" 60 | #endif 61 | 62 | /** pathsearch() locates a file in the path. 63 | * \param buffer [out] Contains the full path of the file on return, if the 64 | * file is found. 65 | * \param bufsize The size in characters of the buffer. 66 | * \param filename [in] The base name of the file. 67 | * \return true on success, false on failure. 68 | * \note If the function fails, parameter "buffer" is not changed. 69 | * \note If the file is found, but the "buffer" parameter is too small to 70 | * contain the full path, the function returns false (and "buffer" is not 71 | * changed). 72 | */ 73 | bool pathsearch(char *buffer, size_t bufsize, const char *filename) 74 | { 75 | assert(buffer != NULL && bufsize > 0); 76 | assert(filename != NULL); 77 | if (strlen(filename) == 0) 78 | return false; 79 | 80 | char *temp_env = getenv("PATH"); 81 | if (temp_env == NULL) 82 | return false; 83 | char *env = strdup(temp_env); 84 | 85 | bool result = false; 86 | for (char *tok = strtok(env, SEPARATOR); tok != NULL; tok = strtok(NULL, SEPARATOR)) { 87 | char path[_MAX_PATH]; 88 | strlcpy(path, tok, sizearray(path)); 89 | size_t len = strlen(path); 90 | assert(len < sizearray(path)); 91 | if (len > 0 && path[len - 1] != DIRSEP_CHAR) 92 | strlcat(path, DIRSEP_STR, sizearray(path)); 93 | strlcat(path, filename, sizearray(path)); 94 | if (access(path, 0) == 0 && strlen(path) < bufsize) { 95 | strlcpy(buffer, path, bufsize); 96 | result = true; 97 | break; 98 | } 99 | } 100 | 101 | free(env); 102 | return result; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /source/pathsearch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Searching the path for a filename. 3 | * 4 | * Copyright 2023 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _PATHSEARCH_H 19 | #define _PATHSEARCH_H 20 | 21 | #include 22 | 23 | bool pathsearch(char *buffer, size_t bufsize, const char *filename); 24 | 25 | #endif /* _PATHSEARCH_H */ 26 | -------------------------------------------------------------------------------- /source/qglib.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/qglib.c -------------------------------------------------------------------------------- /source/qglib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Support routines for QuickGuide. 3 | * 4 | * Copyright (C) 2023-2024 CompuPhase 5 | * All rights reserved. 6 | */ 7 | #ifndef __QGLIB_H 8 | #define __QGLIB_H 9 | 10 | #include 11 | #include "quickguide.h" 12 | 13 | #if defined __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | /* ***** file information ***** */ 18 | 19 | const QG_FILEHDR *qg_file_header(const void *guide); 20 | unsigned qg_topic_count(const void *guide); 21 | const QG_TOPICHDR* qg_topic_by_index(const void *guide,unsigned index); 22 | const QG_TOPICHDR* qg_topic_by_id(const void *guide,uint32_t topic); 23 | const char *qg_topic_caption(const void *guide,uint32_t topic); 24 | 25 | /* ***** links ***** */ 26 | 27 | typedef struct QG_LINK { 28 | struct QG_LINK *next; 29 | int x1,y1,x2,y2; 30 | uint32_t topic; /* topic ID */ 31 | } QG_LINK; 32 | 33 | #define QG_INVALID_LINK 0xffff 34 | 35 | void qg_link_clearall(QG_LINK *root); 36 | bool qg_link_set(QG_LINK *root,int x1,int y1,int x2,int y2,uint32_t topic); 37 | uint32_t qg_link_get(const QG_LINK *root,int x,int y); 38 | 39 | /* ***** variables ***** */ 40 | 41 | typedef struct QG_VARIABLE { 42 | struct QG_VARIABLE *next; 43 | char *name; 44 | char *value; 45 | } QG_VARIABLE; 46 | 47 | bool qg_variables_collect(const void *guide,QG_VARIABLE *root); 48 | void qg_variable_clearall(QG_VARIABLE *root); 49 | bool qg_variable_set(QG_VARIABLE *root,const char *name,const char *value); 50 | const char *qg_variable_find(const QG_VARIABLE *root,const char *name); 51 | const char *qg_variable_get(const QG_VARIABLE *root,int index); 52 | 53 | /* ***** pictures ***** */ 54 | 55 | #define QG_PIXFMT_RGB 3 56 | #define QG_PIXFMT_RGBA 4 57 | 58 | typedef struct QG_PICTURE { 59 | struct QG_PICTURE *next; 60 | unsigned id; 61 | const char *pixels; 62 | unsigned width,height; 63 | int align; 64 | unsigned format; 65 | } QG_PICTURE; 66 | 67 | void qg_picture_clearall(QG_PICTURE *root); 68 | const void *qg_picture_get(const void *guide,QG_PICTURE *root,unsigned id,unsigned *width,unsigned *height,int *align,unsigned *format); 69 | 70 | /* ***** search results ***** */ 71 | 72 | typedef struct QG_SEARCHRESULT { 73 | struct QG_SEARCHRESULT *next; 74 | uint32_t topic; /* topic ID */ 75 | unsigned line; /* line number (related to source strings, before reformatting) */ 76 | unsigned cpos; /* character position in the string */ 77 | unsigned clength; /* length of the search result */ 78 | int ypos; /* y position after most recent reformatting */ 79 | } QG_SEARCHRESULT; 80 | 81 | void qg_search_clearall(QG_SEARCHRESULT *root); 82 | bool qg_search_append(QG_SEARCHRESULT *root,uint32_t topic,int linenr,int position,int length); 83 | QG_SEARCHRESULT *qg_search_next(const QG_SEARCHRESULT *current,uint32_t topic); 84 | 85 | const char *qg_strfind(const char *pattern,const char *text,int *length,bool ignorecase,bool no_accents); 86 | 87 | /* ***** context ***** */ 88 | 89 | bool qg_passcontext(const QG_LINE_RECORD *content, unsigned long contextmask); 90 | 91 | /* ***** topic history ***** */ 92 | 93 | typedef struct QG_HISTORY_PAGE { 94 | uint32_t topic; 95 | int scrollpos; /* scroll position at the moment the page was pushed on the stack */ 96 | } QG_HISTORY_PAGE; 97 | 98 | typedef struct QG_HISTORY { 99 | QG_HISTORY_PAGE *pages; 100 | unsigned size; /* max. number of items the stack can hold */ 101 | unsigned count; /* current number of items in the stack */ 102 | unsigned pos; /* current position in the history */ 103 | } QG_HISTORY; 104 | 105 | bool qg_history_init(QG_HISTORY *stack,unsigned maxitems); 106 | void qg_history_clear(QG_HISTORY *stack); 107 | bool qg_history_push(QG_HISTORY *stack,uint32_t topic); 108 | bool qg_history_markpos(QG_HISTORY *stack,uint32_t topic,int scrollpos); 109 | bool qg_history_goback(QG_HISTORY *stack,uint32_t *topic,int *scrollpos); 110 | bool qg_history_goforward(QG_HISTORY *stack,uint32_t *topic,int *scrollpos); 111 | bool qg_history_pick(QG_HISTORY *stack,unsigned index,bool remove,uint32_t *topic,int *scrollpos); 112 | unsigned qg_history_count(QG_HISTORY *stack); 113 | 114 | #if defined __cplusplus 115 | } 116 | #endif 117 | 118 | #endif /* __QGLIB_H */ 119 | -------------------------------------------------------------------------------- /source/qoi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Adapted from: QOI - The "Quite OK Image" format for fast, lossless image 3 | * compression; see https://phoboslab.org 4 | * 5 | * Copyright (c) 2021, Dominic Szablewski - https://phoboslab.org 6 | * SPDX-License-Identifier: MIT 7 | */ 8 | 9 | #ifndef _QOI_H 10 | #define _QOI_H 11 | 12 | #include 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | #define QOI_SRGB 0 /* sRGB (gamma corrected RGB & linear alpha channel) */ 20 | #define QOI_LINEAR 1 /* all channels linear */ 21 | 22 | typedef struct { 23 | /* file starts with the 4-byte identifier "qoif" */ 24 | uint32_t width; /* stored in Big Endian in the file */ 25 | uint32_t height; /* stored in Big Endian in the file */ 26 | uint8_t channels; /* 3 = RGB, 4 = RGBA */ 27 | uint8_t colorspace; /* QOI_SRGB or QOI_LINEAR */ 28 | } QOI_DESC; 29 | 30 | void *qoi_encode(const void *data, const QOI_DESC *desc, size_t *out_len); 31 | void *qoi_decode(const void *data, size_t size, QOI_DESC *desc, int channels); 32 | void *qoi_free(void *data); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | #endif /* _QOI_H */ 38 | 39 | -------------------------------------------------------------------------------- /source/quickguide.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickGuide file format structure and constants. 3 | * 4 | * Copyright (C) 2023-2024 CompuPhase 5 | * All rights reserved. 6 | */ 7 | #ifndef _QUICKGUIDE_H 8 | #define _QUICKGUIDE_H 9 | 10 | #include 11 | 12 | /* ************************************ */ 13 | /* File format structures and constants */ 14 | /* ************************************ */ 15 | 16 | enum { 17 | QPAR_STANDARD, 18 | QPAR_HEADING, 19 | QPAR_ULIST, 20 | QPAR_OLIST, 21 | QPAR_PREFMT, 22 | QPAR_TABLE, 23 | QPAR_HLINE, 24 | }; 25 | 26 | enum { 27 | QFMT_SENTINEL, 28 | QFMT_STYLE, /* 0=roman, 1=italic, 2=bold, 3=code/monospaced */ 29 | QFMT_NOBREAK, /* character at pos is non-breaking (may be " " or "-") */ 30 | QFMT_SOFTBREAK, /* soft-hyphen */ 31 | QFMT_LINEBREAK, /* forced line break */ 32 | QFMT_COLBREAK, /* column break (in table) */ 33 | QFMT_LINK, 34 | QFMT_PICT, 35 | QFMT_VARIABLE, 36 | }; 37 | 38 | enum { 39 | QALIGN_LEFT, 40 | QALIGN_RIGHT, 41 | QALIGN_CENTRE, 42 | }; 43 | #define QALIGN_CENTER QALIGN_CENTRE 44 | 45 | #define QFLG_VSPACE (1u << 0) 46 | #define QFLG_CONTEXT (1u << 1) 47 | 48 | #if defined __GNUC__ 49 | # define PACKED __attribute__((packed)) 50 | #else 51 | # define PACKED 52 | #endif 53 | 54 | #if defined __LINUX__ || defined __FreeBSD__ || defined __APPLE__ 55 | # pragma pack(1) /* structures must be packed (byte-aligned) */ 56 | #elif defined MACOS && defined __MWERKS__ 57 | # pragma options align=mac68k 58 | #else 59 | # pragma pack(push) 60 | # pragma pack(1) /* structures must be packed (byte-aligned) */ 61 | # if defined __TURBOC__ 62 | # pragma option -a- /* "pack" pragma for older Borland compilers */ 63 | # endif 64 | #endif 65 | 66 | 67 | typedef struct tagQG_FILEHDR { 68 | char signature[3]; 69 | uint16_t version; 70 | uint32_t topic_offs; /* offset to the topic table */ 71 | uint16_t topic_count; 72 | uint32_t var_offs; 73 | uint16_t var_count; 74 | uint32_t pict_offs; 75 | uint16_t pict_count; 76 | } PACKED QG_FILEHDR; 77 | 78 | typedef struct tagQG_TOPICHDR { 79 | uint16_t size; 80 | uint32_t id; 81 | uint32_t content_offs; /* offset to the first string */ 82 | uint16_t content_count; 83 | /* zero-terminated string for topic caption follows */ 84 | } PACKED QG_TOPICHDR; 85 | 86 | typedef struct tagQG_VARIABLE_RECORD { 87 | uint16_t size; 88 | /* zero-terminated strings for the variable name and the default value follow */ 89 | } PACKED QG_VARIABLE_RECORD; 90 | 91 | typedef struct tagQG_PICTURE_RECORD { 92 | uint32_t size; 93 | uint8_t align; 94 | /* picture data follows */ 95 | } PACKED QG_PICTURE_RECORD; 96 | 97 | typedef struct tagQG_FORMATCODE { 98 | uint16_t type; 99 | uint16_t param; 100 | uint32_t pos; 101 | } PACKED QG_FORMATCODE; 102 | 103 | typedef struct tagQG_LINE_RECORD { 104 | uint16_t size; 105 | uint8_t type; 106 | uint8_t indent; 107 | uint8_t param; 108 | uint8_t flags; 109 | uint16_t fmtcodes; 110 | /* a list with format codes follows (fmtcodes is always > 0) 111 | the plain text of the paragraph follows 112 | a list with context patterns may optionally follow (if QFLG_CONTEXT is set) */ 113 | } PACKED QG_LINE_RECORD; 114 | 115 | #if defined __LINUX__ || defined __FreeBSD__ || defined __APPLE__ 116 | # pragma pack() /* reset default packing */ 117 | #elif defined MACOS && defined __MWERKS__ 118 | # pragma options align=reset 119 | #else 120 | # pragma pack(pop) /* reset previous packing */ 121 | #endif 122 | 123 | /* ********************************************** */ 124 | /* Viewer API structures, constants and functions */ 125 | /* ********************************************** */ 126 | 127 | enum { 128 | QBKG_STANDARD, 129 | QBKG_NOTE, 130 | QBKG_TIP, 131 | QBKG_IMPORTANT, 132 | QBKG_CAUTION, 133 | QBKG_WARNING, 134 | QBKG_TABLEHEADER, 135 | QBKG_TABLEROW1, 136 | QBKG_TABLEROW2, 137 | }; 138 | 139 | #endif /* _QUICKGUIDE_H */ 140 | 141 | -------------------------------------------------------------------------------- /source/res/icon_debug.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_debug.ico -------------------------------------------------------------------------------- /source/res/icon_debug_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_debug_64.png -------------------------------------------------------------------------------- /source/res/icon_download.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_download.ico -------------------------------------------------------------------------------- /source/res/icon_download_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_download_32.png -------------------------------------------------------------------------------- /source/res/icon_download_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_download_64.png -------------------------------------------------------------------------------- /source/res/icon_profile.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_profile.ico -------------------------------------------------------------------------------- /source/res/icon_profile_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_profile_64.png -------------------------------------------------------------------------------- /source/res/icon_serial.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_serial.ico -------------------------------------------------------------------------------- /source/res/icon_serial_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_serial_64.png -------------------------------------------------------------------------------- /source/res/icon_trace.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_trace.ico -------------------------------------------------------------------------------- /source/res/icon_trace_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/compuphase/Black-Magic-Probe-Book/cdf0e150705d6777b80dbfbc21142e86eff10034/source/res/icon_trace_64.png -------------------------------------------------------------------------------- /source/rs232.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rs232 - RS232 support, limited to the functions that the GDB RSP needs. 3 | * 4 | * Copyright 2012-2023, CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 7 | * use this file except in compliance with the License. You may obtain a copy 8 | * of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | * License for the specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef _RS232_H 19 | #define _RS232_H 20 | 21 | #include 22 | 23 | #if defined __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | #if defined _WIN32 28 | typedef HANDLE HCOM; 29 | #else /* _WIN32 */ 30 | typedef int HCOM; 31 | #endif /* _WIN32 */ 32 | 33 | enum { 34 | PAR_NONE = 0, 35 | PAR_ODD, 36 | PAR_EVEN, 37 | PAR_MARK, 38 | PAR_SPACE, 39 | }; 40 | 41 | enum { 42 | FLOWCTRL_NONE, 43 | FLOWCTRL_RTSCTS, /* RTS / CTS */ 44 | FLOWCTRL_XONXOFF, /* XON / XOFF */ 45 | }; 46 | 47 | #define LINESTAT_RTS 0x0001 48 | #define LINESTAT_DTR 0x0002 49 | #define LINESTAT_CTS 0x0004 50 | #define LINESTAT_DSR 0x0008 51 | #define LINESTAT_RI 0x0010 52 | #define LINESTAT_CD 0x0020 53 | #define LINESTAT_ERR 0x0040 54 | #define LINESTAT_BREAK 0x0080 /* remote host sent break */ 55 | #define LINESTAT_LBREAK 0x0100 /* local host sent break */ 56 | 57 | HCOM* rs232_open(const char *port, unsigned baud, int databits, int stopbits, int parity, int flowctrl); 58 | HCOM* rs232_close(HCOM *hCom); 59 | bool rs232_isopen(const HCOM *hCom); 60 | size_t rs232_xmit(HCOM *hCom, const unsigned char *buffer, size_t size); 61 | size_t rs232_recv(HCOM *hCom, unsigned char *buffer, size_t size); 62 | void rs232_flush(HCOM *hCom); 63 | size_t rs232_peek(HCOM *hCom); 64 | void rs232_setstatus(HCOM *hCom, int code, int status); 65 | unsigned rs232_getstatus(HCOM *hCom); 66 | void rs232_framecheck(HCOM *hCom, int enable); 67 | int rs232_collect(char **portlist, int listsize); 68 | 69 | #if defined __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* _RS232_H */ 74 | -------------------------------------------------------------------------------- /source/serialmon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple serial monitor (receive data from a serial port). 3 | * 4 | * Copyright 2021-2024 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _SERIALMON_H 19 | #define _SERIALMON_H 20 | 21 | bool sermon_open(const char *port, int baud); 22 | void sermon_close(void); 23 | bool sermon_isopen(void); 24 | 25 | void sermon_clear(void); 26 | int sermon_countlines(void); 27 | void sermon_rewind(void); 28 | const char *sermon_next(bool *is_error, int *severity, int *streamid); 29 | 30 | const char *sermon_getport(int translated); 31 | int sermon_getbaud(void); 32 | 33 | void sermon_setmetadata(const char *tsdlfile); 34 | const char *sermon_getmetadata(void); 35 | 36 | void sermon_statusmsg(const char *message, bool is_error); 37 | int sermon_save(const char *filename, bool csvformat); 38 | 39 | #endif /* _SERIALMON_H */ 40 | -------------------------------------------------------------------------------- /source/specialfolder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Return user folder locations (for local data or configuration). The Linux 3 | * code in this file is inspired by PlatformFolders.cpp by Poul Sander (see 4 | * https://github.com/sago007/PlatformFolders). 5 | * 6 | * Its is under the MIT license, to encourage reuse by cut-and-paste. 7 | * 8 | * Portions copyright (c) 2019 CompuPhase 9 | * Portions copyright (c) 2015-2016 Poul Sander 10 | * 11 | * Permission is hereby granted, free of charge, to any person 12 | * obtaining a copy of this software and associated documentation files 13 | * (the "Software"), to deal in the Software without restriction, 14 | * including without limitation the rights to use, copy, modify, merge, 15 | * publish, distribute, sublicense, and/or sell copies of the Software, 16 | * and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be 20 | * included in all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 26 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 27 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 | * SOFTWARE. 30 | */ 31 | #ifndef _SPECIALFOLDER_H 32 | #define _SPECIALFOLDER_H 33 | 34 | #if defined __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #if defined _WIN32 39 | #define DIR_SEPARATOR "\\" 40 | #else 41 | #define DIR_SEPARATOR "/" 42 | #endif 43 | 44 | int folder_AppData(char *path, size_t maxlength); 45 | int folder_AppConfig(char *path, size_t maxlength); 46 | 47 | #if defined __cplusplus 48 | } 49 | #endif 50 | 51 | #endif /* _SPECIALFOLDER_H */ 52 | 53 | -------------------------------------------------------------------------------- /source/strlcpy.c: -------------------------------------------------------------------------------- 1 | /* source https://gist.github.com/Fonger/98cc95ac39fbe1a7e4d9 2 | modified for more robustness */ 3 | 4 | #include 5 | #include 6 | #include "strlcpy.h" 7 | 8 | /* 9 | * '_cups_strlcat()' - Safely concatenate two strings. 10 | */ 11 | 12 | size_t /* O - Length of string (excluding the terminating zero) */ 13 | strlcat(char *dst, /* O - Destination string */ 14 | const char *src, /* I - Source string */ 15 | size_t size) /* I - Size of destination string buffer */ 16 | { 17 | size_t srclen; /* Length of source string */ 18 | size_t dstlen; /* Length of destination string */ 19 | 20 | if (size == 0) 21 | return 0; 22 | 23 | /* Figure out how much room is left... */ 24 | dstlen = strlen(dst); 25 | if (size <= dstlen + 1) 26 | return (dstlen); /* No room, return immediately... */ 27 | size -= dstlen + 1; 28 | 29 | /* Figure out how much room is needed... */ 30 | srclen = strlen(src); 31 | 32 | /* Copy the appropriate amount... */ 33 | if (srclen > size) 34 | srclen = size; 35 | 36 | memcpy(dst + dstlen, src, srclen); 37 | dst[dstlen + srclen] = '\0'; 38 | 39 | return (dstlen + srclen); 40 | } 41 | 42 | 43 | /* 44 | * '_cups_strlcpy()' - Safely copy two strings. 45 | */ 46 | 47 | size_t /* O - Length of string */ 48 | strlcpy(char *dst, /* O - Destination string */ 49 | const char *src, /* I - Source string */ 50 | size_t size) /* I - Size of destination string buffer */ 51 | { 52 | size_t srclen; /* Length of source string */ 53 | 54 | 55 | /* Figure out how much room is needed... */ 56 | if (size == 0) 57 | return 0; 58 | size --; 59 | 60 | srclen = strlen(src); 61 | 62 | /* Copy the appropriate amount... */ 63 | if (srclen > size) 64 | srclen = size; 65 | 66 | memcpy(dst, src, srclen); 67 | dst[srclen] = '\0'; 68 | 69 | return (srclen); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /source/strlcpy.h: -------------------------------------------------------------------------------- 1 | size_t strlcat(char *dst, const char *src, size_t size); 2 | size_t strlcpy(char *dst, const char *src, size_t size); 3 | 4 | -------------------------------------------------------------------------------- /source/strmatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * String matching with wildcard support (globbing). 3 | * 4 | * Copyright 2024 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _STRMATCH_H 19 | #define _STRMATCH_H 20 | 21 | uint32_t utf8_char(const char *text,int *size,bool *valid); 22 | const char *strmatch(const char *pattern,const char *text,int *length); 23 | 24 | #endif /* _STRMATCH_H */ 25 | -------------------------------------------------------------------------------- /source/svd-support.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Functions for reading and parsing CMSIS SVD files with MCU-specific register 3 | * definitions. 4 | * 5 | * Copyright 2020-2023 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _SVD_SUPPORT_H 20 | #define _SVD_SUPPORT_H 21 | 22 | #include 23 | 24 | void svd_clear(void); 25 | bool svd_load(const char *filename); 26 | bool svd_xlate_name(const char *symbol, char *alias, size_t alias_size); 27 | int svd_xlate_all_names(char *text, size_t maxsize); 28 | 29 | const char *svd_mcu_prefix(void); 30 | const char *svd_peripheral(unsigned index, unsigned long *address, const char **description); 31 | const char *svd_register(const char *peripheral, unsigned index, unsigned long *offset, 32 | int *range, const char **description); 33 | const char *svd_bitfield(const char *peripheral, const char *regname, unsigned index, 34 | short *low_bit, short *high_bit, const char **description); 35 | 36 | int svd_lookup(const char *symbol, int index, const char **periph_name, const char **reg_name, 37 | unsigned long *address, const char **description); 38 | 39 | #endif /* _SVD_SUPPORT_H */ 40 | -------------------------------------------------------------------------------- /source/svnrev.h: -------------------------------------------------------------------------------- 1 | /* This file was generated by the "svnrev" utility 2 | * (https://www.compuphase.com/svnrev.htm). 3 | * You should not modify it manually, as it may be re-generated. 4 | * 5 | * $Revision: 7264$ 6 | * $Date: 2024-10-24$ 7 | */ 8 | 9 | #ifndef _SVNREV_H_ 10 | #define _SVNREV_H_ 11 | 12 | #define SVNREV_NUM 7264 13 | #define SVNREV_STR "1.5.7264" 14 | #define SVNREV_RCS "$Revision: 7264 $" 15 | #define SVNREV_DATE "2024-10-24" 16 | #define SVNREV_STAMP 20241024L 17 | #define SVNREV_MODIFIED 0 18 | 19 | #endif /* _SVNREV_H_ */ 20 | -------------------------------------------------------------------------------- /source/swotrace.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Shared code for SWO Trace for the bmtrace and bmdebug utilities. 3 | * 4 | * Copyright 2019-2024 CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _SWOTRACE_H 19 | #define _SWOTRACE_H 20 | 21 | #include 22 | #include "nuklear.h" 23 | 24 | #define NUM_CHANNELS 32 /* number of SWO channels */ 25 | 26 | enum { 27 | TRACESTAT_OK = 0, 28 | TRACESTAT_NO_INTERFACE, /* Black Magic Probe not found (trace interface not found) */ 29 | TRACESTAT_NO_DEVPATH, /* device path to trace interface not found */ 30 | TRACESTAT_NO_ACCESS, /* failure opening the device interface */ 31 | TRACESTAT_NO_PIPE, /* endpoint pipe could not be found -> not a Black Magic Probe? */ 32 | TRACESTAT_BAD_PACKET, /* invalid trace data packet received */ 33 | TRACESTAT_NO_THREAD, /* thread could not be created */ 34 | TRACESTAT_INIT_FAILED, /* WunUSB / libusb initialization failed */ 35 | TRACESTAT_NO_CONNECT, /* Failed to connect to Black Magic Probe */ 36 | TRACESTAT_NOT_INIT, /* not yet initialized */ 37 | }; 38 | 39 | enum { 40 | TRACESTATMSG_BMP, 41 | TRACESTATMSG_CTF, 42 | }; 43 | 44 | typedef struct tagTRACEFILTER { 45 | char *expr; 46 | int enabled; 47 | } TRACEFILTER; 48 | 49 | #define ADDRESS_ALIGN 2 /* alignment of an address in bytes (16-bit Thumb) */ 50 | #define Address2Index(address, base) (((address) - (base)) / ADDRESS_ALIGN) 51 | #define Index2Address(index, base) ((index) * ADDRESS_ALIGN + (base)) 52 | 53 | void channel_set(int index, bool enabled, const char *name, struct nk_color color); 54 | bool channel_getenabled(int index); 55 | void channel_setenabled(int index, bool enabled); 56 | const char *channel_getname(int index, char *name, size_t size); 57 | void channel_setname(int index, const char *name); 58 | struct nk_color channel_getcolor(int index); 59 | void channel_setcolor(int index, struct nk_color color); 60 | 61 | int trace_init(unsigned short endpoint, const char *ipaddress); 62 | void trace_close(void); 63 | bool trace_isopen(void); 64 | unsigned long trace_errno(int *loc); 65 | int trace_overflowerrors(bool reset); 66 | 67 | void trace_setdatasize(short size); 68 | short trace_getdatasize(); 69 | int trace_getpacketerrors(bool reset); 70 | 71 | void tracestring_clear(void); 72 | bool tracestring_isempty(void); 73 | unsigned tracestring_count(void); 74 | int tracestring_process(bool enabled); 75 | int tracestring_load(const char *filename, int *format); 76 | int tracestring_save(const char *filename); 77 | const char *trace_channelname(int id); 78 | int tracestring_find(const char *text, int curline); 79 | int tracestring_findtimestamp(double timestamp); 80 | 81 | int tracestring_findbookmark(int action); 82 | enum { 83 | BK_NEXT, 84 | BK_PREV, 85 | BK_CLEAR, 86 | }; 87 | 88 | int traceprofile_process(bool enabled, unsigned *sample_map, uint32_t code_base, uint32_t code_top, unsigned *overflow); 89 | 90 | void tracelog_statusmsg(int type, const char *msg, int code); 91 | void tracelog_statusclear(void); 92 | const char *tracelog_getstatusmsg(int idx); 93 | float tracelog_labelwidth(float rowheight); 94 | void tracelog_widget(struct nk_context *ctx, const char *id, float rowheight, int limitlines, 95 | int markline, const TRACEFILTER *filters, int severity, nk_flags widget_flags); 96 | 97 | void timeline_getconfig(double *spacing, unsigned long *scale, unsigned long *delta); 98 | void timeline_setconfig(double spacing, unsigned long scale, unsigned long delta); 99 | void timeline_rebuild(int limitlines, bool zoomfit); 100 | double timeline_widget(struct nk_context *ctx, const char *id, float rowheight, 101 | int limitlines, nk_flags widget_flags); 102 | 103 | double get_timestamp(void); 104 | 105 | #endif /* _SWOTRACE_H */ 106 | -------------------------------------------------------------------------------- /source/tcpip.h: -------------------------------------------------------------------------------- 1 | /* tcpip - networking portability layer for Windows and Linux, limited to the 2 | * functions that the GDB RSP needs 3 | * 4 | * Copyright 2020-2023, CompuPhase 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 7 | * use this file except in compliance with the License. You may obtain a copy 8 | * of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | * License for the specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef _TCPIP_H 19 | #define _TCPIP_H 20 | 21 | #if defined __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | #if defined WIN32 || defined _WIN32 26 | #define WIN32_LEAN_AND_MEAN 27 | #include 28 | #include 29 | #else 30 | #include 31 | typedef int SOCKET; 32 | #define INVALID_SOCKET (-1) 33 | #endif /* __linux__ */ 34 | 35 | #if !defined INADDR_NONE 36 | #define INADDR_NONE (~0) 37 | #endif 38 | 39 | int tcpip_init(void); 40 | int tcpip_cleanup(void); 41 | 42 | int tcpip_open(const char *ip_address); 43 | int tcpip_close(void); 44 | int tcpip_isopen(void); 45 | size_t tcpip_xmit(const unsigned char *buffer, size_t size); 46 | size_t tcpip_recv(unsigned char *buffer, size_t size); 47 | 48 | /* general purpose functions */ 49 | unsigned long getlocalip(char *ip_address); 50 | int connect_timeout(SOCKET sock, const char *host, short port, int timeout); 51 | 52 | #if defined __linux__ || defined __FreeBSD__ || defined __APPLE__ 53 | int closesocket(SOCKET s); 54 | #endif /* __linux__ */ 55 | 56 | #if defined __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* _TCPIP_H */ 61 | 62 | -------------------------------------------------------------------------------- /source/usb-support.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Functions for general purpose USB device access in Microsoft Windows, by 3 | * dynamically loading & Linking WinUSB or libusbK. For libusbK, the native 4 | * API is used, but note that libusbK also provides an implementation of the 5 | * WinUSB API. 6 | * 7 | * Copyright 2020-2023 CompuPhase 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | #include 22 | #include 23 | #include "usb-support.h" 24 | 25 | /* 26 | * Part 1: WinUSB 27 | */ 28 | 29 | BOOL (__stdcall *_WinUsb_Initialize)(HANDLE DeviceHandle, USB_INTERFACE_HANDLE *InterfaceHandle) = NULL; 30 | BOOL (__stdcall *_WinUsb_Free)(USB_INTERFACE_HANDLE InterfaceHandle) = NULL; 31 | BOOL (__stdcall *_WinUsb_QueryInterfaceSettings)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t AlternateInterfaceNumber, USB_INTERFACE_DESCRIPTOR *UsbAltInterfaceDescriptor) = NULL; 32 | BOOL (__stdcall *_WinUsb_QueryPipe)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t AlternateInterfaceNumber, uint8_t PipeIndex, USB_PIPE_INFORMATION *PipeInformation) = NULL; 33 | BOOL (__stdcall *_WinUsb_ReadPipe)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t PipeID, uint8_t *Buffer, uint32_t BufferLength, uint32_t *LengthTransferred, LPOVERLAPPED Overlapped) = NULL; 34 | 35 | static HMODULE hinstWinUSB = NULL; 36 | 37 | BOOL WinUsb_Load(void) 38 | { 39 | if (hinstWinUSB != NULL) 40 | return TRUE; /* double initialization */ 41 | 42 | hinstWinUSB = LoadLibrary("winusb.dll"); 43 | if (hinstWinUSB == NULL) 44 | return FALSE; 45 | 46 | _WinUsb_Initialize = (void*)GetProcAddress(hinstWinUSB, "WinUsb_Initialize"); 47 | _WinUsb_Free = (void*)GetProcAddress(hinstWinUSB, "WinUsb_Free"); 48 | _WinUsb_QueryInterfaceSettings = (void*)GetProcAddress(hinstWinUSB, "WinUsb_QueryInterfaceSettings"); 49 | _WinUsb_QueryPipe = (void*)GetProcAddress(hinstWinUSB, "WinUsb_QueryPipe"); 50 | _WinUsb_ReadPipe = (void*)GetProcAddress(hinstWinUSB, "WinUsb_ReadPipe"); 51 | assert(_WinUsb_Initialize != NULL && _WinUsb_Free != NULL && _WinUsb_QueryInterfaceSettings != NULL 52 | && _WinUsb_QueryPipe != NULL && _WinUsb_ReadPipe != NULL); 53 | return TRUE; 54 | } 55 | 56 | BOOL WinUsb_Unload(void) 57 | { 58 | if (hinstWinUSB == NULL) 59 | return FALSE; 60 | FreeLibrary(hinstWinUSB); 61 | hinstWinUSB = NULL; 62 | _WinUsb_Initialize = NULL; 63 | _WinUsb_Free = NULL; 64 | _WinUsb_QueryInterfaceSettings = NULL; 65 | _WinUsb_QueryPipe = NULL; 66 | _WinUsb_ReadPipe = NULL; 67 | 68 | return TRUE; 69 | } 70 | 71 | BOOL WinUsb_IsActive(void) 72 | { 73 | return hinstWinUSB != NULL; 74 | } 75 | 76 | 77 | /* 78 | * Part 2: libusbK 79 | */ 80 | 81 | BOOL (__stdcall *_UsbK_Init)(USB_INTERFACE_HANDLE* InterfaceHandle, const KLST_DEVINFO *DevInfo) = NULL; 82 | BOOL (__stdcall *_UsbK_Free)(USB_INTERFACE_HANDLE InterfaceHandle) = NULL; 83 | BOOL (__stdcall *_UsbK_QueryInterfaceSettings)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t AlternateInterfaceNumber, USB_INTERFACE_DESCRIPTOR *UsbAltInterfaceDescriptor) = NULL; 84 | BOOL (__stdcall *_UsbK_QueryPipe)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t AlternateInterfaceNumber, uint8_t PipeIndex, USB_PIPE_INFORMATION *PipeInformation) = NULL; 85 | BOOL (__stdcall *_UsbK_ReadPipe)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t PipeID, uint8_t *Buffer, uint32_t BufferLength, uint32_t *LengthTransferred, LPOVERLAPPED Overlapped) = NULL; 86 | 87 | BOOL (__stdcall *_LstK_Init)(KLST_DEVINFO **DeviceList, int Flags) = NULL; 88 | BOOL (__stdcall *_LstK_Free)(KLST_DEVINFO *DeviceList) = NULL; 89 | BOOL (__stdcall *_LstK_Count)(const KLST_DEVINFO *DeviceList, uint32_t *Count) = NULL; 90 | BOOL (__stdcall *_LstK_Enumerate)(const KLST_DEVINFO *DeviceList, KLST_ENUM_DEVINFO_CB *EnumDevListCB, void *Context) = NULL; 91 | 92 | static HMODULE hinstUsbK = NULL; 93 | 94 | BOOL UsbK_Load(void) 95 | { 96 | if (hinstUsbK != NULL) 97 | return TRUE; /* double initialization */ 98 | 99 | hinstUsbK = LoadLibrary("libusbK.dll"); 100 | if (hinstUsbK == NULL) 101 | return FALSE; 102 | 103 | _UsbK_Init = (void*)GetProcAddress(hinstUsbK, "UsbK_Init"); 104 | _UsbK_Free = (void*)GetProcAddress(hinstUsbK, "UsbK_Free"); 105 | _UsbK_QueryInterfaceSettings = (void*)GetProcAddress(hinstUsbK, "UsbK_QueryInterfaceSettings"); 106 | _UsbK_QueryPipe = (void*)GetProcAddress(hinstUsbK, "UsbK_QueryPipe"); 107 | _UsbK_ReadPipe = (void*)GetProcAddress(hinstUsbK, "UsbK_ReadPipe"); 108 | _LstK_Init = (void*)GetProcAddress(hinstUsbK, "LstK_Init"); 109 | _LstK_Free = (void*)GetProcAddress(hinstUsbK, "LstK_Free"); 110 | _LstK_Count = (void*)GetProcAddress(hinstUsbK, "LstK_Count"); 111 | _LstK_Enumerate = (void*)GetProcAddress(hinstUsbK, "LstK_Enumerate"); 112 | assert(_UsbK_Init != NULL && _UsbK_Free != NULL && _UsbK_QueryInterfaceSettings != NULL 113 | && _UsbK_QueryPipe != NULL && _UsbK_ReadPipe != NULL && _LstK_Init != NULL 114 | && _LstK_Free != NULL && _LstK_Count != NULL && _LstK_Enumerate != NULL); 115 | return TRUE; 116 | } 117 | 118 | BOOL UsbK_Unload(void) 119 | { 120 | if (hinstUsbK == NULL) 121 | return FALSE; 122 | FreeLibrary(hinstUsbK); 123 | hinstUsbK = NULL; 124 | _UsbK_Init = NULL; 125 | _UsbK_Free = NULL; 126 | _UsbK_QueryInterfaceSettings = NULL; 127 | _UsbK_QueryPipe = NULL; 128 | _UsbK_ReadPipe = NULL; 129 | _LstK_Init = NULL; 130 | _LstK_Free = NULL; 131 | _LstK_Count = NULL; 132 | _LstK_Enumerate = NULL; 133 | 134 | return TRUE; 135 | } 136 | 137 | BOOL UsbK_IsActive(void) 138 | { 139 | return hinstUsbK != NULL; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /source/usb-support.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Functions for general purpose USB device access in Microsoft Windows, by 3 | * dynamically loading & Linking WinUSB. 4 | * 5 | * Copyright 2020-2023 CompuPhase 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _USB_SUPPORT_H 20 | #define _USB_SUPPORT_H 21 | 22 | #include 23 | #include 24 | 25 | #if defined __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* 30 | * General types (for both WinUSB and libusbK) 31 | */ 32 | typedef enum { 33 | PIPETYPE_CONTROL, 34 | PIPETYPE_ISOCHRONOUS, 35 | PIPETYPE_BULK, 36 | PIPETYPE_INTERRUPT 37 | } USB_PIPE_TYPE; 38 | 39 | typedef struct tagUSB_INTERFACE_DESCRIPTOR { 40 | uint8_t bLength; /**< length of the descriptor in bytes */ 41 | uint8_t bDescriptorType; 42 | uint8_t bInterfaceNumber; 43 | uint8_t bAlternateSetting; 44 | uint8_t bNumEndpoints; /**< number of endpoints excluding the control endpoint */ 45 | uint8_t bInterfaceClass; /**< USB-IF class code for this interface */ 46 | uint8_t bInterfaceSubClass; /**< USB-IF subclass code for this interface*/ 47 | uint8_t bInterfaceProtocol; /**< USB-IF protocol code for this interface */ 48 | uint8_t iInterface; /**< index of the string descriptor for this interface */ 49 | } USB_INTERFACE_DESCRIPTOR; 50 | 51 | typedef struct tagUSB_PIPE_INFORMATION { 52 | uint32_t PipeType; /**< one of the values of the USB_PIPE_TYPE enumeration */ 53 | uint8_t PipeId; 54 | uint16_t MaximumPacketSize; /**< in bytes */ 55 | uint8_t Interval; /**< in milliseconds */ 56 | } USB_PIPE_INFORMATION; 57 | 58 | typedef void* USB_INTERFACE_HANDLE; 59 | 60 | 61 | /* 62 | * Part 1: WinUSB 63 | * minimal subset of WinUSB types & functions 64 | */ 65 | 66 | extern BOOL (__stdcall *_WinUsb_Initialize)(HANDLE DeviceHandle, USB_INTERFACE_HANDLE *InterfaceHandle); 67 | extern BOOL (__stdcall *_WinUsb_Free)(USB_INTERFACE_HANDLE InterfaceHandle); 68 | extern BOOL (__stdcall *_WinUsb_QueryInterfaceSettings)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t AlternateInterfaceNumber, USB_INTERFACE_DESCRIPTOR *UsbAltInterfaceDescriptor); 69 | extern BOOL (__stdcall *_WinUsb_QueryPipe)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t AlternateInterfaceNumber, uint8_t PipeIndex, USB_PIPE_INFORMATION *PipeInformation); 70 | extern BOOL (__stdcall *_WinUsb_ReadPipe)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t PipeID, uint8_t *Buffer, uint32_t BufferLength, uint32_t *LengthTransferred, LPOVERLAPPED Overlapped); 71 | 72 | /* WinUSB loading & unloading functions */ 73 | BOOL WinUsb_Load(void); 74 | BOOL WinUsb_Unload(void); 75 | BOOL WinUsb_IsActive(void); 76 | 77 | 78 | /* 79 | * Part 2: libusbK 80 | */ 81 | 82 | #define KLST_STRING_MAX_LEN 256 83 | 84 | typedef struct tagKLST_DEVINFO { 85 | int Vid; 86 | int Pid; 87 | int MI; /**< interface number, set to -1 for non-composite devices */ 88 | char InstanceID[KLST_STRING_MAX_LEN]; /**< uniquely identifies the USB device */ 89 | int DriverID; 90 | char DeviceInterfaceGUID[KLST_STRING_MAX_LEN]; 91 | char DeviceID[KLST_STRING_MAX_LEN]; 92 | char ClassGUID[KLST_STRING_MAX_LEN]; 93 | char Mfg[KLST_STRING_MAX_LEN]; /**< Manufacturer name */ 94 | char DeviceDesc[KLST_STRING_MAX_LEN]; 95 | char Service[KLST_STRING_MAX_LEN]; /**< driver/service name */ 96 | char SymbolicLink[KLST_STRING_MAX_LEN]; 97 | char DevicePath[KLST_STRING_MAX_LEN]; /**< Windows virtual path, as used in CreateFile() */ 98 | int LUsb0FilterIndex; /**< libusb-win32 filter index id */ 99 | BOOL Connected; 100 | long SyncFlags; /**< Synchronization flags (internal use only) */ 101 | int BusNumber; 102 | INT DeviceAddress; 103 | char SerialNumber[KLST_STRING_MAX_LEN]; 104 | } KLST_DEVINFO; 105 | 106 | typedef void* KUSB_HANDLE; 107 | typedef void* KLST_HANDLE; 108 | 109 | typedef BOOL __stdcall KLST_ENUM_DEVINFO_CB(KLST_HANDLE DeviceList, KLST_DEVINFO *DeviceInfo, PVOID Context); 110 | 111 | extern BOOL (__stdcall *_UsbK_Init)(USB_INTERFACE_HANDLE* InterfaceHandle, const KLST_DEVINFO *DevInfo); 112 | extern BOOL (__stdcall *_UsbK_Free)(USB_INTERFACE_HANDLE InterfaceHandle); 113 | extern BOOL (__stdcall *_UsbK_QueryInterfaceSettings)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t AlternateInterfaceNumber, USB_INTERFACE_DESCRIPTOR *UsbAltInterfaceDescriptor); 114 | extern BOOL (__stdcall *_UsbK_QueryPipe)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t AlternateInterfaceNumber, uint8_t PipeIndex, USB_PIPE_INFORMATION *PipeInformation); 115 | extern BOOL (__stdcall *_UsbK_ReadPipe)(USB_INTERFACE_HANDLE InterfaceHandle, uint8_t PipeID, uint8_t *Buffer, uint32_t BufferLength, uint32_t *LengthTransferred, LPOVERLAPPED Overlapped); 116 | 117 | extern BOOL (__stdcall *_LstK_Init)(KLST_DEVINFO **DeviceList, int Flags); 118 | extern BOOL (__stdcall *_LstK_Free)(KLST_DEVINFO *DeviceList); 119 | extern BOOL (__stdcall *_LstK_Count)(const KLST_DEVINFO *DeviceList, uint32_t *Count); 120 | extern BOOL (__stdcall *_LstK_Enumerate)(const KLST_DEVINFO *DeviceList, KLST_ENUM_DEVINFO_CB *EnumDevListCB, void *Context); 121 | 122 | /* WinUSB loading, unloading & compatibility functions */ 123 | BOOL UsbK_Load(void); 124 | BOOL UsbK_Unload(void); 125 | BOOL UsbK_IsActive(void); 126 | 127 | #if defined __cplusplus 128 | } 129 | #endif 130 | 131 | #endif /* _USB_SUPPORT_H */ 132 | 133 | -------------------------------------------------------------------------------- /source/xmltractor.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | XML Tractor [v1.01] 4 | - goes through all that shit so you don't have to 5 | Copyright © 2012-2017 Arvīds Kokins 6 | More info on https://github.com/snake5/xml-tractor/ 7 | */ 8 | 9 | #pragma once 10 | 11 | #ifdef __cplusplus 12 | extern "C"{ 13 | #endif 14 | 15 | 16 | typedef struct xt_Attrib xt_Attrib; 17 | typedef struct xt_Node xt_Node; 18 | 19 | struct xt_Attrib 20 | { 21 | char* name; 22 | char* value; 23 | int szname; 24 | int szvalue; 25 | }; 26 | 27 | struct xt_Node 28 | { 29 | xt_Node* parent; 30 | xt_Node* firstchild; 31 | xt_Node* sibling; 32 | char* header; 33 | char* content; 34 | char* name; 35 | xt_Attrib* attribs; 36 | int numchildren; 37 | int szheader; 38 | int szcontent; 39 | int szname; 40 | int numattribs; 41 | }; 42 | 43 | xt_Node* xt_parse( const char* data ); 44 | void xt_destroy_node( xt_Node* root ); 45 | 46 | xt_Node* xt_find_child( xt_Node* node, const char* name ); 47 | xt_Node* xt_find_sibling( xt_Node* node, const char* name ); 48 | xt_Attrib* xt_find_attrib( xt_Node* node, const char* name ); 49 | 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /support/.gdbinit: -------------------------------------------------------------------------------- 1 | define bmconnect 2 | if $argc < 1 || $argc > 2 3 | help bmconnect 4 | else 5 | target extended-remote $arg0 6 | if $argc == 2 7 | monitor $arg1 enable 8 | end 9 | monitor swdp_scan 10 | attach 1 11 | end 12 | end 13 | document bmconnect 14 | Attach to the Black Magic Probe at the given serial port/device: 15 | 16 | bmconnect PORT [tpwr] 17 | 18 | Specify PORT as COMx in Microsoft Windows or as /dev/ttyACMx in Linux. 19 | If the second parameter is set as "tpwr", the power-sense pin is driven to 3.3V. 20 | end 21 | 22 | # =========================================================================== 23 | 24 | define mmap-flash 25 | set mem inaccessible-by-default off 26 | if $argc < 1 || $argc > 1 27 | help mmap-flash 28 | else 29 | set $ok = 0 30 | if $arg0 == 800 || $arg0 == 1100 || $arg0 == 1200 || $arg0 == 1300 31 | set {int}0x40048000 = 2 32 | set $ok = 1 33 | end 34 | if $arg0 == 1500 35 | set {int}0x40074000 = 2 36 | set $ok = 1 37 | end 38 | if $arg0 == 1700 39 | set {int}0x400FC040 = 1 40 | set $ok = 1 41 | end 42 | if $arg0 == 4300 43 | set {int}0x40043100 = 0 44 | set $ok = 1 45 | end 46 | if $ok == 0 47 | help mmap-flash 48 | end 49 | end 50 | end 51 | document mmap-flash 52 | Set the SYSMEMREMAP register for NXP LPC devices to map address 0 to Flash memory. 53 | 54 | mmap-flash mcu-type 55 | 56 | The parameter mcu-type must be one of the following: 57 | 800 for LPC8xx series 58 | 1100 for LPC11xx series 59 | 1200 for LPC12xx series 60 | 1300 for LPC13xx series 61 | 1500 for LPC15xx series 62 | 1700 for LPC17xx series 63 | 4300 for LPC43xx series 64 | end -------------------------------------------------------------------------------- /support/55-blackmagicprobe.rules: -------------------------------------------------------------------------------- 1 | # Allow access to the Black Magic Probe for any user. 2 | 3 | # Standard mode 4 | ACTION=="add", SUBSYSTEM=="usb_device", SYSFS{idVendor}=="1d50", SYSFS{idProduct}=="6018", MODE="0666" 5 | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1d50", ATTR{idProduct}=="6018", MODE="0666" 6 | 7 | # DFU mode 8 | ACTION=="add", SUBSYSTEM=="usb_device", SYSFS{idVendor}=="1d50", SYSFS{idProduct}=="6017", MODE="0666" 9 | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1d50", ATTR{idProduct}=="6017", MODE="0666" 10 | 11 | -------------------------------------------------------------------------------- /support/blackmagic.inf: -------------------------------------------------------------------------------- 1 | ; Windows USB CDC ACM driver setup file. 2 | 3 | ; Copyright (C) 2004 Al Borchers (alborchers@steinerpoint.com) 4 | ; Taken from Linux documentation, modified for Black Magic debug probe 5 | ; by Gareth McMullin 6 | 7 | ; This provides the driver information for the GDB and UART interfaces to 8 | ; be presented as virtual serial ports in Windows. 9 | 10 | ; Common to Windows 32- and 64-bit systems 11 | 12 | [Version] 13 | Signature="$Windows NT$" 14 | Class=Ports 15 | ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} 16 | Provider=%BLACKSPHERE% 17 | DriverVer=28/12/2011,0.0.1.1 18 | 19 | [Manufacturer] 20 | %VendorName%=DeviceList, NTamd64 21 | 22 | [Strings] 23 | VendorName = "Black Sphere Technologies" 24 | BLACKMAGICGDB = "Black Magic GDB Server" 25 | BLACKMAGICUART = "Black Magic UART Port" 26 | BLACKSPHERE_DISPLAY_NAME = "Black Magic Probe Driver" 27 | 28 | [DeviceList] 29 | %BLACKMAGICGDB%=DriverInstall, USB\VID_1d50&PID_6018&Rev_0100&MI_00 30 | %BLACKMAGICUART%=DriverInstall, USB\VID_1d50&PID_6018&Rev_0100&MI_02 31 | 32 | [DeviceList.NTamd64] 33 | %BLACKMAGICGDB%=DriverInstall, USB\VID_1d50&PID_6018&Rev_0100&MI_00 34 | %BLACKMAGICUART%=DriverInstall, USB\VID_1d50&PID_6018&Rev_0100&MI_02 35 | 36 | [DestinationDirs] 37 | DefaultDestDir=10,System32\Drivers 38 | 39 | ; Windows 32-bit sections 40 | ;~~~~~~~~~~~~~~~~~~~~~~~~~ 41 | 42 | [DriverInstall.nt] 43 | CopyFiles=DriverCopyFiles.nt 44 | AddReg=DriverInstall.nt.AddReg 45 | 46 | [DriverCopyFiles.nt] 47 | usbser.sys,,,0x20 48 | 49 | [DriverInstall.nt.AddReg] 50 | HKR,,DevLoader,,*ntkern 51 | HKR,,NTMPDriver,,usbser.sys 52 | HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" 53 | 54 | [DriverInstall.nt.Services] 55 | AddService = usbser,0x0002,DriverService.nt 56 | 57 | [DriverService.nt] 58 | DisplayName = %BLACKSPHERE_DISPLAY_NAME% 59 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 60 | StartType = 3 ; SERVICE_DEMAND_START 61 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 62 | ServiceBinary = %10%\System32\Drivers\usbser.sys 63 | LoadOrderGroup = Base 64 | 65 | ; Windows 64-bit sections 66 | ;~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | [DriverInstall.NTamd64] 68 | CopyFiles=DriverCopyFiles.NTamd64 69 | AddReg=DriverInstall.NTamd64.AddReg 70 | 71 | [DriverCopyFiles.NTamd64] 72 | usbser.sys,,,0x20 73 | 74 | [DriverInstall.NTamd64.AddReg] 75 | HKR,,DevLoader,,*ntkern 76 | HKR,,NTMPDriver,,usbser.sys 77 | HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" 78 | 79 | [DriverInstall.NTamd64.Services] 80 | AddService = usbser,0x0002,DriverService.NTamd64 81 | 82 | [DriverService.NTamd64] 83 | DisplayName = %BLACKSPHERE_DISPLAY_NAME% 84 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 85 | StartType = 3 ; SERVICE_DEMAND_START 86 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 87 | ServiceBinary = %10%\System32\Drivers\usbser.sys 88 | LoadOrderGroup = Base 89 | 90 | --------------------------------------------------------------------------------