首先说一下,我之前的开发流程是:VSCode 编辑代码 + Keil 编译及调试。Keil 的调试功能虽然很强大,但是多数功能需要配合 ARM 自家的 ULINKpro 才可以用,例如 Performance Analyzer、Event Viewer 等。而我手头只有Jlink 和 ULINK 非 pro 版的…

  在最近的项目中,随着代码量的不断增加,Keil 的编译速度瓶颈越来越明显!有的问题往往是调试一分钟,编译半小时!编译过慢的问题已经严重影响工作效率,于是开始寻找一个替代品!

Ozone 调试

  起初,在 SEGGER 官网发现了一个名为 Ozone 的 Jlink 专用的调试器,非常小巧,调试也挺好用。不过,它仅仅就是个 Jlink 配套的调试器,不能编译代码。如果使用它,开发流程就是:VSCode 编辑代码 + Keil 编译 + Ozone 调试

调试的话,需要的功能基本都是全的!

  实际情况是,Keil 本身的调试功能还是挺好用的,再单独用 Ozone 调试似乎也没啥必要。因此,在试用了一段时间之后,现在基本很少用 Ozone 调试了。

后文再讲如何在 Qzone 中添加华大 MCU

SEGGER Embedded Studio

  放弃 Ozone 调试之后,无奈继续使用 Keil 编译及调试,然后继续寻找代替方案。同样在 SEGGER 官网转悠的时候,发现了 SEGGER Embedded Studio 这个东西,试用了一下还是不错的!

  1. 自带多套编译套件:GCC、Clang(LLVM)、SEGGER自家编译套件(应该是基于 LLVM 改的),随便选择使用哪个。
  2. 可以配置使用 ARM 的编译器(Keil 自带的 ARMCC ),这是重点!!! 因为工作环境不允许使用别的编译器发布程序!
  3. 代码编辑功能用起来也还行(相比于 Keil 来说),与 VSCode 这一类相比还是有些逊色!比较明显的就是代码高亮!
  4. 非商用,免费无限制,而 Keil、IAR 均限制代码量大小!

  在后续的了解过程中,发现 SEGGER Embedded Studio 就是 SEGGER 买了 CrossWorks 的代码源代码,然后自己再加工一下改出来的!CrossWorks 本身是支持多种调试器的,SEGGER Embedded Studio 则进行了限制,只能支持自家的 Jlink!! 下面是这两个软件的对比图:

  这两者都使用在线的 Packages 来提供了对于不同厂家的 MCU 的支持。使用者可以直接从软件的 Packages Manger 在线下载自己对应的 MCU 支持包(和 Keil5 中的 Pack Installer 一样的作用)!下面是 两者的 Package Manager 的对比图:

  从支持的 MCU 来看,CrossWorks 要更胜一筹!我觉得,说 SEGGER Embedded Studio 就是 CrossWorks 的阉割版一点都不为过!SEGGER Embedded Studio 也就比 CrossWorks 多了 SEGGER 自家基于 LLVM 的编译套件而已!

  关于 CrossWorks 这里不多说,想要进一步了解它的自行去 CrossWorks 的官网:https://www.rowley.co.uk/。下面我们重点来说一下 SEGGER Embedded Studio,当然,这俩软件的配置及项目管理方式是一模一样的!只要搞懂其中一个,另一个肯定不在话下。

项目管理

  SEGGER Embedded Studio 的项目管理使用了 Solution + Project 的方式,相比于 Keil 的单 Project 项目管理(注:Keil 也支持 WorkSpace),不支持文件夹嵌套 不知道强多少。一个 Solution 下可以有多个 Project,Project 下可以有个多个文件或者文件夹,文件夹下又可以有文件夹或文件!但是,SEGGER Embedded Studio 的 Solution + Project 的配置却是相当混乱的,或者说是不容易理解的!

  上图中,我是经过整理之后(手动编辑了.emProject)的项目文件,默认的项目文件是有好几种配置的。导致新手根本不知道该怎么去更改配置。比如,更改 Solution 的各种配置,还是更改 Project 的各种配置。Solution 下的 Public Configuration 及 Private Configuration 下的各种配置与 Project 下的 Public Configuration 及 Private Configuration 下的各种配置有啥区别?如果在结合 .emProject 那就更难以理解了。

  根据目前我的理解,他们的范围由大到小依次为 Solution > Project > Configuration,后者可以继承前者的各种配置。Public Configuration 可以继承 Private Configuration 中的各种配置,我们实际的处理(编译调试)的项目,实际就是一个个的 Public Configuration。因此,那些通用配置一般都放在上层,下层直接继承!

