J-Link/J-Flash
J-Flash批处理脚本配置烧录:当然,前提是要添加J-Link的可执行程序路径到$PATH
环境变量中
program.bat
脚本代码如下,参考修改即可:1
2
3echo start...
JLink -device N32L406CB -if swd -speed 4000 -CommanderScript "C:\Users\Breo\Desktop\Wireless moxibustion\Software\program.jlink"program.jlink
文件代码如下,其中目标设备、文件路径、烧录地址等根据需要配置:1
2
3
4
5
6
7
8
9
10
11
12
13connect
device N32L406CB
si SWD
speed 4000
h // halt-停止
r // 复位,可以考虑去掉
erase // 或 erase 0x8002800,去掉也行,但可能会出现error fail address 0x00000000错误提示
loadfile app.bin 0x8002800 // loadfile app.hex 或 loadfile app.bin 0x8000000
verifybin app.bin 0x8002800
r
go // r go表示reset and run
q // 退出J-Link命令行工具
Ubuntu 无法更新问题
Ubuntu 无法使用apt update
更改软件源
编辑 /etc/apt/sources.list
文件,将以下内容添加到文件末尾
deb https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
清除 apt 缓存
sudo apt clean
sudo apt autoclean
尝试更新系统
sudo apt update
显示 ModuleNotFoundError: No module named 'apt_pkg'
,重新安装 “apt_pkg
“ 模块:
sudo apt install --reinstall python3-apt
显示 ERROR:
E: Could not read response to hello message from hook [ ! -f /usr/bin/snap ] || /usr/bin/snap advise-snap --from-apt 2>/dev/null || true: Success
如果问题仍然存在,尝试修复 Python 包:
sudo apt install --fix-broken
然后就更新系统了:
sudo apt update
sudo apt upgrade
执行sudo apt upgrade
后显示ERROR:
Errors were encountered while processing:
/tmp/apt-dpkg-install-cQBLJW/626-linux-iot-tools-common_5.4.0-1030.31_all.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
最后一步,修复损坏的软件包配置:
sudo dpkg --configure -a
sudo apt upgrade
Breo蓝牙启动异常
Breo蓝牙初始化
蓝牙初始化没完成,透传未开启,app就连接蓝牙了。
设置透传参数,开启透传的的状态中增加连接蓝牙接受指令。
心跳包回复超时
现在是接收/刷新设备数据200ms超时,延迟太长还可以缩短。
SPI级联led灯调试小助手
产品名称:1209RGB幻彩雾状
产品型号:XTQ-016B.RGB-2307125-20
SPI级联led灯问题汇总
充电闪灯问题
问题分析
充电中拔掉电源,立即再次插入,会闪一下灯;若等两秒再插入则不会出现,初步判断是此款芯片有锁存功能,会保存到寄存器中,未完全掉电再次插入则会继续执行上次的寄存器数据。
解决方法
充电中拔掉电源,程序不要立即断电,持续两秒反初始化spi灯珠,即给spi寄存器写全灭数据。
呼吸灯闪烁问题
问题分析
程序中呼吸灯会跑偶尔闪烁,影响显示效果。分析发现,代码中有电机的FG检测,此检测开启了输入捕获功能,会持续中断触发,虽然spi灯的驱动是dma发送,但是也是由CPU来调度的,并不能与中断并行。spi呼吸灯效果需要持续发送数据,且时序要求很高,中断会抢占spi的dma发送,打断spi传输数据,导致数据传输出错,造成闪灯效果。
解决方法
1、提高芯片主频,n32l403KB最高主频为64MHz,如果主频提高效果会好一些。
2、spi呼吸灯效果持续发送数据,不能与中断频繁的代码一起使用。
某项目充电保护仍充电
修改代码:
1 | {-1, 1, PIN_CHARGE_CC_DETECT, PIN_MODE_INPUT}, //input/output switch |
Git小贴士
执行 git pull 会覆盖本地的修改吗?
没有冲突的情况下,远端会直接更新至本地上,但不会改变本地未提交的变动;如果本地修改已提交,则会执行一个远端分支和本地分支的合并
git fetch 和 git pull 的区别与联系
git fetch
用于从远程仓库获取最新的提交,保存到本地的远程跟踪分支中(FETCH_HEAD
),可以通过查看此分支了解远程仓库的更新情况
git diff FETCH_HEAD
比较查看该分支和当前工作分支的内容
git pull
会自动获取远程仓库的更新,并且合并到当前分支上,相当于git fetch
+ git merge FETCH_HEAD
- 将远程仓库中指定分支的最新提交 ID 保存到本地的
FETCH_HEAD
分支中 - 将
FETCH_HEAD
分支合并到当前工作分支中
基础非典型操作
本地git配置
配置本地与远端的SSH密钥连接流程:
- 本地生成SSH公钥和私钥(如果没有的话,另,linux下公钥通常存放于
~/.ssh/*.pub
)ssh-keygen -t rsa -b 4096 -C xxx@xxx.com
- 复制公钥,添加至远端平台的SSH设置上
查看本地配置:
git config --list
查看当前项目的所有配置git config --global --list
查看全局配置
修改用户名(全局/当前项目)
此用户名即提交日志上所展示的用户名称
- 修改全局用户名:
git config --global user.name "xxx"
,影响用户的所有仓库 - 修改当前路径项目的用户名:
git config user.name "xxx"
- 查看全局用户名:
git config user.name
初始化本地工程并与远端已有仓库的main分支关联:
- 进入工程根目录,
git init
初始化本地仓库 - 添加远程仓库:
git remote add origin <远程仓库地址>
git branch -M main
将当前分支重命名为main
,M即--move --force
的缩写。(可以分别输入git add --all
,git commit -m "first commit"
完成对本地分支的首次提交)- 使用
git pull origin main
,将远程仓库的main分支拉取到本地,或者git push -u origin main -f
将本地的xxx分支强制推送到远端main分支,其中-u是--set-upstream
的缩写,后续会保持这个跟踪关系
可变参数函数详解
C语言中的可变参数函数允许您定义函数,其参数个数是不确定的,可以根据具体需求接受可变数量的参数。这在处理不定数量参数的情况下非常有用,比如printf
和scanf
等函数。让我为您详细解释一下可变参数函数的原理和实现。
1. 原理与实现:
可变参数函数的参数列表是从右往左压入堆栈的。假设堆栈中有以下参数:不可变参数1、不可变参数2、…、不可变参数n、可变参数1、可变参数2、…、可变参数n。
为了获取可变参数,我们需要知道每个可变参数的地址。这是通过前一个不可变参数的地址和类型来实现的。
ANSI标准提供了三个宏来实现这个过程:
va_start(va_list arg_ptr, prev_param)
: 初始化可变参数列表,将arg_ptr指向第一个可变参数。va_arg(va_list arg_ptr, type)
: 获取当前参数的值,类型由前面的不可变参数传递。例如,printf中的格式化字符串或者可变参数列表的参数类型和第几个不可变参数的相同。va_end(va_list arg_ptr)
: 释放资源,结束可变参数列表的访问。
这些宏的实现细节由编译器和标准库提供,我们只需调用它们即可。
2. 可变参数函数:
- 可变参数函数允许在函数定义中接受不定数量的参数。
- C语言提供了
stdarg.h
头文件来支持可变参数函数的实现。 - 下面是一个示例代码,展示了如何实现一个可变参数函数 sum,它接受一个整数参数 count,表示接下来的可变参数的数量:
1 |
|
- 在这个示例中,我们定义了一个可变参数函数 sum,它计算传入的整数参数的总和。
3. 可变参数宏:
- 可变参数宏允许在宏调用中接受可变数量的参数。
- 在C语言中,可变参数宏使用
__VA_ARGS__
表示可变参数的部分。 - 下面是一个示例代码,展示了如何定义一个可变参数宏
PRINT_VALUES
,它使用 printf 函数来打印可变数量的值:
1 |
|
- 在这个示例中,我们定义了一个可变参数宏
PRINT_VALUES
,它使用printf
函数来打印多个值。
4. 实现自己的 printf 函数:
printf
函数接受一个格式字符串作为第一个参数,后面是可变数量的参数,用于替换格式字符串中的格式占位符。- 以下是一个简化版的示例代码,展示了一个实现类似于
printf
函数的功能的函数:
1 |
|
汇编基础
参考文档:汇编语言入门教程
实例分析
了解寄存器和内存模型以后,就可以来看汇编语言到底是什么了。下面是一个简单的程序example.c。
1 | int add_a_and_b(int a, int b) { |
gcc 将这个程序转成汇编语言。
1 | $ gcc -S example.c |
example.s经过简化以后,大概是下面的样子。
1 | _add_a_and_b: |
可以看到,原程序的两个函数add_a_and_b和main,对应两个标签_add_a_and_b和_main。每个标签里面是该函数所转成的 CPU 运行流程。
git合并小贴士
分支合并到main
以下是完整的命令流程:
1 | 确保你的分支是最新的 |
如果你希望使用 git rebase
保持提交历史整洁,可以参考以下流程:
1 | 确保你的分支是最新的 |
main合并到分支
使用 git merge
:
1 | 确保本地 main 分支是最新的 |
使用 git rebase
:
1 | 确保本地 main 分支是最新的 |