0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

手把手教你制作DAPLink

Rice嵌入式开发技术分享 来源:Rice嵌入式 作者:Rice嵌入式 2023-12-26 08:35 次阅读

这篇文章主要描述利用RT-THREAD+CherryUSB制作DapLink调试器(R_DapLink)全流程。这里先感谢网友:sakumisu提供cherryUSB协议栈的技术支持。

  • 什么是下载调试器简单来说,下载调试器是将PC(例如通过USB协议)发送的命令转换为MCU(负责MCU内部外围设备)理解的语言(例如SWD或JTAG协议)的设备,加载代码并精确控制执行。

  • 什么是标准简单来说,标准是一组规则和协议,特定行业中的每个参与者都同意遵循并执行。符合某种内核的单片机Q,都可以使用这种协议来下载程序。JTAG和SWD其实都是一种标准的协议。比如JTAG和SWD,都支特下载ARMQ内核单片机的程序。

  • 各种调试器的区别「J-Link:」最有名气、各种渠道版本最多,号称支持芯片量最多。

  1. 适合场景:如果项目文件比较大,首选!下载又快又稳,仿真调试也是杠杠的神器。
  2. 优点:最快、稳如老狗。STM32F407芯片+109K代码实测8秒完成烧录过程。
  3. 缺点:最贵,和谐版都四五十元起步,正版上至数千元。注意:V9版本以下的J-Link大多数不支持STM8

「ST-Link:」随着STM32这十年八年的垄断,ST-Link也跟着发大火了, 妥妥销量一哥。

  1. 适合场景:学校里开STM32课程的,几乎每个宿舍都有吧~
  2. 优点:便宜、便宜,便宜!x宝13元包邮。特别注意一下:驱动包就在KEIL本身的文件夹里头,你说它多火。
  3. 缺点:不够稳定! 可能不时的来个弹窗。

「CMSIS-DAP:」硬件开源!这两三年,含量在火箭式起飞。很多人知道它是因为技小新和立创EDA的开源工程。比STLink稍贵。

  1. 适合场景:玩stm32的,这个是最优选择。
  2. 优点:开源、虚拟串口、免驱。大爱的虚拟串口,很爽、很爽, (有些下载器也有虚拟串口),更爱它开源没心病。
  3. 缺点:真没啥缺点,能拼JLink的稳定, 也能拼ST-Link的便宜,还没版权问题!109K代码烧录实测10秒,也算杠杠的吧。

「DAP-Link:」CMSIS-DAP的升级版。

  1. 适合场景:嗯,如果你的动手能力高超,这个最合适,软硬都开源,可玩性极高,比如做个拖拽的脱机下载
  2. 优点:拖拽烧录、升级固件。包括了CMSIS-DAP的优点:开源+虚拟串口+免驱。
  3. 缺点:真没啥缺点,能拼JLink的稳定, 也能拼ST-Link的便宜,还没版权问题!

R_DapLink说明

  • R_DapLink支持:DapLink+CDC(虚拟串口),采用USB2.1协议。采用GPIO模拟SWD时序

硬件准备

  • R_DapLink的硬件采用stm32f103c8t6,内核:ARM Cortex-M3,主频:72MHz,Flash:64KB,RAM:20KB
b79144b2-a386-11ee-be60-92fbcf53809c.jpg
  • 开发板我们需要做一些改动,由于SWD的数据线有输入和输出,我们这里采用两个引脚合并成一个引脚作为SWD的数据线。stm32的GPIOB0作为SWD的数据线的输出,stm32的GPIOA7作为SWD的数据线的输入
b79765f4-a386-11ee-be60-92fbcf53809c.jpg
  • 准备一个现成的调试器来调试我们的R_DapLink,这里采用正点原子的DapLink。
  • R_DapLink支持CDC(虚拟串口),所以我们还需要一个串口工具,这里采用CH340。

软件准备

  • R_DapLink采用RT-Thread作为我们实时系统,提供系统调度,IPC通信。选择RT-Thread的原因:RT-Thread已经包含了cherryUSB协议栈软件,这给我减少了很多移植的工作量。
  • R_DapLink的USB协议栈采用cherryUSB协议栈,其代码链接:https://github.com/cherry-embedded/CherryUSB。cherryUSB协议栈提供了对应的文档,其文档链接:https://cherryusb.readthedocs.io/zh-cn/latest/
  • DAPLink:Arm Mbed DAPLink是一个开源软件项目,可以对Arm Cortex CPU上运行的应用程序进行编程和调试。其链接:https://github.com/ARMmbed/DAPLink

移植DapLink

准备rt-thread工程

  1. 下载rt-thread的源码,源码链接:https://gitee.com/rtthread/rt-thread,我们采用4.1.1的版本,所以下载完源码需要切换到4.1.1版本中。
  2. 下载完源码,进入stm32f103-blue-pill这个BSP,路径:xxxbspstm32stm32f103-blue-pill,通过env工具dist出来,