编译套件选择

  前面我们说过,SEGGER Embedded Studio 本身就带了 GCC、Clang(LLVM)、SEGGER自家编译套件(应该是基于 LLVM 改的)这三种编译套件,在建立项目时,我们可以根据需要选择其中一种。但是这里有个前提,必须是 SEGGER Embedded Studio 所支持的 MCU 才可以。因为,MCU 的启动文件是特定于编译器的。例如,在 STM32 系列 MCU 中,都会带有不容编译器的启动文件:

  除此之外,其他有些文件也是特定于开发环境的,例如,Keil(ARMCC)的分散加载文件(.sct); IAR 的 ILINK Configuration File (.icf)文件等。

SEGGER Embedded Studio 默认(SEGGER 自家编译套件)也是使用 .icf 文件来生成最终的 elf 文件

  很不幸的是,SEGGER Embedded Studio 目前还不支持华大的 MCU。这也就意味着,我们不能在 SEGGER Embedded Studio 中建立华大的 MCU 的项目(华大的官网的开发环境支持包也没有提供对 SEGGER Embedded Studio 的支持)。

  幸运的是,SEGGER Embedded Studio 支持使用外部编译套件,我么可以直接将 Keil 的项目文件转成 SEGGER Embedded Studio 项目,编译套件选择外部的 ARMCC。

其中,选择 MCU 型号这一步,仍然需要我们自己来处理,SEGGER 的所有工具目前都不支持华大 MCU,下面我们来讲解如何处理!

添加华大 MCU 支持

  SEGGER 的所有工具目前都不支持华大 MCU 的,在选择 MCU 的列表中,是没有华大 MCU 的。在 SEGGER 的系列工具中(都是使用的 Jlink 的配置文件),都会有个名为 JLinkDevices.xml 的文件,这个文件,就是Jlink 支持的 MCU 的列表。注意:旧版本的 Jlink 没有这文件!

我们可以直接编辑这个文件,将华大MCU添加进去,如下:

  <!--        之前的全部省略         --><Device><ChipInfo Vendor="O2Micro" Name="OZ93510F160LN" Core="JLINK_CORE_CORTEX_M0" /><FlashBankInfo Name="QSPI Flash" BaseAddr="0x60000000" MaxSize="0x00020000" Loader="Devices/O2Micro/O2Micro_OZ93510F160LN_QSPI.elf" LoaderType="FLASH_ALGO_TYPE_OPEN" /></Device><!--                 --><!-- HDSC (HC32) --><!--                 --><Device><ChipInfo Vendor="HDSC" Name="HC32L176"  WorkRAMAddr="0x20000000" WorkRAMSize="0x2000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_128K" BaseAddr="0x0" MaxSize="0x20000" Loader="Devices/HDSC/FlashHC32L17X_128K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32L136"  WorkRAMAddr="0x20000000" WorkRAMSize="0x2000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_64K" BaseAddr="0x0" MaxSize="0x10000" Loader="Devices/HDSC/FlashHC32L13X_64K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32L130"  WorkRAMAddr="0x20000000" WorkRAMSize="0x2000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_64K" BaseAddr="0x0" MaxSize="0x10000" Loader="Devices/HDSC/FlashHC32L13X_64K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32F030"  WorkRAMAddr="0x20000000" WorkRAMSize="0x2000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_64K" BaseAddr="0x0" MaxSize="0x10000" Loader="Devices/HDSC/FlashHC32F030_64K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32L110x4"  WorkRAMAddr="0x20000000" WorkRAMSize="0x800" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_16K" BaseAddr="0x0" MaxSize="0x4000" Loader="Devices/HDSC/FlashHC32L110_16K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32L110x6"  WorkRAMAddr="0x20000000" WorkRAMSize="0x1000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_32K" BaseAddr="0x0" MaxSize="0x8000" Loader="Devices/HDSC/FlashHC32L110_32K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32F003"  WorkRAMAddr="0x20000000" WorkRAMSize="0x800" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_16K" BaseAddr="0x0" MaxSize="0x4000" Loader="Devices/HDSC/FlashHC32F003_16K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32F005"  WorkRAMAddr="0x20000000" WorkRAMSize="0x1000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_32K" BaseAddr="0x0" MaxSize="0x8000" Loader="Devices/HDSC/FlashHC32F005_32K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32L15"  WorkRAMAddr="0x20000000" WorkRAMSize="0x1800" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_128K" BaseAddr="0x0" MaxSize="0x20000" Loader="Devices/HDSC/HC32L15.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32F_M14"  WorkRAMAddr="0x20000000" WorkRAMSize="0x2000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_128K" BaseAddr="0x0" MaxSize="0x20000" Loader="Devices/HDSC/HC32F_M14.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32F46x"  WorkRAMAddr="0x20000000" WorkRAMSize="0x10000" Core="JLINK_CORE_CORTEX_M4"/><FlashBankInfo Name="Flash_512K" BaseAddr="0x0" MaxSize="0x80000" Loader="Devices/HDSC/HC32F46x.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32L19x"  WorkRAMAddr="0x20000000" WorkRAMSize="0x8000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_256K" BaseAddr="0x0" MaxSize="0x40000" Loader="Devices/HDSC/FlashHC32L19X_256K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32F19x"  WorkRAMAddr="0x20000000" WorkRAMSize="0x8000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_256K" BaseAddr="0x0" MaxSize="0x40000" Loader="Devices/HDSC/FlashHC32F19X_256K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32F17x"  WorkRAMAddr="0x20000000" WorkRAMSize="0x4000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_128K" BaseAddr="0x0" MaxSize="0x20000" Loader="Devices/HDSC/FlashHC32F17X_128K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32L17x"  WorkRAMAddr="0x20000000" WorkRAMSize="0x4000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_128K" BaseAddr="0x0" MaxSize="0x20000" Loader="Devices/HDSC/FlashHC32L17X_128K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32F072"  WorkRAMAddr="0x20000000" WorkRAMSize="0x4000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_128K" BaseAddr="0x0" MaxSize="0x20000" Loader="Devices/HDSC/FlashHC32F072_128K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device><Device><ChipInfo Vendor="HDSC" Name="HC32L07X"  WorkRAMAddr="0x20000000" WorkRAMSize="0x4000" Core="JLINK_CORE_CORTEX_M0"/><FlashBankInfo Name="Flash_128K" BaseAddr="0x0" MaxSize="0x20000" Loader="Devices/HDSC/FlashHC32L07X_128K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/></Device>

