TN-rk3399使用swd调试系统.

1.通过阅读一些参数资料,他们都用过转接出micro_sd,通过连接标准的swd信号实现调试的。

https://crwulff.blogspot.com/p/rock64.html

http://notes.zahoryzontnik.com/

包括张银奎老师的GDK8和挥马枪的一些资料,我本人就购买了GDK8和挥马枪

https://www.nanocode.cn/#/gdk8/index

https://www.nanocode.cn/#/ntp/index

2.对于不太想折腾的来说直接使用张老师提供的套件即可了。对于喜欢捡电子垃圾的朋友,当然会追求极致性价比请继续看下去

先声明一点,基本上rk3328,rk3399,rk3566,rk3588等,他们的SWD信号都会和MICRO_SD接口的信号线复用(并且位置都是一样的),

以rk3399为例:原理图

 

 

此图十分清晰,你需要引出此二根线,下面看下标准的SDMMC接口定义图

Pin # Pin name Signal Function
1 DAT2 Data Bit 2
2 CD/DAT3 Card Detect / Data Bit 3
3 CMD Command Line
4 Vdd Supply Voltage 2.7v / 3.6v
5 CLK Clock
6 Vss Ground
7 DAT0 Data Bit 0
8 DAT1 Data Bit 1

 

朋友们看明白没有,上面已经表清楚了脚的号码,DATA2为1号脚,DATA3为2号,VSS(地)是6号脚

你需要引出1,2,6三根线才能调试,如何引出呢?TF卡测试槽或者自己PCB画一个,我这里选择TF测试槽(买张老师GDK可以给你准备好一根转接线)

某宝搜:tf卡测试卡套

 

将卡套 1,2,6 号线焊接到杜邦线上,就行了,这里肯定会难住很多朋友,因为大部分的朋友跟我一样是电子白痴,纯软件出生

没有线的朋友可以找身边的会焊接的朋友帮忙焊接一下,就三根线而已,我的就是我弟帮我焊接的,丑是丑了点,但是能用

看见没有,只需要引出三根线就行了。调试的时候将sd卡槽插入被调试的机器,

或者自己从嘉立创免费打板打一个:https://oshwhub.com/shuobatian/tf-2-54

然后自己把柱子焊板子上,这个比上面操作要简单因为焊盘距离相对较远。

3.准备好硬件调试器,其实只要支持的标准的SWD协议的调试器都可以,

比如DAPLINK

https://github.com/ARMmbed/DAPLink

这个项目的arm公司开源的,支持很多单片机实现这个SWD协议,如果你想自己做板子,参考

https://oshwhub.com/hanxiaohu/daplink-hs-share

https://oshwhub.com/jixin002/daplink_jx

嘉立创开源广场自己搜,由于我只能看懂简单的原理图,是个电子废物

因此跟我一样的朋友还是上某宝上买吧,

我推荐这家,为啥,因为我自己就买的这家,并且从金华发货,到杭州很快,并且店家老板

是个硬件大佬,靠谱的,其他某宝搜的daplink,太便宜的不要买比如10几块这种基本用不了几次就会坏,

价格在30到100之间是正常的,当然我建议到这里MuseLab店子里买

4.配置openocd,openocd需要两个文件一个调试器的配置文件一个目标板的配置文件。

openocd windows下载地址:https://gnutoolchains.com/arm-eabi/openocd/

我直接到这里下载的

我这里给出两个配置文件例子吧,连线需要连接TCK/SWD_CK,TMS/SWD_IO,GND三根线到对应的位置

 

cmsis-dap.cfg

 1 # SPDX-License-Identifier: GPL-2.0-or-later
 2 
 3 #
 4 # ARM CMSIS-DAP compliant adapter
 5 #
 6 # http://www.keil.com/support/man/docs/dapdebug/
 7 #
 8 
 9 adapter driver cmsis-dap
10 
11 # Optionally specify the serial number of CMSIS-DAP usb device.
12 # adapter serial 02200201E6661E601B98E3B9