b7add65e-a386-11ee-be60-92fbcf53809c.jpg
  1. 从dist目录下拷贝stm32f103-blue-pill工程出来,并修改名字为:r_daplink。

增加cherryUSB软件包

  1. 进入上面准备好的工程:r_daplink,在工程目录中打开env工具,输入menuconfig。
b7b7be6c-a386-11ee-be60-92fbcf53809c.jpg
  1. 配置增加cherryUSB
b7bed01c-a386-11ee-be60-92fbcf53809c.jpg
  1. r_daplink的USB是作为device,所以选择选择Device mode
b7ce8994-a386-11ee-be60-92fbcf53809c.jpg
  1. r_daplink的usb的速度为全速,选择FS,stm32f103c86的USB IP为FSDEV,并选择上cdc,用于实现虚拟串口。
b7dccb12-a386-11ee-be60-92fbcf53809c.jpg

增加DAPLink源码

  1. 下载DAPLink代码,链接:https://github.com/ARMmbed/DAPLink
  2. DAPLink代码很多,但实际我们只用核心的部分,将DAPLink代码中:sourcedaplinkcmsis-dap目录拷贝到r_daplink工程中。
b7e906a2-a386-11ee-be60-92fbcf53809c.jpg
  1. r_daplink工程中增加两个文件:DAP_config.h和IO_Config.h文件。其中:DAP_config.h用于配置DAPLink的配置,并适配SWD时序模拟的GPIO,IO_Config.h用于配置SWD使用到的GPIO的描述。具体内容看我的开源仓:https://gitee.com/RiceChen0/r_daplink

USB适配

  1. r_daplink的daplink采用winusb+cdc,其中包含3个接口,4个端点,其设备描述符适配:
constuint8_tcdc_winusb_descriptor[]={
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1,0xEF,0x02,0x01,USBD_VID,USBD_PID,0x0100,0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE,0x03,0x01,USB_CONFIG_BUS_POWERED,USBD_MAX_POWER),
USB_INTERFACE_DESCRIPTOR_INIT(0x00,0x00,0x02,0xff,0x00,0x00,0x02),
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP,0x02,USB_MAX_MPS,0x00),
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP,0x02,USB_MAX_MPS,0x00),
CDC_ACM_DESCRIPTOR_INIT(0x01,CDC_INT_EP,CDC_OUT_EP,CDC_IN_EP,USB_MAX_MPS,0x00),
///////////////////////////////////////
///string0descriptor
///////////////////////////////////////
USB_LANGID_INIT(USBD_LANGID_STRING),
///////////////////////////////////////
///string1descriptor
///////////////////////////////////////
0x12,/*bLength*/
USB_DESCRIPTOR_TYPE_STRING,/*bDescriptorType*/
'R',0x00,/*wcChar0*/
'i',0x00,/*wcChar1*/
'c',0x00,/*wcChar2*/
'e',0x00,/*wcChar3*/
'C',0x00,/*wcChar4*/
'h',0x00,/*wcChar5*/
'e',0x00,/*wcChar6*/
'n',0x00,/*wcChar7*/
///////////////////////////////////////
///string2descriptor
///////////////////////////////////////
0x1E,/*bLength*/
USB_DESCRIPTOR_TYPE_STRING,/*bDescriptorType*/
'R',0x00,/*wcChar0*/
'i',0x00,/*wcChar1*/
'c',0x00,/*wcChar2*/
'e',0x00,/*wcChar3*/
'',0x00,/*wcChar4*/
'C',0x00,/*wcChar5*/
'M',0x00,/*wcChar6*/
'S',0x00,/*wcChar7*/
'I',0x00,/*wcChar8*/
'S',0x00,/*wcChar9*/
'-',0x00,/*wcChar10*/
'D',0x00,/*wcChar11*/
'A',0x00,/*wcChar12*/
'P',0x00,/*wcChar13*/
///////////////////////////////////////
///string3descriptor
///////////////////////////////////////
0x1C,/*bLength*/
USB_DESCRIPTOR_TYPE_STRING,/*bDescriptorType*/
'R',0x00,/*wcChar0*/
'i',0x00,/*wcChar1*/
'c',0x00,/*wcChar2*/
'e',0x00,/*wcChar3*/
'-',0x00,/*wcChar4*/
'2',0x00,/*wcChar5*/
'0',0x00,/*wcChar6*/
'2',0x00,/*wcChar7*/
'3',0x00,/*wcChar8*/
'0',0x00,/*wcChar9*/
'1',0x00,/*wcChar10*/
'0',0x00,/*wcChar11*/
'1',0x00,/*wcChar12*/
0x00
};
  1. winusb端点适配
