stm32u5 qspi 读写 w25q128 timeout

需求 使用 STM32U575 主控芯片,使用 QSPI 读写 W25Q128,简单的读写测试没有问题。但是在后面调试中发现,当按照 11 个字节一组进行读写,从 4352 这个地址开始写,写入到 4605 的时候,就超时状态了。 HAL_OSPI_STATE_ERROR 然后我单独从 4605 写入 11 个字节,确实会超时,但是前面写入并没有超时,很奇怪。 然后,我测试了一下,从0开始写,每次写 11 个字节,当从 1023 开始写入 11 个字节会超时。感觉好像是在 256字节的页边界出写入会出问题,但是又不是每个 256 边界都会出问题。 解决 先使用 16个字节为一组进行测试,没有跨界问题。然后又使用了4字节写入,写入了 400多万组,也没有任何问题。 这基本就说明了,是软件或者库的某个层面,因为32位对齐产生的这个 bug. 解决的方法也很简单,我原来写入 11 个字节是对结构体使用了 pragma pack(1) ,只要不用这个字节对齐命令,编译器会自动进行 32位对齐,重新测试,数据就可以正常读写,没有问题了。 参考 stm32: QSPI flash driver concurrent access issue STM32L4使用QSPI驱动spiFLASH(W25Q64) {SPI/QSPI} 正确理解STM32H7驱动QSPI W25Q手册中时钟后缀1-2-2,1-4-4等代表的含义 AN4760 Quad-SPI interface on STM32 microcontrollers and microprocessors HAL_QSPI_AutoPolling() fail when polling the SR of NOR flash in QPI mode Stm32h7 Hal qspi autpolling timeout stm32u575rit6 qspi driver ST external loader learning w25q flash series part 8 quadspi external loader

2023-12-28 · 1 min · 94 words · RamLife

mysql 多表外键联查视图

需求 使用 mysql,建立了多张表,表之间使用外键进行关联,现在需要通过视图进行多表联查。 多表内容 reagent key_id project type 1 coag gbact itemrange key_id fk_reagent item 1 1 act 2 1 cr 3 1 pf filereportdata key_id fk_item value strip 1 2 1.1 sid01 2 1 2.2 sid02 3 3 3.3 sid03 多表关系 filereportdata.fk_item = itemrange.key_id itemrange.fk_reagent = reagent.key_id 期望结果 strip project type item value sid01 coag gbact cr 1.1 sid02 coag gbact act 2.2 sid03 coag gbact pf 3.3 解决 多表查询 SELECT f....

2023-12-18 · 1 min · 156 words · RamLife

stm32 rtc 读取数据不正常

需求 stm32 使用 hal 读取 rtc 数据时,发现数据读取要不是 0,要不就不变,比较奇怪。 解决 经过多次调试并查看源码,才发现,API的注释里面写了,需要先调用 HAL_RTC_GetTime, 再调用 HAL_RTC_GetDate, 才行,否则就不行。因为先读取 time 可以解锁读取。 =You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values in the higher-order calendar shadow registers to ensure consistency between the time and date values.= 参考

2023-12-12 · 1 min · 42 words · RamLife

android 获取 IP 地址