rk3399.cfg

 1 # SPDX-License-Identifier: GPL-2.0-or-later
 2 # Rockchip RK3399 Target
 3 # https://rockchip.fr/RK3399%20datasheet%20V1.8.pdf
 4 # https://rockchip.fr/Rockchip%20RK3399%20TRM%20V1.4%20Part1.pdf
 5 
 6 if { [info exists CHIPNAME] } {
 7   set _CHIPNAME $CHIPNAME
 8 } else {
 9   set _CHIPNAME rk3399
10 }
11 
12 #
13 # Main DAP
14 #
15 if { [info exists DAP_TAPID] } {
16    set _DAP_TAPID $DAP_TAPID
17 } else {
18    set _DAP_TAPID 0x5ba02477
19 }
20 
21 adapter speed 12000
22 
23 transport select swd
24 
25 # declare the one SWD tap to access the DAP
26 swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version
27 
28 # create the DAP
29 dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
30 target create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0
31 set _TARGETNAME $_CHIPNAME.lcore
32 # declare the 6 main application cores
33 set _smp_command ""
34 
35 set $_TARGETNAME.base(0) 0x80030000
36 set $_TARGETNAME.base(1) 0x80032000
37 set $_TARGETNAME.base(2) 0x80034000
38 set $_TARGETNAME.base(3) 0x80036000
39 set $_TARGETNAME.cti(0) 0x80038000
40 set $_TARGETNAME.cti(1) 0x80039000
41 set $_TARGETNAME.cti(2) 0x8003a000
42 set $_TARGETNAME.cti(3) 0x8003b000
43 
44 
45 set _TARGETNAME $_CHIPNAME.bcore
46 set $_TARGETNAME.base(4) 0x80210000
47 set $_TARGETNAME.base(5) 0x80310000
48 set $_TARGETNAME.cti(4) 0x80220000
49 set $_TARGETNAME.cti(5) 0x80320000
50 
51 set _cores 6
52 for { set _core 0 } { $_core < $_cores } { incr _core 1 } {
53     if {$_core < 4} {
54         set _TARGETNAME $_CHIPNAME.lcore
55     } else {
56         set _TARGETNAME $_CHIPNAME.bcore
57     }
58 
59 
60     cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 1
61 
62     target create ${_TARGETNAME}$_core aarch64 \
63                          -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \
64                          -dbgbase [set $_TARGETNAME.base($_core)]
65 
66     if { $_core != 0 } {
67         ${_TARGETNAME}$_core configure -defer-examine
68     } else {
69         # uncomment to use hardware threads pseudo rtos
70         # ${_TARGETNAME}$_core configure -rtos hwthread"
71         # 0xff8c0000~0xff8d0000=0x10000 size=0x10000+0x20000 in rk3399-rockpro64.dts
72         ${_TARGETNAME}$_core configure -work-area-size 0x30000 -work-area-phys 0xff8c0000 \
73                                 -work-area-backup 0
74     }
75     set _smp_command "$_smp_command ${_TARGETNAME}$_core"
76 }
77 
78 target smp $_smp_command
79 
80 targets rk3399.lcore0

 

运行openocd命令:

openocd -f cmsis-dap.cfg -f rk3399.cfg

这时肯定连不上,因为没有开启swd调试,一般板子默认是sd的功能,需要将其切换到SWD功能,

需要读参考的手册,比如rk3399

