CLion嵌入式开发上手

CLion从2019.1开始正式加入了对嵌入式开发的支持,虽然仅仅是整合了之前已经有的OpenOCD和STM32CubeMX的插件,但也有很强的可玩性了。其实大概一年前这个特性刚出来的时候我就试过,因为某些原因不了了之,具体内容可以在我原来博客的存档里面找到。好久没有做嵌入式了,这次因为选修嵌入式课程开始重操旧业。

现在是2020年3月,我正在Windows 10上面使用CLion 2019.3.4,Toolbox检查已是最新版本。还是要说明,这篇文章不是什么教程,仅仅只是我个人尝试的经历,分享出来希望能和大家一起交流,如果有哪里不好烦请不吝赐教。底部有评论区,恳请大家留点经验意见。

表情包来自互联网,侵删。

准备工作

在开始之前,你需要准备一些东西:

一块开发板(废话)。等了几天快递,今天终于刚到手一块NUCLEO-F446RE。用什么板子应该是无所谓的,最多是后面选Board config file的时候没有,要自己写(其实大部分都没几句话,应该问题不大)。

表情包来自互联网,侵删。

有了开发板还要调试器,通常还要给调试器安装驱动程序,由于NUCLEO板载ST-LINK/V2,所以去到STSW-LINK009 – ST-LINK, ST-LINK/V2, ST-LINK/V2-1 USB driver signed for Windows7, Windows8, Windows10 – STMicroelectronics安装驱动程序。

事先安装好CLion(废话)。我推荐先安装JetBrains Toolbox,然后再通过Toolbox安装CLion,使用Toolbox来管理这些IDE会比较方便。当然,要是你真的从头到尾都只使用他家的CLion的话,直接安装CLion也没啥问题。

Toolbox长这样的,方便管理各个工具和最近的项目

Mingw-w64。我是使用MSYS2安装的,不用应该也可以(比如那些预构建包,在MinGW-w64 – for 32 and 64 bit Windows download | SourceForge.net)。

平时偶尔写写C/C++,所以事先基本包已经怼上了

这个环境是用来构建C/C++程序的,这里主要好像只是用到了make(就是那个mingw32-make.exe)。根据文档,你想使用MinGW应该也没有问题。另外,我之前用子系统Ubuntu(官方文档没说可以)的工具链好像构建总是会失败,忘记报错信息了,你可以试试然后来分享一下。

OpenOCD。不是很了解,不敢瞎BB。看到这篇好像不错?跟我一起学OpenOCD(一) – 知乎,有空再看看文档。根据官方文档,如果有MSYS2,那么安装比较简单:

pacman -S mingw-w64-x86_64-openocd

没有好像也没关系,Getting OpenOCD « Open On-Chip Debugger下面有非官方的预构建包可以下载,解压后即可使用。随后都需要在设置中指定其位置(找不到可以两下Shift来Search Everywhere,然后搜你想要的)。

Settings->Build, Execution, Deployment->Embedded Development
测试一下

STM32CubeMX。用来生成代码框架等,官网下载安装即可,如果是默认的安装路径的话CLion中应该能自动检测到。

STM32CubeMX

gcc-arm-none-eabi。最重要的工具,交叉编译用。虽然GitHub – msys2/MINGW-packages: Package scripts for MinGW-w64 targets to build under MSYS2.里面有PKGBUILD:

但是根据How to install mingw-w64-arm-none-eabi-gcc · Issue #4068 · msys2/MINGW-packages · GitHub,需要自行构建,pacman暂时没法直接装上。不过可以直接到ARM的官网上下载预编译好的工具链,链接找不到可以点上面的。CLion此时的文档仍然是写的支持2019-q3或者2018-q2及之前的版本。看了一下,2019-q3是GCC 8,2019-q4是GCC 9,估计是没测试完就没写支持吧,自己斟酌。而且印象中这个时候的CLion对于版本高于8的gdb仍然会给出不支持的警告(虽然还是能用)。