添加文件该文件之后,细心地就会发现,上面的代码中的 Loader 指向了一个文件夹中的特定文件,这些文件就是指定的 MCU 的下载算法文件。这些文件我们可以直接从华大官网的 MCU 软件包中获得。然后放到上面写的路径中 Devices/HDSC 中。

这一步处理完成后,我们就可以在 SEGGER 系列工具中选择华大的 MCU 了!

错误处理

  直接从 Keil 导入项目之后,编译可能会报错误,这些错误基本都是因为在自己的项目(Keil)中使用了编译编译环境(Keil)特定的文件导致或者说路径变化导致的!下面我说一下我遇到的几个问题

  1. 第一个错误就是路径问题。在 Keil 中,默认使用 Windows 路径风格:反斜线,例如: …\Directory 。而,SEGGER Embedded Studio 使用的是 Linux 路径风格:斜线,例如:…/…/Directory。如下,我的项目中有使用的命令,就会导致 SEGGER Embedded Studio 报错
  2. 输出文件夹变动导致的错误。项目在导入到 SEGGER Embedded Studio 后,我编译生成的文件路径会被放到 SEGGER Embedded Studio 定义的目录中(配置项中可更改),同样是上图,文件夹变化后(归根结底还是文件路径变化),编译也会报错。我们自行做对应的更改就可以了。

外设寄存器

  经过上面的处理之后基本编译 + 调试应该没有问题了。但是其中一个问题就是,在调试时,只能看到 CPU 的寄存器(Cortex-M 核定义的寄存器),MCU 外设寄存器还是没有的,这里也需要我们自己来处理。

  默认情况下,SEGGER Embedded Studio 使用的 xml 格式的外设寄存器定义文件。但是这个文件只有 SEGGER Embedded Studio 支持的 MCU 才有,我们自己添加的 MCU 是没有这个文件的。幸运的是,SEGGER Embedded Studio 兼容 ARM 定义的 .svd 的文件,我们可以为 SEGGER Embedded Studio 指定我们 MCU 的 SVD 文件。

MCU 的 SVD 文件可以在华大官网的 MCU 软件包中获得!至此,我们应该就可以愉快的编译加调试了!

遗留问题

  1. 目前在调试时发现, Watch某个变量不能正常工作,无法识别结构体变量。

参考

  1. SEGGER Embedded Studio 手册

