? ǰ�� Ƕ��ʽ����������Ƕ��ʽ�����������ս�ԵĻ���֮һ����PC������ͬ��Ƕ��ʽϵͳ��Դ���ޡ������ֶ����ޣ���Ҫ����ר�ŵĵ������ۺͼ��ɡ����Ľ������ۻ�����ʵ��Ӧ�ã�ȫ�����Ƕ��ʽ�������Լ�����
? �������ۻ��� ʲô���������ԣ� �������� ��Software Debug����������������Ƿ�������ʧЧ����λ�������������Ĺ��̡�
1 �������Թ��� = �������� �� ��λ���� �� ������ �� ��֤��
���Ե���Ҫ�� ? ͳ��������ʾ ��
��������ʱ��һ��ռ�����������ڵ� 50%����
�����������к�ʱ����һ��
�ܶ���Ŀ�������������ڲ��ܶ�λ��bug��
����ϵͳ���Ӷ����ӣ����Լ�����Ҫͬ������
Ƕ��ʽ���Ե������� ��PC����������ȣ�Ƕ��ʽ���Ծ��������ص㣺
�ص�
PC����
Ƕ��ʽ����
��Դ����
�ڴ桢�洢����
��Դ��������
���Ի���
�ḻ�ĵ��Թ���
�����ֶ�����
ʵʱ��
ʵʱ��Ҫ��
�ϸ��ʵʱ��Ҫ��
Ӳ������
����Ӳ��ƽ̨
�߶������ض�Ӳ��
����Ӱ��
������������
������Ӳ��
? ���Թ��ߺͷ��� Ӳ�����Թ��� 1. JTAG������ JTAG��Joint Test Action Group������õ�Ӳ�����Խӿڣ�
1 2 3 4 5 6 7 �ص㣺 ? ���Ե����������� ? ֧�ֵ������� ? ���Բ鿴�Ĵ���״̬ ? ֧�ֶϵ����� ? ��Ҫר�ŵĵ�����Ӳ�� ? ռ��MCU�ĵ�����Դ
����JTAG������ ��
J-Link : Segger��˾��Ʒ������ǿ��֧�ֶ���MCU
ST-Link : ST��˾��Ʒ��ר������STM32����
OpenOCD : ��Դ���Է������ɱ�����
2. SWD���Խӿ� SWD��Serial Wire Debug����ARM�Ƴ��ĵ��Խӿڣ�
1 2 3 4 5 ���ƣ� ? ֻ��Ҫ2���ߣ�SWDIO��SWCLK�� ? ��JTAG��ʡ���� ? ���Թ������� ? ֧���Ȳ��
3. �������� ���ڷ��������ź�ʱ��
1 2 3 4 - Saleae Logic Pro - DSLogic Plus - PulseView
4. ʾ���� ���ڷ���ģ���źź�ʱ��
1 2 3 4 5 Ӧ�ó����� ? ��Դ�Ʋ����� ? �ź������Լ�� ? ʱ���ϵ��֤ ? EMC���ⶨλ
�������Թ��� 1. GDB������ GDB����ǿ��������е�������
1 2 3 4 5 6 7 8 9 10 11 12 gdb program (gdb) run (gdb) break main (gdb) break file.c:100 (gdb) continue (gdb) step (gdb) next (gdb) print variable (gdb) info registers (gdb) backtrace (gdb) quit
2. ���ɿ������� Keil MDK ��
1 2 3 4 5 6 7 ���ƣ� ? �����Ѻã�����ʹ�� ? ���ɶȸߣ����������� ? ֧�ֶ���ARM�ں� ? ���湦��ǿ�� ? ��ҵ�������۸� ? ��Ҫ֧��ARM�ܹ�
IAR Embedded Workbench ��
1 2 3 4 5 6 7 ���ƣ� ? �����Ż�����ǿ ? ֧�ֶ��ּܹ� ? ���Թ������� ? ��̬�������� ? �۸� ? ѧϰ���߶���
STM32CubeIDE ����ѣ���
1 2 3 4 5 6 7 ���ƣ� ? ��ȫ��� ? ����Eclipse�����ܷḻ ? ����STM32���ù��� ? ֧�ֶ��ֵ����� ? ��Ҫ���STM32 ? �����ٶȽ���
3. ��̬�������� PC-lint/PC-lint Plus ��
1 2 3 4 5 6 - δ��ʼ������ - �ڴ�й© - ����Խ�� - ����ת������ - ��������
Cppcheck ����Դ����
1 2 3 sudo apt install cppcheckcppcheck --enable =all src/
? �������Գ��� 1. ϵͳ������ ����ԭ�� ��
ʱ�����ô���
�ڴ��ʼ������
�����������
Ӳ����������
���Բ��� ��
1 2 3 4 5 1. ����Դ��ʱ�� 2. ʹ��JTAG���ӣ��鿴PCָ��λ�� 3. ����ִ���������� 4. ����ڴ�ӳ������ 5. ��֤Ӳ������
2. ���������쳣 Hard Fault�쳣���� ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 void HardFault_Handler (void ) { __asm volatile ( "TST lr, #4 \n" "ITE EQ \n" "MRSEQ r0, MSP \n" "MRSNE r0, PSP \n" "B hard_fault_handler_c \n" ) ;} void hard_fault_handler_c (uint32_t *hardfault_args) { volatile uint32_t stacked_r0; volatile uint32_t stacked_r1; volatile uint32_t stacked_r2; volatile uint32_t stacked_r3; volatile uint32_t stacked_r12; volatile uint32_t stacked_lr; volatile uint32_t stacked_pc; volatile uint32_t stacked_psr; stacked_r0 = ((uint32_t )hardfault_args[0 ]); stacked_r1 = ((uint32_t )hardfault_args[1 ]); stacked_r2 = ((uint32_t )hardfault_args[2 ]); stacked_r3 = ((uint32_t )hardfault_args[3 ]); stacked_r12 = ((uint32_t )hardfault_args[4 ]); stacked_lr = ((uint32_t )hardfault_args[5 ]); stacked_pc = ((uint32_t )hardfault_args[6 ]); stacked_psr = ((uint32_t )hardfault_args[7 ]); while (1 ); }
3. �ڴ�������� ջ������ ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define STACK_CANARY 0xDEADBEEF void stack_overflow_check (void ) { extern uint32_t _estack; uint32_t *stack_end = &_estack - 100 ; if (*stack_end != STACK_CANARY) { error_handler(); } } void init_stack_canary (void ) { extern uint32_t _estack; uint32_t *stack_end = &_estack - 100 ; *stack_end = STACK_CANARY; }
�ڴ�й©��� ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 typedef struct { void *ptr; size_t size; const char *file; int line; } mem_block_t ; #define MAX_MEM_BLOCKS 100 static mem_block_t mem_blocks[MAX_MEM_BLOCKS];static int mem_block_count = 0 ;void * debug_malloc (size_t size, const char *file, int line) { void *ptr = malloc (size); if (ptr && mem_block_count < MAX_MEM_BLOCKS) { mem_blocks[mem_block_count].ptr = ptr; mem_blocks[mem_block_count].size = size; mem_blocks[mem_block_count].file = file; mem_blocks[mem_block_count].line = line; mem_block_count++; } return ptr; } #define malloc(size) debug_malloc(size, __FILE__, __LINE__)
4. ʵʱ��������� ����ִ��ʱ����� ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 void dwt_init (void ) { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; DWT->CYCCNT = 0 ; } uint32_t get_cycle_count (void ) { return DWT->CYCCNT; } void measure_function_time (void ) { uint32_t start_time = get_cycle_count(); target_function(); uint32_t end_time = get_cycle_count(); uint32_t cycles = end_time - start_time; uint32_t us = cycles / 168 ; printf ("Function execution time: %lu us\n" , us); }
? �����Լ��� 1. Printf�����Ż� �ض���printf�������� ��
1 2 3 4 5 6 7 8 9 10 11 12 13 int _write(int file, char *ptr, int len) { for (int i = 0 ; i < len; i++) { ITM_SendChar((*ptr++)); } return len; } int _write(int file, char *ptr, int len) { HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY); return len; }
�������������Ϣ ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #ifdef DEBUG #define DBG_PRINT(fmt, args...) printf("DEBUG: " fmt, ## args) #else #define DBG_PRINT(fmt, args...) #endif typedef enum { LOG_ERROR = 0 , LOG_WARN = 1 , LOG_INFO = 2 , LOG_DEBUG = 3 } log_level_t ; #define LOG_LEVEL LOG_INFO #define LOG(level, fmt, args...) \ do { \ if (level <= LOG_LEVEL) { \ printf("[%s] " fmt "\n" , log_level_str[level], ## args); \ } \ } while(0)
2. ���Ի��� 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #ifdef DEBUG #define ASSERT(expr) \ do { \ if (!(expr)) { \ printf("ASSERT failed: %s, file %s, line %d\n" , \ #expr, __FILE__, __LINE__); \ while(1); \ } \ } while(0) #else #define ASSERT(expr) #endif void buffer_write (uint8_t *buf, int index, uint8_t data) { ASSERT(buf != NULL ); ASSERT(index >= 0 && index < BUFFER_SIZE); buf[index] = data; }
3. �������� 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 void watchdog_debug_init (void ) { #ifdef DEBUG __HAL_DBGMCU_FREEZE_IWDG(); #endif } void task_with_watchdog_debug (void ) { HAL_IWDG_Refresh(&hiwdg); process_step1(); HAL_IWDG_Refresh(&hiwdg); process_step2(); HAL_IWDG_Refresh(&hiwdg); }
4. ���ܷ��� �������ø��� ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #ifdef FUNCTION_TRACE #define FUNC_ENTER() printf("ENTER: %s\n" , __FUNCTION__) #define FUNC_EXIT() printf("EXIT: %s\n" , __FUNCTION__) #else #define FUNC_ENTER() #define FUNC_EXIT() #endif void example_function (void ) { FUNC_ENTER(); FUNC_EXIT(); }
�ڴ�ʹ�ü�� ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void check_stack_usage (void ) { extern uint32_t _estack; extern uint32_t _sstack; uint32_t stack_size = (uint32_t )&_estack - (uint32_t )&_sstack; uint32_t current_sp; __asm volatile ("mov %0, sp" : "=r" (current_sp)) ; uint32_t used_stack = (uint32_t )&_estack - current_sp; uint32_t usage_percent = (used_stack * 100 ) / stack_size; printf ("Stack usage: %lu/%lu bytes (%lu%%)\n" , used_stack, stack_size, usage_percent); }
?? ���Ի���� 1. OpenOCD���� ��װOpenOCD ��
1 2 3 4 5 6 7 8 9 10 sudo apt install openocdgit clone https://git.code.sf.net/p/openocd/code openocd cd openocd./bootstrap ./configure --enable-stlink --enable-jlink make sudo make install
�����ļ�ʾ�� ��
1 2 3 4 5 6 7 8 9 source [find interface/stlink.cfg]source [find target/stm32f4x.cfg]$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x8000 reset_config srst_only
�������ԻỰ ��
1 2 3 4 5 6 7 8 9 openocd -f openocd.cfg arm-none-eabi-gdb firmware.elf (gdb) target remote localhost:3333 (gdb) monitor reset halt (gdb) load (gdb) continue
2. VSCode�������� launch.json���� ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { "version" : "0.2.0" , "configurations" : [ { "name" : "Debug STM32" , "type" : "cortex-debug" , "request" : "launch" , "servertype" : "openocd" , "cwd" : "${workspaceRoot}" , "executable" : "./build/firmware.elf" , "configFiles" : [ "interface/stlink.cfg" , "target/stm32f4x.cfg" ] , "svdFile" : "./STM32F407.svd" , "runToMain" : true , "showDevDebugOutput" : true } ] }
? �������ʵ�� 1. ���Բ��� �ֲ���Է� ��
1 Ӧ�ò� �� �м���� �� ������ �� Ӳ����
���ַ���λ ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 void suspicious_function (void ) { process_part1(); printf ("Checkpoint 1: OK\n" ); process_part2(); printf ("Checkpoint 2: OK\n" ); process_part3(); }
2. ����������֤ �����Ա�� ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 int safe_divide (int a, int b) { if (b == 0 ) { LOG(LOG_ERROR, "Division by zero!" ); return -1 ; } return a / b; } void safe_array_access (int *array , int size, int index) { if (array == NULL ) { LOG(LOG_ERROR, "Null pointer!" ); return ; } if (index < 0 || index >= size) { LOG(LOG_ERROR, "Array index out of bounds: %d" , index); return ; } array [index] = 0 ; }
3. ������Ϣ���� �ṹ����־ ��
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 typedef struct { uint32_t timestamp; log_level_t level; const char *module; const char *message; } log_entry_t ; void structured_log (log_level_t level, const char *module, const char *fmt, ...) { char buffer[256 ]; va_list args; va_start(args, fmt); vsnprintf(buffer, sizeof (buffer), fmt, args); va_end(args); printf ("[%lu][%s][%s] %s\n" , HAL_GetTick(), log_level_str[level], module, buffer); } structured_log(LOG_INFO, "UART" , "Received %d bytes" , count);
? ����ȫע������ 1. ����������ȫ 1 2 3 4 5 6 7 8 #ifndef PRODUCTION #define DEBUG_PRINT(fmt, args...) printf(fmt, ## args) #define DEBUG_BREAK() __asm("bkpt 0" ) #else #define DEBUG_PRINT(fmt, args...) #define DEBUG_BREAK() #endif
2. ������Ϣ���� 1 2 3 4 5 6 void log_user_info (const char *username, const char *password) { LOG(LOG_INFO, "User login: %s" , username); }
? ѧϰ��Դ���� �Ƽ��鼮
��Ƕ��ʽ�������ԡ�- ������
��ARM Cortex-M3Ȩ��ָ�ϡ�- Joseph Yiu
��Ƕ��ʽʵʱ����ϵͳ��C/OS-III��- Jean J. Labrosse
������Դ
ʵ�ù���
Ӳ������ : J-Link, ST-Link, Logic Analyzer
�������� : GDB, OpenOCD, Keil MDK, IAR
�������� : Wireshark, PulseView, PC-lint
? �ܽ� Ƕ��ʽ����������һ���ۺ��Լ�������Ҫ���գ�
���ۻ��� : �˽����ԭ���ͷ�����
����ʹ�� : ����ʹ�ø��ֵ��Թ���
ʵս���� : ͨ������ʵ�����۾���
ϵͳ˼ά : ��Ӳ����������ȫջ��������
�����ĵ� ��
? ϸ�Ĺ۲� : ע��ÿһ���쳣����
? ��˼�� : ������������λ����
? ��¼�ܽ� : �������˵���֪ʶ��
? �Ŷ�Э�� : ����Ѱ������ͷ�������
������Щ���Լ��ܣ������������Ƕ��ʽ����Ч�ʺ�������������
? ���Խ�� : “���Ծ�����̽��������Ҫ���ġ�ϸ�ĺ���˼ά��ÿһ��bug����һ�����⣬�ȴ���ȥ���”
��������Ƽ� :