我下载的.zip包,解压到了MSYS2环境里(自己建了个3rd文件夹),放哪里应该都是无所谓的。然后要到设置中手动指定arm-none-eabi-gcc.exearm-none-eabi-g++.exearm-none-eabi-gdb.exe。(这个方法是我突然想到的,感觉应该有更好的?)

Settings->Build, Execution, Deployment->Toolchains

你会注意到,如果这个配置文件在队列里不是第一个的话,并不会显示default,也就是说平时并没有用这个配置。如果你平时在使用多个Toolchain于不同用途,你并不需要一直在这里切换,而是可以在这里为每个Project单独设置:

Settings->Build, Execution, Deployment->CMake

你会注意到上面有个地方可以设置环境变量,因为我没有在PATH中设置编译器位置时,后续建好Project的时候CMake还是会找不到,像这样:

Reload CMake Project

你可以写一个.cmake文件来设置,不过我在这里直接给这个Project设置环境变量(这样不会影响系统的):

Settings->Build, Execution, Deployment->CMake->Environment

此时应该就没有问题了:

开工吧!

准备了这么多东西,现在该来尝试一下了。你需要先打开CLion,然后新建一个Project,就像这样:

New Project

项目名字自己起一个,尽量别untitled一路下来(我真的见过一堆项目untitled一直到untitled200的)。

点击打开STM32CubeMX来配置

默认上来的型号通常不是你想要的,点击Open with STM32CubeMX来启动STM32CubeMX。你可以在这里点击型号来改变:

点按STM32F030F4Px
搜索你的开发板或是MCU等

这是文档里这么干的,感觉有点奇怪。这并不能直接改型号,而是新建了一个Project,我感觉还不如直接新建好,然后再用CLion打开呢…因为这是新建的,所以你需要到这里来设置好名称和工具链。你需要保证生成的代码的位置和刚刚你在CLion中新建的Project一样,不然就白折腾了半天。就像下面这样:

Project Manager

此时点按GENERATE CODE来生成代码,会提示是否覆盖CLion自动生成的那份.ioc文件。覆盖吧,反正没啥用。总之我感觉这么干有点多此一举。

生成正常的话,现在就可以回到CLion中了。此时右下角应该会有气泡窗口显示已经自动检测到了:

这次弹窗要我选择Board config file,由于这里有现成的,就直接用了:(没有的话,应该在OpenOCD目录下的scripts里面可以依葫芦画瓢一下)

Board Config File

由于我之前设置环境变量是单独为Project设置的,所以每次新建都需要设置,不然就会:

Reload CMake Project

同样地,像上面那样设置好环境变量就OK了。回来再点击一下上一个图里左上角这个Reload CMake Project图标,应该就没有问题了。

注意到右上角,要执行任务的配置还是没设置好,此时还不能Run:

右上角,Edit Configurations

很简单,点按Edit Configurations…来修复错误。注意到窗口下方的错误信息是:

Edit Configurations下方有错误信息

那么只要指定Target就好了:

指定Target

此时Run和Debug的图标应该就不是灰色的了。插上开发板,点按Run(此时的配置应该是那份OCD的而不是CMake的),顺利的话应该很快就会:

此时应该已经烧录成功了,你也可以尝试着写点小程序来测试一下。

只能Run还不够,Debug也很重要。打上断点,点按Debug图标来启动,应该没有问题的:

下方的Debug窗口应该会显示变量、堆栈等信息。不知道你会不会在Debug窗口的第一栏看到这个很好使的小工具:

划重点,点按后即可在当前现场执行你想要的语句,有点像脚本语言一样?总之很好使就对了。

如果你想查看引脚信息,需要导入.svd文件,根据SVD files on ARM website – Keil forum – Software Tools – Arm Community,你可以在MDK5 Software Packs里先下载pack,然后从里面拿到。

如果你之前就在使用Keil做嵌入式开发,那么你应该已经有了这个pack,直接去找就好了。导入后就可以正常查看了。

应该暂时就这么多吧。想到啥再补充。

