使用 –debug 会发现卡在 Detect dns server first.
命令前加上 DOH_USE=3
前缀,使用阿里云的 DOH 服务器。
题外话,更新错误一半由 GFW 造成我也是服了。
使用 –debug 会发现卡在 Detect dns server first.
命令前加上 DOH_USE=3
前缀,使用阿里云的 DOH 服务器。
题外话,更新错误一半由 GFW 造成我也是服了。
本文所记录的是我整个过程的踩坑经历,关于项目和其使用说明请参考项目主页:hilookas/SeekFree_RT1064_RTThread_Library_GCC_Porting | GitHub
关于逐飞 RT1064 库的移植项目请参考其项目主页:hilookas/SeekFree_RT1064_Library_GCC_Porting | GitHub
更多内容请参见另一篇博文: 逐飞 RT1064 库 GCC (VSCode) 移植踩坑 | lookas
这些文件本来就是 UTF-8:
./Libraries/rttherad_libraries/examples/*
./Libraries/rttherad_libraries/components/drivers/can/readme-zh.txt
使用命令 diff --brief --recursive dira dirb
nxp_libraries:
Libraries/nxp_libraries/drives/fsl_lpuart.c
Libraries/nxp_libraries/middleware/sdmmc/port/fsl_sdmmc_event.h
Libraries/nxp_libraries/middleware/sdmmc/port/usdhc/interrupt/fsl_sdmmc_event.c
seekfree_libraries:
Libraries/seekfree_libraries/board/board.c
Libraries/seekfree_libraries/board/board.h
Libraries/seekfree_libraries/common/common.c
Libraries/seekfree_libraries/common/common.h
Libraries/seekfree_libraries/headfile.h
Libraries/seekfree_libraries/zf_systick.c
Libraries/seekfree_libraries/zf_systick.h
seekfree_peripheral:
Libraries/seekfree_peripheral/SEEKFREE_IPS200_PARALLEL8.h
Libraries/seekfree_peripheral/SEEKFREE_MT9V03X.c
Libraries/seekfree_peripheral/SEEKFREE_MT9V03X_CSI.c
RT-Thread 要求通过设置 -eentry
到编译参数,使 main
函数运行前,先运行 entry
函数以初始化 RT-Thread。(Libraries/rttherad_libraries/src/components.c:157
objdump -d
可反汇编)
如果在 startup_MIMXRT1064.s
中使用 GCC 自带的 _start
(来自 GCC 自带的 crt0.o
),_start
在初始化 c 运行环境之后,会直接进入 main
函数,不会经过 entry
函数。故需要在启动文件中,手动初始化 c 运行环境(初始化 bss 段,调用 __libc_init_array
函数),并跳入 entry
函数。
ref:
context_gcc.S
中的编译错误在 Libraries/rttherad_libraries/libcpu/arm/cortex-m7/context_gcc.S
中有错误:
Error: thumb conditional instruction should be in IT block -- `vstmdbeq r1!,{d8-d15}'
解决方案:在 flags.cmake
增加 -mimplicit-it=thumb
flag
ref:
C 标准库里和 RT-Thread 库中有重复定义,需要配置 RT-Thread 以让出符号。
解决方案:添加了 Libraries/rttherad_libraries/bsp/cconfig.h
文件(来自 Github),添加到了 files.cmake
中的头文件搜索目录,在 flags.cmake
中添加了 HAVE_CCONFIG_H
flag
ref:
增加了 .rti_fn
(用于 RT-Thread 自动初始化) .FSymTab
.VSymTab
(用于 FinSH)段的配置。
在 .heap
(底)和 .stack
(顶)间配置了 heap_start
heap_end
作为 RT-Thread 的堆内存(用于分配线程栈等)。
ref:
如默认项目里的 rt_thread_mdelay(100);
,在 100ms 后 LED 并没有切换状态。
发现是由于 Libraries/nxp_libraries/middleware/sdmmc/port/usdhc/polling/fsl_sdmmc_event.c
里的 SysTick_Handler
覆盖掉了 Libraries/seekfree_libraries/board/board.c
文件中的 SysTick_Handler
,其中 board.c
负责配置 SysTick 并且在 SysTick 定时结束时调用 RT-Thread 继续线程(初始化板子)。
解决方案:在 files.cmake
里注释掉 Libraries/nxp_libraries/middleware/sdmmc/port/usdhc/polling/fsl_sdmmc_event.c
(该错误解决后我根据 IAR 的配置继续注释掉了其他不需要的文件)
Tips:修改 Libraries/rttherad_libraries/include/rtdebug.h
可以开启内核功能调试输出
ref:
Summary: 该文介绍了在 MacOS 下,使用 GCC 工具链在 VSCode 中利用 Cortex Debug 插件编译调试逐飞 RT1064 库的踩坑过程。(Linux 下类似,但是具体步骤本文并没有写)
本文所记录的是我整个过程的踩坑经历,关于项目和其使用说明请参考项目主页:hilookas/SeekFree_RT1064_Library_GCC_Porting | GitHub
关于逐飞 RT1064 RT-Thread 库的移植项目请参考其项目主页:hilookas/SeekFree_RT1064_RTThread_Library_GCC_Porting | GitHub
从山外 K60 库开始,我开始了我的漫漫智能车之路。山外库只支持 IAR,但是可惜 IAR 并不支持 MacOS/Linux,逐飞 RT1064 库增加了对 Keil 的支持,但是 Keil 仍然只支持 Windows。我不甘心与在 Mac 上与嵌入式无缘,同时好在开源工具链 GCC 支持(几乎)所有平台,故有了这篇折腾文章。
现在的微控制单元(单片机)一般会有两个文档,一个是 Data Sheet ,负责介绍芯片电气相关的参数,另一个是 Reference Manual ,负责介绍硬件上一些功能如何使用,寄存器布局等。
初次之外厂商提供一些 Application Note,用于介绍特定的功能是如何使用,这个文档一般比较口语化,而且部分还提供中文翻译,推荐要实现一个功能的时候可以优先参考。
NXP 提供 SDK ,SDK 提供了许多样例供参考,和一些芯片的基础库,将寄存器封装起来,避免用户自己直接操作寄存器(太头疼)。
CMSIS 是一个 ARM 的标准,用于标准化来自不同厂商的 ARM 芯片差异。将芯片的 ARM 内核相关的寄存器封装起来。
CMSIS 还提供 CMSIS Pack,其中包含了不同厂商自己外设的驱动程序。
NXP 的 SDK 包含了 NXP 的 CMSIS Pack (SDK 的 SDK_2.9.1_MIMXRT1064xxxxA/devices/MIMXRT1064
里的内容其实就是 NXP 的 CMSIS Pack 的)
ref:
IMXRT1064RM.pdf
from NXPGetting Started with MCUXpresso SDK for EVK-MIMXRT1064.pdf
from NXP SDK SDK_2.9.1_MIMXRT1064xxxxA/docs/
RT1064 芯片有内嵌的 BootROM (直接刻在芯片上的那种),其会根据启动引脚和内部保险丝的情况决定从哪个位置启动。同时 RT1064 芯片内部有一颗使用 FlexSPI2 的 Flash (即 RT1064 的 4 意义所在),没有特殊配置,芯片会从这个 Flash 启动。
BootROM 会从 Flash 的 IVT(Image Vector Table) 读取 BootROM 配置信息(如 PC 指针的值,和配置 SEMC SDRAM 的“脚本”)
ref:
i.mx6 linux启动流程分析.pdf
介绍了一下 i.MX6 带操作系统启动流程。其与 RT1064 类似,区别在于 RT1064 没有 MMU ,无法运行操作系统。寄存器有两种,一种是处理器寄存器,ARM 核心使用,一种是外设寄存器,用于控制芯片中的外设的(如 UART)。后者被映射到处理器的内存空间中,可以被寻址,具体地址参见芯片手册。
ref:
逐飞的库文件编码是乱的,强迫症的我不能对此坐视不管。库里的绝大多数文件是使用 GB2312 编码,但是有两个文件是同时使用了 UTF-8 和 GB2312 编码,更加神奇的是,还有三个文件中参加了几个中文符号!这导致 iconv 的转换编码进程被卡住。这主要涉及到以下几个文件:
UTF-8 和 GB2312 编码混在一起:
Libraries/seekfree_libraries/common/SEEKFREE_PRINTF.c
Libraries/seekfree_libraries/common/SEEKFREE_PRINTF.h
混有中文标点符号:
Libraries/nxp_libraries/middleware/usb/host/class/usb_host_cdc.c
Libraries/nxp_libraries/drives/fsl_semc.h
Libraries/nxp_libraries/utilities/debug_console/fsl_debug_console_conf.h
本来就是用 UTF-8 编码的:
./Project/RT1064智能车推荐引脚分配.txt
./Project/CODE/本文件夹作用.txt
为了加快修改所有源代码文件编码为 UTF-8 的进程,我简单的写了一个脚本,供各位参考:
#!/bin/bash
# Convert GB2312 to UTF-8 (MacOS) and CRLF to LF
# from https://docs.moodle.org/310/en/Converting_files_to_UTF-8
# from https://gist.github.com/jappy/2012320
# change * to *.c to specify only code files
# for x; do
# 涉及到 *.c *.h *.s *.S *.txt
find . -type f -name "*" | while read x; do
iconv -f GB2312 -t UTF-8 < "$x" | tr -d '\015' > "$x.tmp"
mv "$x.tmp" "$x"
done
Libraries/nxp_libraries/deceive
目录名错了,是 device
IAR 和 Keil 的配置也做了相应的调整
逐飞库里并不是所有的文件都需要编译的,有些文件加入编译后会导致编译不通过(如引用的头文件不存在),甚至导致运行时错误(错误覆盖了某些函数),具体可以参见 files.cmake
(根据 IAR program/RT106X.ewp
配置文件进行了注释)
但是,相对于 IAR 的配置,有些文件是仍旧需要的,否则会导致编译不过(引用的头文件不存在)。以下头文件是需要的:
Libraries/nxp_libraries/xip/
Libraries/nxp_libraries/CMSIS/Include/
Libraries/nxp_libraries/CMSIS/Driver/Include/
ref:
链接文件负责将代码合适的摆放在芯片所需要的位置上(如下文提到的 IVT 必须放到指定位置上,芯片才能正常启动)
MIMXRT1064xxxxx_seekfree.ld
文件修改自 NXP SDK 的 SDK_2.9.1_MIMXRT1064xxxxA/devices/MIMXRT1064/gcc/MIMXRT1064xxxxx_flexspi_nor.ld
逐飞核心板所需要的内存布局可以参考 IAR 的链接文件 Project/IAR/icf/MIMXRT1064xxxxx_flexspi_nor.icf
和逐飞的 Libraries/doc/read me.txt
说明文档。
ref:
一段代码的加载地址并不一定与运行地址相同,比如,在程序运行前,先从 ROM 里加载代码到 RAM 中,再在 RAM 中执行代码,速度会比直接从 ROM 中执行快很多。GCC Linker 默认情况下,加载地址为运行地址,但是其也支持自行使用 AT 执行指定加载地址。
ref:
加载地址设置这里有坑,设置了 AT 之后的代码好像并不会自动与前面的代码错开放置,需要自行计算排好。
Linker output.map 是一个很好的调试工具
ref:
主要涉及到芯片上电启动后 Reset_Handler
和,在其中运行的 SystemInit
。
需要配置 DTCM 和 ITCM 的内存分配,以及复制全局变量等到对应的位置。
Libraries/nxp_libraries/startup/GCC-ARM/startup_MIMXRT1064.s
文件修改自 NXP SDK 的 SDK_2.9.1_MIMXRT1064xxxxA/devices/MIMXRT1064/gcc/startup_MIMXRT1064.S
同时还修改了 Libraries/nxp_libraries/device/system_MIMXRT1064.c
和 Libraries/seekfree_libraries/common/common.h
(代码放置位置的快捷宏)
ref:
使用 i.MX RT FlexRAM ITCM DTCM 的大小配置是在 Reset_Handler 中进行
ARM assembly: bad instruction "mov32" – Stack Overflow gcc asm 并不支持 mov32 这个伪指令
gcc – How to get value of variable defined in ld linker script from C – Stack Overflow
ARM汇编语言入门 – 知乎 寄存器相关
NXP-MCUBootUtility/README-zh.md at master · JayHeng/NXP-MCUBootUtility
IAR 提供了 __iar_program_start
函数,拷贝在 icf 链接文件中定义的需要拷贝的数据。GCC 提供的相同地位的函数 _start
好像不帮我拷贝那些 LMA 与 VMA 不同的块。
解决方案:在 startup_MIMXRT1064
手动把变量初始化了。
ref:
NXP SDK 提供的样例是是使用 CMake 编译的,逐飞的核心板由于其外置 RAM ,需要手动开启一些编译 Flag,具体可以参见 flags.cmake
和 Libraries/doc/read me.txt
。
CMakeLists.txt
,*.cmake
和 *.sh
修改自 NXP SDK 的 SDK_2.9.1_MIMXRT1064xxxxA/boards/evkmimxrt1064/demo_apps/led_blinky/armgcc
下相关文件。
ref:
在使用 Cortex Debug 之前,我有尝试直接使用 GDB (通过 JLinkGDBServer)一段时间,但是 GDB 直接使用好像不是特别好使,continue
monitor halt
很烦,并且使用 GDB 的自带寄存器显示功能 info registers
的显示好像是错的。Cortex Debug 用完后,感觉还不错,就没有再继续研究 GDB 了。
ref:
现象是使用 Cortex Debug 插件启动芯片后,程序会第一次死在 Libraries/nxp_libraries/device/system_MIMXRT1064.c
的复制向量表(到外置 RAM)过程中,进入 HardFault 中断,使用 JMem 查看后发现对应位置(0x80000000 外置 RAM)没有数据(显示为 -
)。在 Reset_Handler 中设置断点的情况下,芯片自动重启后会恢复正常(进入到 main 函数)。
芯片自带的 BootROM 负责根据内置 Flash 上的 IVT 区域的 DCD(Device Configuration Data) 配置信息配置 SEMC 与外置 RAM 的通信。猜测 JLink 启动芯片的时候并不会运行芯片自带的 BootROM ,故需要 JLinkScript 在每次启动芯片的时候,手动配置一下外置 RAM 相关的数据。
使用从 NXP SDK 中提取到的 evkmimxrt1064_sdram_init.jlinkscript (来自 SDK_2.9.1_MIMXRT1064xxxxA/boards/evkmimxrt1064/sdmmc_examples/sdcard_interrupt/evkmimxrt1064_sdram_init.jlinkscript
),附加到 Cortex Debug JLink 启动选项(文件 launch.json
)后,可以正常调试运行了。
ref:
CMSIS-DAP 可以用 pyOCD 与其通讯。在 MacOS 下,运行 pyOCD 与 CMSIS-DAP 通讯是“免驱”的。OpenOCD 好像也可以与它通讯,但是没有继续尝试…另外根据 Cortex Debug 的文档,Homebrew 的 OpenOCD 版本比较老,推荐使用编译方式安装或者直接从官网下载
ref:
DAPLink使用说明 V1.2.pdf
from 逐飞 DAP 下载器使用说明.zip
复制 RT1064 的 SVD 文件即可
MIMXRT1064.xml
即 SVD 文件来自 NXP SDK 的 SDK_2.9.1_MIMXRT1064xxxxA/devices/MIMXRT1064/MIMXRT1064.xml
,也是 NXP CMSIS-Pack 的 NXP.MIMXRT1064_DFP.13.0.0.pack/MIMXRT1064.xml
ref:
rt,经过测试发现,如果没有调用初始化函数,Cortex Debug 反汇编根本无法找到中断处理函数,只有在初始化后才能找到。故认为是如果没有调用初始化函数,编译器自动优化掉了处理函数。
在使用断点功能的时候需要注意并不是所有位置打了断点都能生效的。
ref:
DIO CLK GND 是必须连接的,VCC 可以连接(这四根引脚即为核心板调试引脚最靠近 Type-C 口的那四个),RST 实测不连也可以 Reset (该功能不依赖该引脚)
如果有转换板的话,板子上其实有一个四线的口,用那个口即可
核心板上调试口的串口(标注 TX RX 字样),默认是要连到 UART1_TX_B12 UART1_RX_B13 两个脚上,但是实际上空了两个 0R 电阻位作为跳线。如果需要使用调试口上的串口,需要手动用一坨锡或者电阻连上。或者在主板上引出这两个口
Tips:修改 Project/USER/inc/RT106X_config.h
可以配置默认串口。
Tips:使用 screen /dev/tty.xxx 115200
可以连接到串口
ref:
TL;DR: 如果硬盘快满了,删除硬盘上的一些文件,使其有一定空余空间
最近电脑风扇狂转,发现 Chrome CPU 占用率非常高,使用 Chrome 内任务管理器发现“浏览器”一项占用很高。
经过一次浏览器重置后,占用率有所下降,但是使用一段时间后,占用率又保持非常高的状态,尤其是在看视频的时候,这现象更为严重。
使用 Safari 后,有所缓解,但是由于缺少许多插件,使用起来比较难受,故又换回 Chrome。
经过一些搜索,删除硬盘上一些文件,让硬盘有一定空闲空间后,占用率下降了许多,问题解决。
最近在折腾锐角云…
看到商家的介绍,8g 内存 64g 存储只要 200 多?!赶紧剁手下单,结果到手后才发现,内存和存储都是焊接到主板上的…不禁感叹,买的还是没有卖的精啊。
这个设备原装是两个存储设备,一个板载 64G 的 eMMC 另外一个是采用 mSATA 口的 SSD ,到手的时候这台机器只剩下板载的存储了,那个 SSD 已经不翼而飞了,为这设备再添购一个 SSD 实在是不划算,同时为了最大化利用这个硬件,我在这台设备上折腾了一下,尝试使用 PVE,结果安装的过程中提示 unable to get device for partition 1 on device /dev/mmcblk1
经过一天的尝试,通过以下方式可以绕开官方的限制,在 eMMC 上安装 Proxmox VE 6.3:
⚠️警告:PVE 并未针对这种设备优化,eMMC 也并非针对这种使用设计。PVE 每天要往存储设备中写入一定量的日志信息,USE AT YOUR OWN RISK!
Install Proxmox VE (Debug mode)
Ctrl-D
,继续安装过程vi /usr/bin/proxinstall
编辑文件(或者使用其他文字编辑器如 nano)/unable to get device
定位到对应位置...
} elsif ($dev =~ m|^/dev/[^/]+/hd[a-z]$|) {
return "${dev}$partnum";
} elsif ($dev =~ m|^/dev/nvme\d+n\d+$|) {
return "${dev}p$partnum";
} else {
die "unable to get device for partition $partnum on device $dev\n";
}
...
将其修改(添加)为:...
} elsif ($dev =~ m|^/dev/[^/]+/hd[a-z]$|) {
return "${dev}$partnum";
} elsif ($dev =~ m|^/dev/nvme\d+n\d+$|) {
return "${dev}p$partnum";
} elsif ($dev =~ m|^/dev/mmcblk\d+$|) {
return "${dev}p$partnum";
} else {
die "unable to get device for partition $partnum on device $dev\n";
}
...
Ctrl-D
,继续安装过程/dev/mmcblk1
(没有 bootX
后缀)(建议关闭 swap)Ctrl-D
,重启系统另外,也可以使用官方提供的方式,先安装 Debian 再安装 PVE,只不过那样安装很慢,而且网卡和分区并没有提前配置好,需要自己手动配置。具体参见:Install Proxmox VE on Debian Buster – Proxmox VE
网上还有使用 bin 等类似 ghost 的方法直接 dd 进 eMMC,或者先安装到另外一个硬盘上再使用 DiskGenius 乾坤大挪移到 eMMC 等方法在此不再做过多叙述,可以参见下方文章:
Install Proxmox VE (Debug mode)
提供了在安装过程中各个阶段执行脚本的能力。
修改的文件是为安装程序提供 MMC 设备检测支持。
没有直接修改 ISO 主要是由于,一是该文件在 pve-installer.squashfs 中,由安装程序在运行的时候加载,修改需要解包后重新打包,二是这样更透明,避免使用一个来源不是很明确的二进制文件。
安装过程中,配置信息那里使用了 Linux 的图形界面,类似于 Ubuntu 的使用,按下 Ctrl+Alt+F1/F2
为相应的日志信息,按下 Ctrl+Alt+F3
可以切换出命令行,按下 Ctrl+Alt+F4
可以切换回图形界面。
人,讨厌的不是强权,而是自己没有得到强权。
高考成绩下来了,与我而言可能并不能去自己非常想去的学校,于是抱怨社会,为什么大家都认同985/211,而不认同双非?
其实说自己在翻找去年的学校录取分数表时,尝试“捡漏”,这何尝不是一种歧视呢?
拿着重点学校的名字,哈,我多么强大,去看不起对方的时候,有曾想过自己也会成为“被看不起的”那一方呢?
所以啊,人,要学会遇到强者,能安然面对,面对弱者,能保持敬畏之心。
这也算是这次高考给我带来的一个深刻的教训吧。
人文社科类学科其实是蛮重要的,不仅仅体现在成绩,而且体现在人的文化修养上。
每次想到一些头疼的事情,总是想,如果多读一点书,是不是现在心态就会稍微好一点呢?
之前在接触到多播这个概念的时候一直在想这么美好的东西为什么不在互联网上使用,后来想了想,现在一直在说的 CDN 不就是做到这一点了嘛,减少骨干网络上重复数据的传输,在近用户端复制成多份分发。
今天看到腾讯云的这个演讲,同时也印证了这个观点:腾讯云PCDN:从P2P到万物互联框架
另外,P2P真的是一个很有趣的东西,与人斗,其乐无穷~
永远不要对他人的不幸落井下石,因为你无法确保你自己不会遇到类似情况。
Web 本质就是一个传递信息的工具,Web 有着用于传递信息的方法 HTTP,Web 有着用于表示信息的方法 HTML,那 Web 2.0 到底特殊在哪里?
我的理解, Web 2.0 将如何传递信息以及如何表达信息与用户的使用做了隔离,也就是说,在Web 2.0 时代,用户没有必要去考虑如何做出一个美观的网页,如何将自己的信息一直放在网上,如何用flash嵌入自己的视频作品,他只需要去做的是写一段文字,或者上传一些视频,其余的内容由计算机城区去帮忙处理。
Web 2.0 使得互联网的分工进行了细化,界面的美观设计有专业的设计师去处理,信息的保存有专门的运维去处理,解决各种疑难问题有程序员去做等等。
Web 2.0 其实就是应用程序这个概念的互联网延伸。
Web 2.0 的特性导致为了完成上述事宜,以及某些决策人员恬不知耻的产品“护城墙”战略,导致了互联网的中心化,从互联网变成了互联树,让用户的信息成为了一些公司的摇钱树,以及让控制信息的传播成为了[censered]。
将程序与数据分开吧!去掉那些本来就没有必要存在的中心化节点吧!还网络一个自由、开放的世界吧!
#拥抱IPFS ~~hashtag…~~