华大 MCU 之六 SEGGER Embedded Studio 及 Ozone 使用 Jlink 调试相关推荐

  1. Getting Started with STM32 in Segger Embedded Studio

    初识Segger Embedded Studio(SES) 第一次见SES是在"安富莱电子论坛"上,"硬汉"提到SES的一些特性,再加上Jlink的大名,于是试 ...

  2. nRF52832:使用 SEGGER Embedded Studio(SES)创建库文件

    系统环境 系统:macOS 11.2 网络:联网 软件环境 编译器环境:SEGGER Embedded Studio v5.40(SES) 镜像烧录器:nRF Connect v3.6.1 仿真器驱动 ...

  3. 用SEGGER Embedded Studio(SES)开发蓝牙nRF52840

    0. 准备 WIN10电脑一台 nrf52840开发板一套(其实如果基本蓝牙功能的话,nrf52832也行,有更小的成本).nrf52840集成了2.4GHz的各种协议,但还是蓝牙功能比较完善. 仿真 ...

  4. nRF51822:在 macOS 下使用 SEGGER Embedded Studio(SES)搭建开发环境

    系统环境 系统:macOS 10.13.6(Windows 和 Linux 同样适用) 网络:联网 软件环境(只能保证这个版本环境好用) 编译器环境:SEGGER Embedded Studio v3 ...

  5. nRF52832:在 macOS 下使用 SEGGER Embedded Studio(SES)搭建开发环境

    系统环境 系统:macOS 10.14.5(Windows 和 Linux 同样适用) 网络:联网 软件环境 编译器环境:SEGGER Embedded Studio v4.16(SES) 镜像烧录器 ...

  6. Segger Embedded Studio 软件下载和工程配置

    软件下载 Embedded Studio下载地址:https://www.segger.com/downloads/embedded-studio/ 下载完主程序,还需要在官网下载待开发器件对应的库函 ...

  7. HPM6750系列--第五篇 使用Segger Embedded Studio for RISC-V开发环境

    一.目的 之前的博文中<HPM6750系列--第四篇 搭建Visual Studio Code开发调试环境>我们介绍了如何使用visual studio code进行开发调试,但是用起来总 ...

  8. 华大 MCU 之七 DMA 导致 SPI 异常停止的原因分析、DMA 配置的那些坑

    缘起   在最近的项目测试中发现,SPI 通信总是莫名其妙的失败,查看寄存器发现 SPI 已经被停止了.根据手册,SPI 在异常情况下会被强制停止(SPI 的使能为被清零),而根据波形显示通信过程没有 ...

  9. 华大 MCU 之五 SPI 从机 DMA 模式 配置(不能正常接收问题处理)

      最近有个需求是需要使用 华大 MCU(HC32F460) 的 SPI 作为从机来接收数据,无奈搞了两天死活不可用.配置完 SPI 的从机模式后,只要启动主机端的发送就出现如下图所示的错误: 下面是 ...

最新文章

  1. array_filter php5.4 php5.5,PHP 5.4:我可以使用filter_var_array()将多个标志与过滤器一起使用吗?...
  2. 建军92周年,让我们了解那些先进的军用机器人
  3. glance系列二:glance部署及操作
  4. IE浏览器支持响应式网站设计
  5. 和移动对接短信http协议和cmpp协议那个好_python网络爬虫之HTTP原理,爬虫的基本原理,Cookies和代理介绍...
  6. 计算机网络-RIP与OSPF
  7. 视觉SLAM笔记(65) 简约总结
  8. 虚拟机Ubuntu20.04.2LTS卸载python3.8出现tty1-tty6循环登录,无法进入图形化界面,乱码(亲测)
  9. 美团点评技术年货:900+页电子书,覆盖前端、后台、大数据、算法……(附下载链接)...
  10. 100个WordPress常用插件精选
  11. Hadoop2.7.3伪分布式集群搭建
  12. mysql 勒索病毒怎么恢复_敲诈者病毒解密恢复 勒索病毒数据库恢复 数据库中病毒解密恢复...
  13. K210车牌归属地识别[获取图像+训练+识别效果演示]
  14. 从普通物理到弦论教材推荐
  15. Fiddler抓取手机端APP接口数据
  16. 一个大型网站图片服务器架构的演进
  17. emoji 表情包全套手机端pc都支持
  18. Kong的插件:Request Size Limiting
  19. [UE4]传送门:场景切换
  20. linux命令和选项作用,linux tar 命令中 -f选项作用

热门文章

  1. mysql基本数据库操作
  2. 《深入理解Nginx》阅读与实践(四):简单的HTTP过滤模块
  3. linux网络相关常见问题
  4. Java poi插件导出Excel文件合并多sheet页
  5. gorm的零值问题:默认仅更新非零值
  6. kvm虚拟机端口映射(端口转发)到宿主机
  7. idea报错解决:Cannot start compilation: the output path is not specified for module “XXX“.
  8. Linkis计算中间件部署过程记录
  9. 【收藏】hdfs参数配置详解
  10. 关于linux分区与挂载的解释