引用:(文中已做超链接的就不再列出了)
CLion 2019.1 EAP: CLion for Embedded Development, Part III | CLion Blog
STM32CubeMX Projects – Help | CLion
CLion for embedded development | CLion Blog
CLion for Embedded Development Part II | CLion Blog
MSYS2 installation · msys2/msys2 Wiki · GitHub
How to cross compile with cmake + arm-none-eabi on windows? – Stack Overflow
[柴工带你学习LiteOS系列]之—Windows下的GCC环境搭建_云博客_云社区-华为云
使用CLion做嵌入式开发 | 王晓磊贴代码用的Blog

JetBrains Quest (March 9, 2020) Write-Up

这篇文章是事先写好的,等到解谜到期后(“You have until the 15th of March at 12:00 CET to finish all the quests.”,也就是北京时间当日19:00)才放出的。总之我觉得,在结束前就到处发题解,大概就只能是破坏解谜气氛和便宜了黑产吧。

48 61 76 65 20 79 6f 75 20 73 65 65 6e 20 74 68 65 20 73 6f 75 72 63 65 20 63 6f 64 65 20 6f 66 20 74 68 65 20 4a 65 74 42 72 61 69 6e 73 20 77 65 62 73 69 74 65 3f

比较明显的十六进制的特征

看着很像是16进制表示的内容,尝试着转为ASCII字符。改行写Kotlin了,以后看到脚本长得跟你平时看见的不一样不要觉得奇怪…

import java.util.*

fun main() {
    val string = "48 61 76 65 20 79 6f 75 20 73 65 65 6e 20 74 68 65 20 73 6f 75 72 63 65 20 63 6f 64 65 20 6f 66 20 74 68 65 20 4a 65 74 42 72 61 69 6e 73 20 77 65 62 73 69 74 65 3f"
    val scanner = Scanner(string)
    while (scanner.hasNextInt(16)) {
        print(scanner.nextInt(16).toChar())
    }
}
输出的结果

得到输出:Have you seen the source code of the JetBrains website?

应该是一个提示。去看看官网的源码。访问JetBrains: Developer Tools for Professionals and Teams,然后Ctrl+U查看源代码(或者直接在网址前面打上view-source:)。比较长,于是尝试Ctrl+F搜索quest,发现了一段注释:

官网源代码中的注释,给出了hint

画个重点:

JetBrains has a lot of products, but there is one that looks like a joke on our Products page, you should start there… (hint: use Chrome Incognito mode)

产品页中有一个看起来像是个玩笑?提示用Chrome的无痕浏览。

其实还有一个更重要的重点:

It’s dangerous to go alone take this key: Good luck! == Jrrg#oxfn$

有一个奇怪的key。

先跳转产品页,也就是All Developer Tools and Products by JetBrains。3月12日的时候,直接访问相比Chrome的无痕浏览模式访问,会多出一个:

哈哈哈哈哈…很难笑欸
复制一个玩,当纪念吧。

点开康康:

仍然是hint

要求计算500到5000范围内的质数的数量。这个时候可能很多人会默默开始写脚本了,然而我选择WolframAlpha:

直接得到有574个质数

所以应该访问https://jb.gg/574。有一说一,这个域名挺难听的…被跳转到了https://www.jetbrains.com/help/pycharm/getting-help.html#quest

PyCharm的文档页

有用过YouTrack,或者是曾经发现JetBrains家的IDE有问题的人应该会知道这个编号的含义的。不知道的话,看上面的图标应该也能猜到要去看看这个产品是啥。到YouTrack的官网搜这个事件编号就可以了,甚至粗暴地Google一下也可以。所以就是访问JetBrains Quest : MPS-31816

有一串密文

考虑到之前给出的hint:Good luck! == Jrrg#oxfn$。能发现两个o都对应了r,应该只是进行了替换而已。好了,开工:

fun main() {
    val string = "Qlfh\$#Li#|rx#duh#uhdglqj#wklv#|rx#pxvw#kdyh#zrunhg#rxw#krz#wr#ghfu|sw#lw1#Wklv#lv#rxu#lvvxh#wudfnhu#ghvljqhg#iru#djloh#whdpv1#Lw#lv#iuhh#iru#xs#wr#6#xvhuv#lq#Forxg#dqg#iru#43#xvhuv#lq#Vwdqgdorqh/#vr#li#|rx#zdqw#wr#jlyh#lw#d#jr#lq#|rxu#whdp#wkhq#zh#wrwdoo|#uhfrpphqg#lw1#|rx#kdyh#ilqlvkhg#wkh#iluvw#Txhvw/#qrz#lw“v#wlph#wr#uhghhp#|rxu#iluvw#sul}h1#Wkh#frgh#iru#wkh#iluvw#txhvw#lv#‟WkhGulyhWrGhyhors†1#Jr#wr#wkh#Txhvw#Sdjh#dqg#xvh#wkh#frgh#wr#fodlp#|rxu#sul}h1#kwwsv=22zzz1mhweudlqv1frp2surpr2txhvw2"
    val stringBuilder = StringBuilder()
    string.forEach {
        stringBuilder.append(when (it) {
            'J' -> 'G'
            'r' -> 'o'
            'g' -> 'd'
            '#' -> ' '
            'o' -> 'l'
            'x' -> 'u'
            'f' -> 'c'
            'n' -> 'k'
            '$' -> '!'
            else -> it
        })
    }
    print(stringBuilder.toString())
}

得到的输出是这样的:

仍然是乱码

继续观察一下,结合ASCII表就发现,密文只是相对于明文右移了3位而已。那么可以尝试还原了:

fun main() {
    val string = "Qlfh\$#Li#|rx#duh#uhdglqj#wklv#|rx#pxvw#kdyh#zrunhg#rxw#krz#wr#ghfu|sw#lw1#Wklv#lv#rxu#lvvxh#wudfnhu#ghvljqhg#iru#djloh#whdpv1#Lw#lv#iuhh#iru#xs#wr#6#xvhuv#lq#Forxg#dqg#iru#43#xvhuv#lq#Vwdqgdorqh/#vr#li#|rx#zdqw#wr#jlyh#lw#d#jr#lq#|rxu#whdp#wkhq#zh#wrwdoo|#uhfrpphqg#lw1#|rx#kdyh#ilqlvkhg#wkh#iluvw#Txhvw/#qrz#lw“v#wlph#wr#uhghhp#|rxu#iluvw#sul}h1#Wkh#frgh#iru#wkh#iluvw#txhvw#lv#‟WkhGulyhWrGhyhors†1#Jr#wr#wkh#Txhvw#Sdjh#dqg#xvh#wkh#frgh#wr#fodlp#|rxu#sul}h1#kwwsv=22zzz1mhweudlqv1frp2surpr2txhvw2"
    val stringBuilder = StringBuilder()
    string.forEach {
        stringBuilder.append(it - 3)
    }
    print(stringBuilder.toString())
}

这下直接得到结果了:Nice! If you are reading this you must have worked out how to decrypt it. This is our issue tracker designed for agile teams. It is free for up to 3 users in Cloud and for 10 users in Standalone, so if you want to give it a go in your team then we totally recommend it. you have finished the first Quest, now it’s time to redeem your first prize. The code for the first quest is “TheDriveToDevelop”. Go to the Quest Page and use the code to claim your prize. https://www.jetbrains.com/promo/quest/

也就是前往上面这个链接兑奖就可以了。

片刻即可收到邮件:

三个月全家桶,算是个小惊喜吧。

Windows 10下使用Windows+Shift+S截图

好消息,好消息!如果你正在使用较新的Windows 10,那么截图只要:Windows徽标键+Shift+S即可触发截图和草图应用来抓取矩形截图、任意形状截图、窗口截图或是全屏幕截图Windows徽标键+PrtSc即可触发截图和草图应用直接抓取全屏幕截图不用再为了截图打开微信或QQ啦。

截图和草图应用