voidusbd_winusb_out(uint8_tep,uint32_tnbytes)
{
usbd_ep_start_read(WINUSB_OUT_EP,usb2dap_buff[usb2dap_index],USB2DAP_PACK_SIZE);
}

voidusbd_winusb_in(uint8_tep,uint32_tnbytes)
{
if((nbytes%USB_MAX_MPS)==0&&nbytes){
usbd_ep_start_write(WINUSB_IN_EP,NULL,0);
}
}

structusbd_endpointwinusb_out_ep={
.ep_addr=WINUSB_OUT_EP,
.ep_cb=usbd_winusb_out
};

structusbd_endpointwinusb_in_ep={
.ep_addr=WINUSB_IN_EP,
.ep_cb=usbd_winusb_in
};
  1. cdc端点适配
voidusbd_cdc_acm_bulk_out(uint8_tep,uint32_tnbytes)
{
usbd_ep_start_read(CDC_OUT_EP,usb2uart_buff,USB2UART_PACK_SIZE);
}

voidusbd_cdc_acm_bulk_in(uint8_tep,uint32_tnbytes)
{
if((nbytes%USB_MAX_MPS)==0&&nbytes){
usbd_ep_start_write(CDC_IN_EP,NULL,0);
}
}

structusbd_endpointcdc_out_ep={
.ep_addr=CDC_OUT_EP,
.ep_cb=usbd_cdc_acm_bulk_out
};

structusbd_endpointcdc_in_ep={
.ep_addr=CDC_IN_EP,
.ep_cb=usbd_cdc_acm_bulk_in
};
  1. usb初始化
intusb_service_init(void)
{
usbd_desc_register(cdc_winusb_descriptor);
usbd_bos_desc_register(&bos_desc);
usbd_msosv2_desc_register(&msosv2_desc);

usbd_add_interface(&intf0);
usbd_add_endpoint(&winusb_out_ep);
usbd_add_endpoint(&winusb_in_ep);

usbd_add_interface(usbd_cdc_acm_init_intf(&intf0));
usbd_add_interface(usbd_cdc_acm_init_intf(&intf1));
usbd_add_endpoint(&cdc_out_ep);
usbd_add_endpoint(&cdc_in_ep);

usbd_initialize();
returnRT_EOK;
}
  1. 以上适配完将板子的USB插上电脑,通过设备管理器查看是否成功
b7ef8a86-a386-11ee-be60-92fbcf53809c.jpg

cdc适配

  1. 我们采用串口3作为我们USB到串口的转发。
  2. cdc虚拟串口的配置传给串口3,具体实现如下:
staticvoiduart_config_set(uart_config_t*config)
{
if(rt_memcmp(&uart_config,(rt_uint8_t*)config,sizeof(uart_config_t))!=0)
{
rt_memcpy((rt_uint8_t*)&uart_config,config,sizeof(uart_config_t));
uart_is_config=RT_TRUE;
}
if(uart_is_config)
{
structserial_configureserial_config=RT_SERIAL_CONFIG_DEFAULT;
if(uart_dev!=RT_NULL){
rt_device_close(uart_dev);
uart_dev=RT_NULL;
}

uart_is_config=RT_FALSE;
uart_dev=rt_device_find(UART_NAME);
serial_config.baud_rate=uart_config.baudrate;
serial_config.stop_bits=uart_config.stopbit;
serial_config.parity=uart_config.parity;
serial_config.data_bits=uart_config.databit;
serial_config.bufsz=UART_PACK_SIZE;
rt_device_control(uart_dev,RT_DEVICE_CTRL_CONFIG,&serial_config);

rt_device_open(uart_dev,RT_DEVICE_FLAG_DMA_RX);
rt_device_set_rx_indicate(uart_dev,uart_recv_isr);
}
}
  1. cdc虚拟串口数据到串口3的实现如下:
voidusb2uart_handler(rt_uint8_t*data,rt_uint16_tlen)
{
if(uart_dev)
{
rt_device_write(uart_dev,0,data,len);
}
}
  1. 串口3数据到cdc虚拟串口的实现如下:
staticrt_err_tuart_recv_isr(rt_device_tdev,rt_size_tsize)
{
if(size>0)
{
rt_sem_release(&uart_rx_sem);
}
returnRT_EOK;
}

staticvoiduart2usb_handler(void*param)
{
rt_uint16_trx_size=0;
for(;;)
{
rt_sem_take(&uart_rx_sem,RT_WAITING_FOREVER);
if(uart_dev)
{
rx_size=rt_device_read(uart_dev,0,uart_rx_buff,UART_PACK_SIZE);
usb_service_uart2usb(uart_rx_buff,rx_size);
}
}
}
  1. 测试验证:
b802227c-a386-11ee-be60-92fbcf53809c.jpg

daplink适配

  1. daplink的实现原理:将usb接收到的数据传输到DAP_ExecuteCommand()函数,并且从这个函数获取返回数据,将数据传输到usb上。

  2. 我们将usb接收到数据通过邮箱的方式传输到数据处理现成,具体实现如下:

staticvoidusb2dap_handler(rt_uint8_t*data,rt_uint16_tlen)
{
rt_mb_send(&dap2usb_mb,(rt_ubase_t)data);
}

staticvoiddap2usb_handler(void*param)
{
char*rx_data=NULL;
for(;;)
{
if(rt_mb_recv(&dap2usb_mb,(rt_ubase_t*)&rx_data,RT_WAITING_FOREVER)==RT_EOK)
{
if(rx_data[0]==ID_DAP_QueueCommands)
{
rx_data[0]=ID_DAP_ExecuteCommands;
}
dap2usb_size=DAP_ExecuteCommand((constuint8_t*)rx_data,dap2usb_buff);
usb_service_dap2usb(dap2usb_buff,dap2usb_size);
}
}
}
  1. 验证:我们keil里面选择我们dap,可以正常的识别到DAP,并且能识别链接的设备
b80863d0-a386-11ee-be60-92fbcf53809c.jpg

r_daplink的烧录验证

b80ed74c-a386-11ee-be60-92fbcf53809c.jpgb81ba030-a386-11ee-be60-92fbcf53809c.jpg

总结

r_daplink的开源链接:https://gitee.com/RiceChen0/r_daplink

b82a1e44-a386-11ee-be60-92fbcf53809c.png


审核编辑 黄宇


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • usb
    usb
    +关注

    关注

    60

    文章

    7936

    浏览量

    264451
  • Link
    +关注

    关注

    0

    文章

    101

    浏览量

    26952
  • 调试器
    +关注

    关注

    1

    文章

    303

    浏览量

    23716
  • dap
    dap
    +关注

    关注

    1

    文章

    24

    浏览量

    8470
收藏 人收藏

    评论

    相关推荐

    手把手教你制作机器人

    手把手教你制作机器人
    发表于 08-12 09:52

    手把手教你制作无线充电器

    手把手教你制作无线充电器(无线充电原理+产品应用+DIY实例)
    发表于 09-28 07:48

    手把手教你构建一个完整的工程

    手把手教你构建一个完整的工程
    发表于 08-03 09:54 33次下载
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>构建一个完整的工程

    手把手教你写批处理-批处理的介绍

    手把手教你写批处理-批处理的介绍
    发表于 10-25 15:02 69次下载

    美女手把手教你如何装机(中)

    美女手把手教你如何装机(中) 再来是硬碟的部份,这款机壳还不错,可以旋转支架~
    发表于 01-27 11:14 1462次阅读

    美女手把手教你如何装机(下)

    美女手把手教你如何装机(下) 接著下来就是今天的重头戏,开核萝!~
    发表于 01-27 11:16 2923次阅读

    手把手教你制作立体声调频电台

    手把手教你制作立体声调频电台
    发表于 03-28 14:43 5538次阅读
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b><b class='flag-5'>制作</b>立体声调频电台

    手把手教你制作XDS100V3教程+固件烧写方法--学DSP必备

    手把手教你制作XDS100V3教程+固件烧写方法--学DSP必备
    发表于 06-17 16:48 104次下载

    手把手教你学电子书制作

    手把手教你学电子书制作,可以自己DIY电子书
    发表于 09-13 11:26 0次下载

    手把手教你安装Quartus II

    本章手把手把教你如何安装 Quartus II 软件 ,并将它激活 。此外 还有USB -Blaster下载器的驱动安装步骤 。
    发表于 09-18 14:55 9次下载

    手把手教你在家搭建监控系统

    手把手教你在家搭建监控系统
    发表于 01-17 19:47 25次下载

    手把手教你如何开始DSP编程

    手把手教你如何开始DSP编程。
    发表于 04-09 11:54 12次下载
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>如何开始DSP编程

    手把手教你学LabVIEW视觉设计

    手把手教你学LabVIEW视觉设计手把手教你学LabVIEW视觉设计手把手教你学LabVIEW视
    发表于 03-06 01:41 3129次阅读

    手把手教你开关电源PCB排板

    手把手教你开关电源PCB排板(新型电源技术)-分享一下开关电源PCB排板的基本要点及分析,以及例子讲解。绝对的手把手
    发表于 09-18 12:27 57次下载
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>开关电源PCB排板

    手把手教你学FPGA仿真

    电子发烧友网站提供《手把手教你学FPGA仿真.pdf》资料免费下载
    发表于 10-19 09:17 2次下载
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>学FPGA仿真