先贴链接: https://ankiweb.net/shared/info/351967078
只有n5-n2,因为打算考N2,N1暂时没有哈.
先贴链接: https://ankiweb.net/shared/info/351967078
只有n5-n2,因为打算考N2,N1暂时没有哈.
前段时间出了几个坑人的bug(都不是我的)需要做Coverity检查,对同事引入的指摘进行修正.因为同事没有用VCS找出修改点变成了活生生的体力活.
正好今天想研究下Antlr,顺便做了个工具(golang),生成函数签名和函数体hash列表,这样不同版本的code就可以比较差分了.(即使函数位于不同文件,或注释不一致)
https://github.com/feilongfl/CCodeHash
代码十分少,只有几行,算是Antlr入门作了,利用FunctionDefinition定义对函数体进行分析,获得函数签名和实体,并对整个函数进行hash计算生成hash.
第一个是原文件,第二个只修改了注释,第三个对函数代码进行了修改.
配合Shell,以后再有这种坑人事也有对策了.
对于#if还没做考虑
最近研究了一下廉价CAN分析设备的原理,顺便明白了和CAN-OE设备的差距真的是天上地下.不过存在着不少优点还是可以学习的.下面是商品链接:
https://www.can232.com/
从名字上就可以看出这是一个串口到can数据包的转换工具,但是搜索很久都没找到通信协议,插在电脑上也不会主动发送消息,正在我百思不得其解的时候,发现了Linux内核里面有个叫做slcan
的驱动模块,里面写着CAN232设备的网址.于是先调查下slcan是个什么东西.
全名 serial line CAN interface driver ,正好是CAN232设备的支持模块,需要配合slcand
来使用(位于can=utils程序中).
初始化slcan很简单,正常初始化即可,但是如果我们把CAN232换成普通串口进行抓包,也是可以初始化的o.o
因此在打开设备时候可以捕获到下面数据(结尾均为0x0d,即’\r’):
C
S6
F
O
根据slcand的代码,可以判断相应字母(区分大小写)的意思,每个命令0x0d结尾
C -> 关闭 S6 -> 速度500k (参考: https://elinux.org/Bringing_CAN_interface_up#SLCAN_based_Interfaces) F -> 获取状态 O -> 打开设备 // 下面这些也是代码中描述的协议 L -> 只听模式 s -> 设置波特率 //数据报文(大写代表扩展帧,小写代表数据帧) t 数据帧 r 远程帧 //回复结尾 0x0d 正常 异常(我忘了o.o,回头再试一下) z 发送成功
因此,随便一个串口只要按照上面格式发送数据就可以被linux转换为CAN消息.当然这样的协议存在明显的缺点,即抗干扰能力差(不过CAN232采用了FTDI的串口芯片,一般实验室情况下稳定性足够了).
最后补上一张串口助手模拟的CAN.
这个串口模块非常古老,因此不支持CAN-FD的协议,但是内核驱动写的很清晰易懂,配合虚拟串口回环和cangen
工具,制作了一个支持CAN-FD的驱动https://github.com/feilongfl/slcanfd.
首先模块名字改成了slcanfd,编译安装并手动加载即可使用slcand进行启动.(注意卸载slcan模块,否则会冲突)
后续可以考虑修改下slcand工具,增加下数据速度设置.在stm32G431上配合usb cdc跟fdcan做个usbcanfd(淘宝好像也有现成的,不过我想玩玩画板子,4层板都快成白菜价了)
发送接收展示:
顺便wakatime也挺好玩的,能看到调查这堆东西花了多少时间:
对于单片机来讲,串口通信是比较方便的接口了,打印log什么的不需要自己写上位机,网上串口助手一大把,随便找个就行,比较适合嵌入式项目的前期调试使用。
但是,随着嵌入式芯片的速度不断提高,产生的log越来越多,串口也需要比较高的速度,前段时间给mcu的串口终端通信压力测试时候,用国产山寨pl2303
把速度设到921600
才能给mcu一点压力。
并且新的项目需要更加快速的log速度,于是我开始寻找更加快速的串口。首先想到的是以前玩px4
时候用的ft232
高贵的三十多块钱的串口,速度好像3m左右来着,当年也没什么特殊需求,也没在速度这边做研究。于是打开FTDI的官网,发现最大速度12m,而且还有更加高贵的版本,70多块的ft4232
,相当于4个ft232
的版本。更加新一代的产品ft4233
在当前(2020/5/1)还没有发售,比ft232
支持了typec的pd功能(其实这个更符合我的需求,奈何淘宝没有,之后联络供应商可能会有其他回答)
清晰可见电容扭曲,因为我焊接引脚时候焊锡落在在电容上,两个电容是我后焊上去的,折腾了好久。如果不是测试用,强烈不建议
购买这种,做工很差,pcb特别薄,而且明显的拼版,掰开后没打磨,在从usb拔出时候极易割伤手指(我已经被割伤了)。四周尖角,扎人。非要买的话,建议一起买个锉刀,打磨下。
2. 驱动的话,windows 10
和manjaro linux
基本都能自己驱动,不用折腾,连接在PC上4个COM口,linux的话lsusb
出现一个设备,/dev/ttyUSB
出现4个,在我这边测试都是从小到大对应ABCD,没有出现反人类情况。
3. 新的FTDI芯片可以通过FT PROG
对eeprom进行配置。这个软件只能windows
运行。
这个软件在点击扫描时候有可能闪退(比如我这),通过上面命令行执行SCAN
命令,可以看到错误
对这个错误进行搜索,可以查询到这是一个已知的问题,https://www.ftdicommunity.com/index.php?topic=39.0
简单来说就是和我的鼠标冲突(因为我键盘使用ps2接口,不使用USB HID协议),于是拔下鼠标,按F5
然后再把鼠标插上就可以正常工作了,这里根据需要设置即可,不过感觉设置没什么作用,可能是因为我还没有测试D2XX
接口。
4 通过串口助手进行发送测试,波特率直接测试12000000
,通信没什么问题,回环和逻辑分析仪都没什么问题,但是循环发送速度特别慢,约几kb/s,让人难以接受,在网络上搜索没什么有效的结果,于是上逻辑分析仪进行测试。
可以看到每次传输都是比较快的,但是在中间等待了很长时间才进行下一次传输,于是猜测串口助手影响,使用golang写(抄)了如下测试代码。
package main
import (
"flag"
"github.com/tarm/goserial"
"github.com/larspensjo/config"
"os"
"log"
)
var (
conFile = flag.String("configfile","/config.ini","config file")
)
var TOPIC = make(map[string]string)
func main() {
file, _ := os.Getwd()
cfg, err := config.ReadDefault(file + *conFile)
id, err := cfg.String("COM","COMID")
baud, err := cfg.Int("COM","BAUD")
c := &serial.Config{Name: id, Baud: baud}
s, err := serial.OpenPort(c)
if err != nil {
log.Fatal(err)
}
data := []byte("0")
for i:=0; i< 1000000; i++ {
_, err := s.Write(data)
if err != nil {
log.Fatal(err)
}
}
}
[COM] COMID=COM17 BAUD=12000000
依旧间隔很久,肉眼可见的等待时间,怀疑驱动层或者goserial
或者windows系统对串口处理有问题(linux尚未测试,c语言串口也需要测试一下),于是对每次传输字节数量进行增加,得到下面波形,可见大数据是可以高速通信的。
接收的话12m的波特率没什么问题,可以正常看到数据,没发现丢包情况,不过看串口助手cpu占用率挺高,快占满一个核心了,估计自制串口通讯工具时候也需要注意这一点,把串口接收单独一个线程,防止丢数据。
这方面应该跟板载电容大小有关,但是作为淘宝货,应该也是直接抄的公版电路,所以对启动电平的测量也能在一定程度上说明一定问题,对今后串口下载电路的实现可以起到一定的借鉴作用.因为这个板子没有usb的电压接口,只能采取测量ldo的3v3输出.
可以看到上电初期时序,做下载电路的话,dtr时间最长.适合作为rst使用.大约40us左右,rts可以作为类似与stm32的boot0一样的存在,用于选择引导位置.
最近开始研究了一下stm32cube,发现挺好用的,就是bug太多,经常生成的工程不能编译.
我一般选择生成makefile
,这样对自动集成比较友好.方便后续迭代.
没有硬件,电路在不断改设计(这个是我随便画得,不一定能运行,没看手册),暂定这么分配管脚.这次主要是测试编译和接口,为以后开发踩下坑
芯片支持usbfs和fdcan,可以做个canfd数据分析,省下周立功两千多大洋(感觉周立功的东西去个0差不多),vector这种级别的比不了还是买吧.
而且支持双向USBPD,可以做快充,或者大功率耗电.看了下st的pd视频,估计未来的st芯片系列都会带有这个模块.
ucpd
必须要手动开启中断和DMA,增加USBPD
中间件并不会自动配置.这坑就大了…
Makefile上
IDrivers/CMSIS/Include
这里多一行,生成工程经常遇到,老错误了LIBS = -lc -lm -lnosys \
-lUSBPDCORE_PD3_FULL_CM4_wc32.a
LIBDIR = \
-LMiddlewares/ST/STM32_USBPD_Library/Core/lib
把链接文件当库用了…应当是下面这样:
LIBS = -lc -lm -lnosys \
Middlewares/ST/STM32_USBPD_Library/Core/lib/USBPDCORE_PD3_FULL_CM4_wc32.a
LIBDIR =
3. 修改下面编译阶段,加入ccache可以加快编译,毕竟整个库几乎不用改.不然每次修改makefile都会全部重新构建.
4. cube配置后可能有重复的文件加进去,导致一堆符号重复,删除重复即可
经过上面反复折腾,如果你在cube配置时选择双向(dual
)PD你会看到下面错误:
/usr/bin/ccache arm-none-eabi-gcc -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -DUSE_FULL_LL_DRIVER -DUSBPD_PORT_COUNT=1 -D_RTOS -D_DRP -D_TRACE -D_GUI_INTERFACE -DUSBPDCORE_LIB_PD3_FULL -DUSE_HAL_DRIVER -DSTM32G431xx -IInc -IDrivers/STM32G4xx_HAL_Driver/Inc -IDrivers/STM32G4xx_HAL_Driver/Inc/Legacy -IUtilities/GUI_INTERFACE -IUtilities/TRACER_EMB -IMiddlewares/Third_Party/FreeRTOS/Source/include -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -IMiddlewares/ST/STM32_USBPD_Library/Core/inc -IMiddlewares/ST/STM32_USBPD_Library/Devices/STM32G4XX/inc -IMiddlewares/ST/STM32_USBPD_Library/../../../Drivers/STM32G4xx_HAL_Driver/Inc -IMiddlewares/ST/STM32_USB_Device_Library/Core/Inc -IMiddlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -IDrivers/CMSIS/Device/ST/STM32G4xx/Include -IDrivers/CMSIS/Include -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"build/usbpd_cad_hw_if.d" -Wa,-a,-ad,-alms=build/usbpd_cad_hw_if.lst Middlewares/ST/STM32_USBPD_Library/Devices/STM32G4XX/src/usbpd_cad_hw_if.c -o build/usbpd_cad_hw_if.o Middlewares/ST/STM32_USBPD_Library/Devices/STM32G4XX/src/usbpd_cad_hw_if.c:167:17: warning: 'ManageStateDetached_SNK' used but never defined 167 | static uint32_t ManageStateDetached_SNK(uint8_t PortNum); | ^~~~~~~~~~~~~~~~~~~~~~~ arm-none-eabi-gcc build/main.o build/app_freertos.o build/usbpd.o build/usbpd_dpm_user.o build/usbpd_pwr_user.o build/usbpd_pwr_if.o build/usbpd_vdm_user.o build/usbpd_dpm_core.o build/usb_device.o build/usbd_conf.o build/usbd_desc.o build/usbd_cdc_if.o build/stm32g4xx_it.o build/stm32g4xx_hal_msp.o build/stm32g4xx_hal_timebase_tim.o build/stm32g4xx_ll_utils.o build/stm32g4xx_ll_exti.o build/stm32g4xx_hal_gpio.o build/stm32g4xx_hal_pcd.o build/stm32g4xx_hal_pcd_ex.o build/stm32g4xx_ll_usb.o build/stm32g4xx_hal.o build/stm32g4xx_hal_rcc.o build/stm32g4xx_hal_rcc_ex.o build/stm32g4xx_hal_flash.o build/stm32g4xx_hal_flash_ex.o build/stm32g4xx_hal_flash_ramfunc.o build/stm32g4xx_hal_exti.o build/stm32g4xx_hal_dma.o build/stm32g4xx_hal_dma_ex.o build/stm32g4xx_hal_pwr.o build/stm32g4xx_hal_pwr_ex.o build/stm32g4xx_hal_cortex.o build/stm32g4xx_hal_adc.o build/stm32g4xx_hal_adc_ex.o build/stm32g4xx_ll_adc.o build/stm32g4xx_hal_crc.o build/stm32g4xx_hal_crc_ex.o build/stm32g4xx_hal_dac.o build/stm32g4xx_hal_dac_ex.o build/stm32g4xx_hal_fdcan.o build/stm32g4xx_hal_i2c.o build/stm32g4xx_hal_i2c_ex.o build/stm32g4xx_hal_smbus.o build/stm32g4xx_hal_i2s.o build/stm32g4xx_hal_iwdg.o build/stm32g4xx_ll_lpuart.o build/stm32g4xx_ll_gpio.o build/stm32g4xx_ll_dma.o build/stm32g4xx_hal_uart.o build/stmle32g4xx_hal_uart_ex.o build/stm32g4xx_hal_rng.o build/stm32g4xx_hal_rtc.o build/stm32g4xx_hal_rtc_ex.o build/stm32g4xx_hal_spi.o build/stm32g4xx_hal_spi_ex.o build/stm32g4xx_hal_tim.o build/stm32g4xx_hal_tim_ex.o build/stm32g4xx_ll_pwr.o build/stm32g4xx_ll_usart.o build/stm32g4xx_ll_ucpd.o build/system_stm32g4xx.o build/croutine.o build/event_groups.o build/list.o build/queue.o build/stream_buffer.o build/tasks.o build/timers.o build/cmsis_os2.o build/heap_4.o build/port.o build/usbpd_trace.o build/usbpd_cad_hw_if.o build/usbpd_hw.o build/usbpd_hw_if_it.o build/usbpd_phy.o build/usbpd_phy_hw_if.o build/usbpd_pwr_hw_if.o build/usbpd_timersserver.o build/stm32g4xx_ll_tim.o build/usbd_core.o build/usbd_ctlreq.o build/usbd_ioreq.o build/usbd_cdc.o build/data_struct_tlv.o build/bsp_gui.o build/gui_api.o build/tracer_emb.o build/tracer_emb_hw.o build/stm32g4xx_ll_rcc.o build/startup_stm32g431xx.o -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -specs=nano.specs -TSTM32G431RBTx_FLASH.ld -lc -lm -lnosys Middlewares/ST/STM32_USBPD_Library/Core/lib/USBPDCORE_PD3_FULL_CM4_wc32.a -Wl,-Map=build/sthub.map,--cref -Wl,--gc-sections -o build/sthub.elf /usr/lib/gcc/arm-none-eabi/9.3.0/../../../../arm-none-eabi/bin/ld: build/usbpd_cad_hw_if.o: in function `ManageStateDetached_DRP': /home/feilong/workspace/sthub/prj/stm32g431rbtx/Middlewares/ST/STM32_USBPD_Library/Devices/STM32G4XX/src/usbpd_cad_hw_if.c:1137: undefined reference to `ManageStateDetached_SNK' collect2: error: ld returned 1 exit status make: *** [Makefile:260:build/sthub.elf] 错误 1
这个问题我猜了好久,因为之前的链接库错误,我一直在找这个库在那个lib里面,就差对全系统文件进行objdump
了,后来突然发现这个ManageStateDetached_SNK
函数就在报错的那个文件里面.不过是这么写的
#if defined(_SNK) static uint32_t ManageStateDetached_SNK(uint8_t PortNum) {
看来ST是认为这个函数只有在sink
时候才应该编译,但按照名字来看双向接口应该也有这个功能.于是修改成下面这样,编译之.
#if defined(_DRP) || defined(_SNK) static uint32_t ManageStateDetached_SNK(uint8_t PortNum) {
然后编译成功了.
不过至于能不能正常工作,这个就需要之后硬件完成后在测试了.
这些年都是靠着Pandownload来下载文件的,作者突然被捕,感觉挺心痛的.
https://zh.wikipedia.org/zh-hans/PanDownload
纪念PanDownload,纪念死去的互联网精神.
前提条件west debug能正常工作,如果不能的话,请参考官方文档进行配置.
cortex-debug
,C/C++
, Native Debug
,arm
settings.json里面加上下面两行
{ "cortex-debug.armToolchainPath": "/opt/zephyr-sdk/arm-zephyr-eabi/bin/", "cortex-debug.armToolchainPrefix": "arm-zephyr-eabi" }
下面这些参考了github,各种文档汇总而成.
launch.json
{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "cortex-debug", "request": "launch", "servertype": "openocd", "cwd": "${workspaceRoot}", "executable": "${workspaceFolder}/build/zephyr/zephyr.elf", "name": "stm32f746g-discovery", "device": "STM32F746NG", "configFiles": [ "${workspaceFolder}/boards/arm/stm32f746g_disco/support/openocd.cfg" ] } ] }
c_cpp_properties.json
{ "env": { "myZephyrSourcePath": "/home/feilong/workspace/zephyrproject/zephyr/", "myZephyrSDKPath": "/opt/zephyr-sdk" }, "configurations": [ { "name": "Linux", "includePath": [ "${myZephyrSourcePath}/include/", "${myZephyrSourcePath}/lib/libc/minimal/include/", "${myZephyrSourcePath}/arch/arm/include/", "${myZephyrSourcePath}/build/zephyr/include/generated/" ], "compilerPath": "${myZephyrSDKPath}/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "gcc-x64" } ], "version": 4 }
west build之后f5就可以了.
前几天更新Cimoc的时候,随手把Android SDK加了1,之后发现被提示要切换到AndroidX库,以前的库要废弃了。本文依旧是面向Google搜索编程(笑),不过搜的有点多,记不太清都从哪里查的资料了。
目前不确定是否有bug,先放成测试版,挂着测试几天。
之前一直没抽出空来,终于过年得到了额外假期关心下大家健康,前两天把之前鸽了好久的Cimoc更新了一下。目前大多数源都可以使用了,有几个源网站失效准备删去,修复了几个,大部分貌似都能用,几个不能用的先搁置几天。
今天抽时间更新了程序的依赖以及适配了Android Q,并且切换到R8混淆器。
通过R8混淆器的使用,编译速度由10min缩短至5min左右(travis ci集成时间),体积缩小170kb左右(由于后面将android support库切换为AndroidX库,依赖更新,折腾完后比原先涨了100k左右)
本来R8早在19年就已经被Google设置成为了默认的混淆器,但是由于咕咕咕,以及不常写Android软件,当时的处理是关掉R8,仍保持原有混淆策略。
这次,首先在debug模式启用混淆,启用R8,进行编译,得到了闪退的程序,查看logcat的堆栈信息可知,由于GreenDAO的崩溃导致闪退。
通过面向Google搜索的编程(参考https://juejin.im/post/5d5fb53b51882554a13f8b6a),做出补丁https://github.com/feilongfl/Cimoc/commit/a51f39c406ae9762190f379400491f1b2f108324
再次测试,OK不闪退了,面向Google编程结束。
最近研究了下AutoHotKey这个小玩具,跟高中时代玩过的AutoIt很像,不过这边更侧重于全局热键的实现。
前几天也把多年不用的C#重新用了下,四处抄抄代码做了个跟按键精灵类似的东西,突然想到AutoIt这个老物,于是又搜索了下又没有什么更好地方案,毕竟AutoIt印象里体积比较大,而且闭源。
具体对比可以参考 https://ui.vision/blog/ahk-vs-autoit/
这个工具的功能是每按一次热键将鼠标位置保存,并切换到原来位置。
主要用途是简化多屏幕/多窗口远距离频繁移动。
比如debug时有两个窗口,一边是代码,另一边是调试中的程序,在两个屏幕反复移动比较累(懒癌晚期),所以可以用一个快捷键快速切换位置。
更新: https://gist.github.com/feilongfl/8bb1799565ad74495f4140591d686cbd#file-mouseswitch-ahk
#SingleInstance force ; global val define global mouseSwitch = -1 ; set pixel pos base on screen CoordMode, Mouse, Screen CoordMode, ToolTip, Screen ; work func cahngeMouseStatus() { static xpos = 0 static ypos = 0 ; intial script varbal if(mouseSwitch = -1) { ; save omuse pos MouseGetPos, xpos, ypos ToolTip, %msg% , %xpos%, %ypos% ; initial mouse index mouseSwitch = false } mouseSwitch := mouseSwitch = true ? false : true ; get mouse pos MouseGetPos, xpos_t, ypos_t ; pop old pos MouseMove, %xpos%, %ypos% ; push origin pos xpos = %xpos_t% ypos = %ypos_t% ; showTips msg = %mouseSwitch%: %xpos% %ypos% ToolTip, %msg% , %xpos%, %ypos% } ; reg hotkey ; trig CapsLock:: cahngeMouseStatus() ; clear ^CapsLock:: ToolTip mouseSwitch = -1 return ; capslock +CapsLock:: SetCapsLockState % !GetKeyState("CapsLock", "T") return