如果你觉得这个快捷键比较难按,你可以在设置->轻松使用->键盘中修改:

修改热键为PrtScn

什么?你说我火星了?好像不是我,是我的朋友们…(无中生友ing)

好,来说说这个功能。根据此文章Why doesn’t the screen clipping tool work anymore? – OneNote所述,该热键本是OneNote用户用于截图的,自Windows 10创意者更新(也就是1703)后,由截图与草图应用接管。相关文章还包括:What’s New in Windows 10’s Creators UpdateHow to take and annotate screenshots on Windows 10

还要注意的是,根据Snip & Sketch…. : Windows10 – Reddit。截取屏幕后,你通常直接从剪贴板中取得图片,但是在:%LOCALAPPDATA%\Packages\Microsoft.Windows.ShellExperienceHost_cw5n1h2txyewy\TempState\ScreenClip路径下仍然保存有图片的副本(也就是C:\Users\%USERNAME%\AppData\Local\Packages\Microsoft.Windows.ShellExperienceHost_cw5n1h2txyewy\TempState\ScreenClip)。可能有隐私泄露风险,请务必注意。

Chrome 离线安装

推荐同学用Google Chrome作为日常的浏览器,但是他表示很难下载成功。为了省事,我决定直接弄个离线安装包给他。

直接搜索chrome offline installer,找到了官方文档:下載及安裝 Google Chrome – 電腦 – Google Chrome說明。文中说明了在离线状态下安装Chrome,需要在联网的主机上下载备用Chrome安装程序,就是我想要的离线安装包了。

只要打开上述链接再点击下载Chrome就可以得到离线安装包了。

仔细看了一下那个链接,其实本质上只是在Chrome的官方网址https://www.google.com/chrome/后面加上?standalone=1而已。即:https://www.google.com/chrome/?standalone=1

访问试一下,没有问题,有图有真相:

IDM抓取到的,看文件名和大小应该没有问题。

类似问题:Google Chrome 离线安装包的官方下载地址是什么? – 知乎

Foobar2000 简单上手

Foobar2000是一个强大的音乐播放器。好久没有拿出来用了,今天简单记录一下。

官网:foobar2000

Monkey’s Audio files (.APE)

下载安装就不用说了。印象中默认是不能直接播放ape格式的文件的,需要安装解码器(decoder)。可以在官网找到:foobar2000: Components Repository – Monkey’s Audio Decoder。正常情况下下载后直接双击这个插件就可以安装了。

双击后应该会弹出插件列表

双击后应该会弹出插件列表,点击Apply即可。

如果没有弹出插件列表,可能是插件的文件格式没有被关联上,这个时候只需要到插件列表里手动安装即可:

进入设置,设置里的第一个(Components)就是了
点击Install,并找到你刚下载好的插件就可以了

安装会要求重启Foobar2000,重启后就可以播放ape格式的文件了。

Free Encoder Pack

想要转换格式的时候发现,如果想要转换成flac等格式的文件,会发现缺少编码器,要求你提供flac.exe的位置。

同样地,要解决这个问题,可以在官网上找到一个整合了很多编码器的包:foobar2000: Free Encoder Pack,描述称:这个包内含多个用于转换的编码器文件。下载安装即可。

安装后再执行转换就不会要求你选择编码器了。

音乐库扫描内含*.cue的文件

默认音乐库只扫描个人文件夹下的音乐文件夹,可以在设置中自行设置。打开设置(Preferences,偏好项),点击媒体库(Media Library)即可自行修改目录。

Preferences->Media Library

注意到了Exclude项,它默认排除识别*.cue文件,这通常不是我们想要的,因为这样会使得那些完全依赖cue文件进行分轨的整轨音乐无法被识别为多个音乐文件。在某些时候可以考虑删除它,此时应该能正常识别了。

此外,Shell Integration中也默认排除*.cue文件,自行根据需要调整吧。

要指出的是,某些安全软件会阻止你修改这些选项,有点迷…

大概就先这样吧,想到什么再补。