你需要将寄存器的某几个位写成相应的值,如何写?通过devmem2这个工具,我这里提供源码,C的,原版的代码有bug不建议使用

  1 /*
  2  * devmem2.c: Simple program to read/write from/to any location in memory.
  3  *
  4  *  Copyright (C) 2000, Jan-Derk Bakker (jdb@lartmaker.nl)
  5  *
  6  *
  7  * This software has been developed for the LART computing board
  8  * (http://www.lart.tudelft.nl/). The development has been sponsored by
  9  * the Mobile MultiMedia Communications (http://www.mmc.tudelft.nl/)
 10  * and Ubiquitous Communications (http://www.ubicom.tudelft.nl/)
 11  * projects.
 12  *
 13  *
 14  * This program is free software; you can redistribute it and/or modify
 15  * it under the terms of the GNU General Public License as published by
 16  * the Free Software Foundation; either version 2 of the License, or
 17  * (at your option) any later version.
 18  *
 19  * This program is distributed in the hope that it will be useful,
 20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 22  * GNU General Public License for more details.
 23  *
 24  * You should have received a copy of the GNU General Public License
 25  * along with this program; if not, write to the Free Software
 26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 27  *
 28  */
 29 
 30 #include <stdio.h>
 31 #include <stdlib.h>
 32 #include <unistd.h>
 33 #include <string.h>
 34 #include <errno.h>
 35 #include <signal.h>
 36 #include <fcntl.h>
 37 #include <ctype.h>
 38 #include <termios.h>
 39 #include <sys/types.h>
 40 #include <sys/mman.h>
 41 
 42 #define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
 43   __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)
 44 
 45 #define MAP_SIZE 4096UL
 46 #define MAP_MASK (MAP_SIZE - 1)
 47 
 48 int main(int argc, char **argv) {
 49     int fd;
 50     void *map_base, *virt_addr;
 51         unsigned long read_result, writeval;
 52         off_t target;
 53         int access_type = 'w';
 54 
 55         if(argc < 2) {
 56                 fprintf(stderr, "\nUsage:\t%s { address } [ type [ data ] ]\n"
 57                         "\taddress : memory address to act upon\n"
 58                         "\ttype    : access operation type : [b]yte, [h]alfword, [w]ord, [i]nt\n"
 59                         "\tdata    : data to be written\n\n",
 60                         argv[0]);
 61                 exit(1);
 62         }
 63         target = strtoul(argv[1], 0, 0);
 64 
 65         if(argc > 2)
 66                 access_type = tolower(argv[2][0]);
 67 
 68 
 69     if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
 70     printf("/dev/mem opened.\n");
 71     fflush(stdout);
 72 
 73     /* Map one page */
 74     map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
 75     if(map_base == (void *) -1) FATAL;
 76     printf("Memory mapped at address %p.\n", map_base);
 77     fflush(stdout);
 78 
 79     virt_addr = map_base + (target & MAP_MASK);
 80     switch(access_type) {
 81                 case 'b':
 82                         read_result = *((unsigned char *) virt_addr);
 83                         break;
 84                 case 'h':
 85                         read_result = *((unsigned short *) virt_addr);
 86                         break;
 87                 case 'w':
 88                         read_result = *((unsigned long *) virt_addr);
 89                         break;
 90                 case 'i':
 91                         read_result = *((unsigned int *) virt_addr);
 92                         break;
 93                 default:
 94                         fprintf(stderr, "Illegal data type '%c'.\n", access_type);
 95                         exit(2);
 96         }
 97     //read_result = 0xffffffffffffffff;
 98     printf("Value at address 0x%X (%p): 0x%lX\n", target, virt_addr, read_result);
 99     fflush(stdout);
100 
101         if(argc > 3) {
102                 writeval = strtoul(argv[3], 0, 0);
103                 switch(access_type) {
104                         case 'b':
105                                 *((unsigned char *) virt_addr) = writeval;
106                                 read_result = *((unsigned char *) virt_addr);
107                                 break;
108                         case 'h':
109                                 *((unsigned short *) virt_addr) = writeval;
110                                 read_result = *((unsigned short *) virt_addr);
111                                 break;
112                         case 'w':
113                                 *((unsigned long *) virt_addr) = writeval;
114                                 read_result = *((unsigned long *) virt_addr);
115                                 break;
116                         case 'i':
117                                 *((unsigned int *) virt_addr) = writeval;
118                                 read_result = *((unsigned long *) virt_addr);
119                                 break;
120                 }
121                 printf("Written 0x%lX; readback 0x%lX\n", writeval, read_result);
122                 fflush(stdout);
123         }
124 
125         if(munmap(map_base, MAP_SIZE) == -1) FATAL;
126     close(fd);
127     return 0;
128 }

这里有坑的是,读的时候w是8字节对齐,一般寄存器又是4字节大小,因此你需要让它对齐才行

参考手册搜这个:force_jtag,一般需要将这个位写成1才行,自己搜找到地址

因此我这里直接给出tn3399这个开发板在linux内核开启swd调试的命令

 

./devmem2 0xFF77e218 w 0x1000180000000000
./devmem2 0xFF77e020 w 0xffffAAAA00005555

分别是操作两个寄存器:GRF_SOC_CON7,GRF_GPIO4B_IOMUX,可以看看这个两个寄存器在芯片手册的上位置

然后我就成功的断了下来了,给大家看几张成功的图

windows需要使用gdb-multiarch才能调试,因为它gdb-multiarch才支持多架构

需要安装msys2和这个包 mingw-w64-x86_64-gdb-multiarch

https://packages.msys2.org/package/mingw-w64-x86_64-gdb-multiarch?repo=mingw64

5.结尾,大家有什么问题可以联系我,我能解答就全解答,便宜的板子哪里买?

ophub支持的板子并且是rk芯片的都可以买

https://github.com/ophub/amlogic-s9xxx-armbian

咸鱼自己去搜这些板子的型号大多非常便宜在100-200之间

记住一定要选择带TF卡槽的,接口多尽量选接口多的,有串口最好,

带千兆网的更好。

大家有什么问题随时可以联系我。

posted @ 2023-11-12 01:57  maojun1998  阅读(306)  评论(3编辑  收藏  举报