需求 android 获取本机 ip 地址 解决 public class NetworkHelper { private static final String TAG = "NetworkHelper"; private Context context; public NetworkHelper(Context context) { this.context = context; } // 获取ip地址 @RequiresApi(api = Build.VERSION_CODES.M) public String getLocalIpAddress() { // ConnectivityManager netManager = (ConnectivityManager) getApplicationContext().getSystemService(CONNECTIVITY_SERVICE); ConnectivityManager netManager = (ConnectivityManager) context.getApplicationContext().getSystemService(CONNECTIVITY_SERVICE); // NetworkInfo info = netManager.getActiveNetworkInfo(); // // 网络是否连接 // if (info != null && info.isConnected()) { // // wifi类型 // if (info.getType() == TYPE_WIFI) { // return getWifiIpAddress(); // } else { // // 其他类型 // return getEthIpAddress(); // } // } try { NetworkInfo info = netManager....

2023-12-03 · 3 min · 436 words · RamLife

QT5 升级到 Qt6, QRegExp 不能用

需求 Qt5 的工程升级到 Qt6 之后,找不到 QRegExp 等一系列类。 解决 QRegExp -> QRegularExpression QRegExpValidator -> QRegularExpressionValidator // Qt5 QRegExp version(QLatin1String("(.+)_v(\\d+)")); if (version.exactMatch(completeBaseName/*QString*/)) { // some code } // Qt6 QRegularExpression version(QLatin1String("(.+)_v(\\d+)")); QRegularExpressionMatch match = version.match(completeBaseName); if (match.hasMatch()) { // Find exact match or not } 参考 QT6找不到QRegExpValidator类问题解决办法 关于QRegExpValidator头文件不存在的问题 Qt6中的端口QRegExp::exactMatch()

2023-12-02 · 1 min · 47 words · RamLife

Guix text_button 设置文字,报错 0x30

需求 需要设置 text_button 上面显示的文字的时候,报错 "GX_SYSTEM_MEMORY_ERROR : (0x30) 未定义内存分配器或内存分配失败。" 解决 分析 debug 仔细追查,发现 _gx_text_button_text_set_ext 这个函数里面会判断有没有设置 private text copy, 如果设置了,那么再检查有没有开启 _gx_system_memory_allocator, 如果没有,那么就会报错 0x30 了。 解决方法 有两种解决方法: 无 private text copy + 无 gx_system_memory_allocator_set(memory_allocate, memory_free), 会直接使用传入进去的字符串参数,只要传入进去的不是局部变量,就没有必要勾选 private text copy. 有 private text copy + 有 gx_system_memory_allocator_set(memory_allocate, memory_free), 也可以,会多复制一份数据。 参考 第 4 章 - GUIX 服务说明 {ThreadX全家桶} GUIX sample 错误–>gx_prompt_text_set_ext大坑,必须正确指定有效字符串长度才可以使用

2023-11-30 · 1 min · 56 words · RamLife

stm32使用FMC控制 LCD 时,图像不正常

需求 stm32 使用 fmc 来控制 Lcd 显示时,碰到了两个问题: 图像变小了,并且是双份显示 屏幕只显示了 4/5,最下面花屏 解决 经过网络搜索和反复的调试,终于找到问题。 图像变小 这个是 fmc 的时序配置有问题,导致使用 DMA2D 进行数据传输时,lcd 会丢数据,然后图像就变小了。这个解决只需要对照 lcd 的芯片中的时间参数,重新设置 fmc 的时序参数即可解决。 图像只显示 4/5 这个是 FMC 的地址线的问题。 我们需要重新考虑一下为什么可以使用 fmc 来控制 lcd 显示,理论上来说, DMA2D 写入数据的时候,地址是自动增长的啊! 其实因为我们只使用了一根地址线,那么写入数据的时候,这个地址线的低位就算增长也没有关系,毕竟我们只使用了最高位作为地址线,只要使用 DMA2D 写入的数据不会超过最高位,那么就不会有影响。 所以这次的错误就是 DMA2D 在全屏写入的时候, 320*240 = 76800, 而当前的地址线使用的是 A16,那么能够提供的空间只有 2的16次方 = 65536,已经溢出了。解决的方法也很简单,使用 A17 地址线即可。 参考 DMA2D skips pixels when sending directly to display over FMC STM32 FMC Display

2023-11-22 · 1 min · 65 words · RamLife

stm32 cube ide 编译提示 undefined reference to

需求 编译的时候,提示 undefined reference to 解决 这种问题经常会碰到,一般就是相关源文件没有在编译列表里面,结果经过仔细查找,都添加进去了。后来经过仔细查找,发现原来是 c++ 和 c 混合编译的问题,在 c++ 中文件里面调用的函数,其所在的头文件没有使用 extern "C" 包含,导致的。想要修改也很简单,不需要改动头文件,只需要在 c++ 文件中这样: #include "gx_api.h" extern "C" { #include "gx_display.h" } 而且其实在 map 文件中是有相关线索的,下面分别是没有用 extern 包含,和用了 extern 包含的 map 文件中的函数信息。可以明显看到有 extern 包含的,有相关地址。 .text._gx_display_driver_565rgb_setup 0x0000000000000000 0x260 ./guix/common/src/gx_display_driver_565rgb_setup.o .text._gx_display_driver_565rgb_setup 0x000000000801e6e8 0x260 ./guix/common/src/gx_display_driver_565rgb_setup.o 0x000000000801e6e8 _gx_display_driver_565rgb_setup 参考 gcc “undefined reference to” 问题解决方法

2023-11-17 · 1 min · 53 words · RamLife

Guix 移植

需求 使用 stm32cubeide 移植 guix 到 stm32u575 上面。 解决 简单界面设计 下载 guix studio 按照例子做个最简单界面 导出 resource 和 specification 源码 下载 guix studio 对应版本源码 把源码中的 common 整个文件夹放到工程中 把源码中的 port 中相应架构的 gx_port.h 放到工程中 开启 GX_INCLUDE_USER_DEFINE_FILE, 把 guix studio 的例子中的 gx_user.h 复制到工程中。 板级相关 在 port 文件夹中新增 gx_display_driver_rgb565_stm32u575 相关源文件和头文件。 在文件中新增: UINT GuixDriverSetupRgb565(GX_DISPLAY *display) { LcdInit(); _gx_display_driver_565rgb_setup(display, (VOID*)GUIX_SCREEN_HANDLE, GuixBufferToggleRgb565); display -> gx_display_driver_horizontal_line_draw = GuixHorizontalLineDirectDrawRgb565; display -> gx_display_driver_vertical_line_draw = GuixVerticalLineDirectDrawRgb565; display -> gx_display_driver_pixel_write = GuixPixelDirectWriteRgb565; display -> gx_display_driver_pixel_blend = GuixPixelDirectBlendRgb565; // display -> gx_display_driver_buffer_toggle = stm324xg_16bpp_buffer_toggle; display -> gx_display_handle = GUIX_SCREEN_HANDLE; return(GX_SUCCESS); } 新增上面相关的这些画点和线的函数。 线程 新增线程函数, 其中设置都是和 guix studio 导出的文件相关的。 GX_WINDOW *pScreen; GX_WINDOW_ROOT *root; void GuixMainEntry(ULONG thread_input) { (void)thread_input; gx_system_initialize(); // gx_system_memory_allocator_set(memory_allocate, memory_free); gx_studio_display_configure(PRIMARY, GuixDriverSetupRgb565, LANGUAGE_ENGLISH, PRIMARY_THEME_1, &root); gx_studio_named_widget_create((char *)"Button_Screen", (GX_WIDGET *)root, (GX_WIDGET **)&pScreen); gx_widget_show(root); gx_system_start(); while (1) { tx_thread_sleep(20); } } 把线程函数添加到启动线程中即可。 参考 {ThreadX全家桶} ThreadX GUIX直驱方案搞定,任何显示屏,低资源的MCU都可以跑了,不再需要画布,附工程下载 {ThreadX全家桶} 第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第30章,emWin更新至第57章(2022-04-04)

2023-11-16 · 1 min · 134 words · RamLife

__attribute__((weak)) 修饰的函数没有被覆盖

需求 定义了同名函数后,原来的 __attribute__((weak)) 修饰的函数并没有被覆盖 ? 解决 打开生成的 map 文件,经过搜索,只找到了原来的函数,并没有找到新定义的函数。 在头文件中增加了新定义函数的声明 int _write(int file, char *ptr, int len);, 重新编译后,打开 map 文件,就可以找到新定义的函数了。 所以这个问题还是因为没有在头文件中声明,导致 printf 再调用的时候,只找到了弱定义的 write. 参考 ARM 之十一__weak 和 attribute((weak)) 关键字的使用 弱符号_attribute_((weak))

2023-11-10 · 1 min · 31 words · RamLife