当前位置: 首页 > news >正文

[单片机框架][调试功能] 回溯案发现场

程序莫名死机跑飞,不知道问题,那么下面教你回溯错误源

回溯案发现场

  • 一、修改HardFault_Handler
    • 1. xx.s 在启动文件,找到HardFault_Handler。并修改。
    • 2. 定义HardFault_Handler_C函数。(主要是打印信息并存储Flash)
    • 3. 根据回读PC和LR地址,通过MAP文件找到对应位置,判断引起硬件错误的原因。
  • 二、定义DefaultISR,查看是否有中断未声明
  • 三、如果使用了RTX,则需要重定义osRtxErrorNotify函数。
  • 四、读取错误信息
  • 举例

jianqiang.xue



一、修改HardFault_Handler

1. xx.s 在启动文件,找到HardFault_Handler。并修改。

HardFault_Handler\PROCEXPORT  HardFault_Handler         [WEAK]MOV     R0, spIMPORT  HardFault_Handler_CBL      HardFault_Handler_CENDP

2. 定义HardFault_Handler_C函数。(主要是打印信息并存储Flash)

void HardFault_Handler_C(unsigned int* hardfault_args) {HardFault_t info;info.r0 = ((unsigned long)hardfault_args[0]);info.r1 = ((unsigned long)hardfault_args[1]);info.r2 = ((unsigned long)hardfault_args[2]);info.r3 = ((unsigned long)hardfault_args[3]);info.r12 = ((unsigned long)hardfault_args[4]);info.lr = ((unsigned long)hardfault_args[5]);info.pc = ((unsigned long)hardfault_args[6]);info.psr = ((unsigned long)hardfault_args[7]);info.BFAR = (*((volatile unsigned long*)(0xE000ED38)));info.CFSR = (*((volatile unsigned long*)(0xE000ED28)));info.HFSR = (*((volatile unsigned long*)(0xE000ED2C)));info.DFSR = (*((volatile unsigned long*)(0xE000ED30)));info.AFSR = (*((volatile unsigned long*)(0xE000ED3C)));info.SCB_SHCSR = SCB->SHCSR;uint8_t data[70], len = 0;len = snprintf((char *)data,70, "\n[Hard fault handler - all num in hex] %x\r\n", *hardfault_args);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "R0 = %x\r\nR1 = %x\r\nR2 = %x\r\nR3 = %x\r\n", info.r0, info.r1, info.r2, info.r3);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "R12 = %x\r\n", info.r12);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "LR [R14] = %x,subroutine call return address\r\n", info.lr);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "PC [R15] = %x,program counter\r\n", info.pc);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "PSR = %x\r\nBFAR = %lx\r\n", info.psr, (*((volatile unsigned long*)(0xE000ED38))));McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "CFSR = %lx\r\nHFSR = %lx\r\nDFSR = %lx\r\n",(*((volatile unsigned long*)(0xE000ED28))), (*((volatile unsigned long*)(0xE000ED2C))), (*((volatile unsigned long*)(0xE000ED30))));McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "AFSR = %lx\r\nSCB_SHCSR = %x\r\n",(*((volatile unsigned long*)(0xE000ED3C))), SCB->SHCSR);McuUartWriteString(&ble_uart, data, len);info.event = 0;kv_set_env(0xFF00, &info, sizeof(HardFault_t)); // 记录到Flashwhile (1);
}

3. 根据回读PC和LR地址,通过MAP文件找到对应位置,判断引起硬件错误的原因。

二、定义DefaultISR,查看是否有中断未声明

#define VECTORNUM    (*(volatile uint32_t*)(0xE000ED04))
void DefaultISR(void) {HardFault_t info;uint8_t data[50], len;len = sprintf((char *)data, "\n default_isr %d,%x \n", (uint8_t)VECTORNUM, (uint32_t)VECTORNUM);McuUartWriteString(&ble_uart, data, len);info.event = 1;info.VECTORNUM_ADDR = VECTORNUM;kv_set_env(0xFF00, &info, sizeof(HardFault_t)); // 记录到Flashwhile(1);
}

根据打印出来的数据,判断VECTOR,是怎么原因触发中断的。查对应芯片向量表,得知导致原因。
在这里插入图片描述

在这里插入图片描述

三、如果使用了RTX,则需要重定义osRtxErrorNotify函数。

uint32_t osRtxErrorNotify(uint32_t code, void* object_id) {HardFault_t info;(void)object_id;uint8_t data[100], len = 0;switch (code) {case osRtxErrorStackOverflow:len = sprintf((char *)data, "\n Stack overflow detected for thread (thread_id=0x%x)\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// Stack overflow detected for thread (thread_id=object_id)break;case osRtxErrorISRQueueOverflow:len = sprintf((char *)data, "\n ISR Queue overflow detected when inserting object 0x%x\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// ISR Queue overflow detected when inserting object (object_id)break;case osRtxErrorTimerQueueOverflow:len = sprintf((char *)data, "\n User Timer Callback Queue overflow detected for timer (timer_id=0x%x)\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// User Timer Callback Queue overflow detected for timer (timer_id=object_id)break;case osRtxErrorClibSpace:len = sprintf((char *)data, "\n Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM 0x%x\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUMbreak;case osRtxErrorClibMutex:len = sprintf((char *)data, "\n Standard C/C++ library mutex initialization failed 0x%x\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// Standard C/C++ library mutex initialization failedbreak;default:// Reservedbreak;}info.event = 2;info.RTX_CODE = code;info.RTX_OBJ_ID = (uint32_t)object_id;kv_set_env(0xFF00, &info, sizeof(HardFault_t)); // 记录到Flashfor (;;) {}// return 0U;
}

四、读取错误信息

采用ATCMD读取,如下

#ifdef ATCMD_EN
// 在功能模块中定义一个标准函数
static int atcmd_backtrack(atcmd_pack_t *pack) {HardFault_t *info = NULL;uint8_t buff[100], len;info = kv_get_env(0xFF00);if (info == NULL) {strcat((char*)buff, AT_ERROR);} else {if (info->event == 0) {len = snprintf((char *)buff, 100, "R0 = %x\r\nR1 = %x\r\nR2 = %x\r\nR3 = %x\r\nR12 = %x\r\n", info->r0, info->r1, info->r2, info->r3, info->r12);pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "LR [R14] = %x,subroutine call return address\r\n", info->lr);pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "PC [R15] = %x,program counter\r\n", info->pc);pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "PSR = %x\r\nBFAR = %lx\r\n", info->psr, (*((volatile unsigned long*)(0xE000ED38))));pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "CFSR = %lx\r\nHFSR = %lx\r\nDFSR = %lx\r\n",(*((volatile unsigned long*)(0xE000ED28))), (*((volatile unsigned long*)(0xE000ED2C))), (*((volatile unsigned long*)(0xE000ED30))));pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "AFSR = %lx\r\nSCB_SHCSR = %x\r\n",(*((volatile unsigned long*)(0xE000ED3C))), SCB->SHCSR);pack->reply(buff, strlen((char*)buff));memset(buff, 0, 100);} else if (info->event == 1) {len = snprintf((char *)buff, 100, "\n default_isr %d,%x \n", (uint8_t)info->VECTORNUM_ADDR, (uint32_t)info->VECTORNUM_ADDR);} else if (info->event == 2) {len = snprintf((char *)buff, 100, "\n RTX_ERR CODE=0x%x, OBJ_ID=0x%x \n", (uint8_t)info->RTX_CODE, (uint32_t)info->RTX_OBJ_ID);}strcat((char*)buff, AT_OK);}pack->reply(buff, strlen((char*)buff));return 0;
}// 注册AT指令,传入标准函数
ATCMD_INIT("AT+BACKTRACK?", atcmd_backtrack);
#endif

举例

/********************************************************************************* @file    backtrack.c* @author  jianqiang.xue* @Version V1.0.0* @Date    2023-02-10* @brief   记录错误原因,方便追溯问题源********************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>#include "cmsis_os2.h"
#include "os_api.h"
#include "SKEAZ1284.h"
#include "atcmd_slave.h" // 自行添加[Module\atcmd\atcmd_slave.c]#include "kv_sys.h"
#include "mcu_uart.h"
#include "ecu_cc2642.h"
#include "edebug.h"typedef struct __PACKED {uint32_t event; // 0--HardFault 1--DefaultISR 2--osRtxErrorNotify// HardFault_Handleruint32_t r0;uint32_t r1;uint32_t r2;uint32_t r3;uint32_t r12;uint32_t lr;uint32_t pc;uint32_t psr;uint64_t BFAR;uint64_t CFSR;uint64_t HFSR;uint64_t DFSR;uint64_t AFSR;uint64_t SCB_SHCSR;// DefaultISRuint32_t VECTORNUM_ADDR;// osRtxErrorNotifyuint32_t RTX_CODE;uint32_t RTX_OBJ_ID;
} HardFault_t;void HardFault_Handler_C(unsigned int* hardfault_args) {HardFault_t info;info.r0 = ((unsigned long)hardfault_args[0]);info.r1 = ((unsigned long)hardfault_args[1]);info.r2 = ((unsigned long)hardfault_args[2]);info.r3 = ((unsigned long)hardfault_args[3]);info.r12 = ((unsigned long)hardfault_args[4]);info.lr = ((unsigned long)hardfault_args[5]);info.pc = ((unsigned long)hardfault_args[6]);info.psr = ((unsigned long)hardfault_args[7]);info.BFAR = (*((volatile unsigned long*)(0xE000ED38)));info.CFSR = (*((volatile unsigned long*)(0xE000ED28)));info.HFSR = (*((volatile unsigned long*)(0xE000ED2C)));info.DFSR = (*((volatile unsigned long*)(0xE000ED30)));info.AFSR = (*((volatile unsigned long*)(0xE000ED3C)));info.SCB_SHCSR = SCB->SHCSR;uint8_t data[70], len = 0;len = snprintf((char *)data,70, "\n[Hard fault handler - all num in hex] %x\r\n", *hardfault_args);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "R0 = %x\r\nR1 = %x\r\nR2 = %x\r\nR3 = %x\r\n", info.r0, info.r1, info.r2, info.r3);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "R12 = %x\r\n", info.r12);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "LR [R14] = %x,subroutine call return address\r\n", info.lr);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "PC [R15] = %x,program counter\r\n", info.pc);McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "PSR = %x\r\nBFAR = %lx\r\n", info.psr, (*((volatile unsigned long*)(0xE000ED38))));McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "CFSR = %lx\r\nHFSR = %lx\r\nDFSR = %lx\r\n",(*((volatile unsigned long*)(0xE000ED28))), (*((volatile unsigned long*)(0xE000ED2C))), (*((volatile unsigned long*)(0xE000ED30))));McuUartWriteString(&ble_uart, data, len);len = snprintf((char *)data,70, "AFSR = %lx\r\nSCB_SHCSR = %x\r\n",(*((volatile unsigned long*)(0xE000ED3C))), SCB->SHCSR);McuUartWriteString(&ble_uart, data, len);info.event = 0;kv_set_env(0xFF00, &info, sizeof(HardFault_t)); // 记录到Flashwhile (1);
}#define VECTORNUM    (*(volatile uint32_t*)(0xE000ED04))
void DefaultISR(void) {HardFault_t info;uint8_t data[50], len;len = sprintf((char *)data, "\n default_isr %d,%x \n", (uint8_t)VECTORNUM, (uint32_t)VECTORNUM);McuUartWriteString(&ble_uart, data, len);info.event = 1;info.VECTORNUM_ADDR = VECTORNUM;kv_set_env(0xFF00, &info, sizeof(HardFault_t)); // 记录到Flashwhile(1);
}uint32_t osRtxErrorNotify(uint32_t code, void* object_id) {HardFault_t info;(void)object_id;uint8_t data[100], len = 0;switch (code) {case osRtxErrorStackOverflow:len = sprintf((char *)data, "\n Stack overflow detected for thread (thread_id=0x%x)\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// Stack overflow detected for thread (thread_id=object_id)break;case osRtxErrorISRQueueOverflow:len = sprintf((char *)data, "\n ISR Queue overflow detected when inserting object 0x%x\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// ISR Queue overflow detected when inserting object (object_id)break;case osRtxErrorTimerQueueOverflow:len = sprintf((char *)data, "\n User Timer Callback Queue overflow detected for timer (timer_id=0x%x)\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// User Timer Callback Queue overflow detected for timer (timer_id=object_id)break;case osRtxErrorClibSpace:len = sprintf((char *)data, "\n Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM 0x%x\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUMbreak;case osRtxErrorClibMutex:len = sprintf((char *)data, "\n Standard C/C++ library mutex initialization failed 0x%x\n", (uint32_t)object_id);McuUartWriteString(&ble_uart, data, len);// Standard C/C++ library mutex initialization failedbreak;default:// Reservedbreak;}info.event = 2;info.RTX_CODE = code;info.RTX_OBJ_ID = (uint32_t)object_id;kv_set_env(0xFF00, &info, sizeof(HardFault_t)); // 记录到Flashfor (;;) {}// return 0U;
}#ifdef ATCMD_EN
// 在功能模块中定义一个标准函数
static int atcmd_backtrack(atcmd_pack_t *pack) {HardFault_t *info = NULL;uint8_t buff[100], len;info = kv_get_env(0xFF00);if (info == NULL) {strcat((char*)buff, AT_ERROR);} else {if (info->event == 0) {len = snprintf((char *)buff, 100, "R0 = %x\r\nR1 = %x\r\nR2 = %x\r\nR3 = %x\r\nR12 = %x\r\n", info->r0, info->r1, info->r2, info->r3, info->r12);pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "LR [R14] = %x,subroutine call return address\r\n", info->lr);pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "PC [R15] = %x,program counter\r\n", info->pc);pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "PSR = %x\r\nBFAR = %lx\r\n", info->psr, (*((volatile unsigned long*)(0xE000ED38))));pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "CFSR = %lx\r\nHFSR = %lx\r\nDFSR = %lx\r\n",(*((volatile unsigned long*)(0xE000ED28))), (*((volatile unsigned long*)(0xE000ED2C))), (*((volatile unsigned long*)(0xE000ED30))));pack->reply(buff, strlen((char*)buff));len = snprintf((char *)buff, 100, "AFSR = %lx\r\nSCB_SHCSR = %x\r\n",(*((volatile unsigned long*)(0xE000ED3C))), SCB->SHCSR);pack->reply(buff, strlen((char*)buff));memset(buff, 0, 100);} else if (info->event == 1) {len = snprintf((char *)buff, 100, "\n default_isr %d,%x \n", (uint8_t)info->VECTORNUM_ADDR, (uint32_t)info->VECTORNUM_ADDR);} else if (info->event == 2) {len = snprintf((char *)buff, 100, "\n RTX_ERR CODE=0x%x, OBJ_ID=0x%x \n", (uint8_t)info->RTX_CODE, (uint32_t)info->RTX_OBJ_ID);}strcat((char*)buff, AT_OK);}pack->reply(buff, strlen((char*)buff));return 0;
}// 注册AT指令,传入标准函数
ATCMD_INIT("AT+BACKTRACK?", atcmd_backtrack);
#endif

相关文章:

[单片机框架][调试功能] 回溯案发现场

程序莫名死机跑飞&#xff0c;不知道问题&#xff0c;那么下面教你回溯错误源 回溯案发现场一、修改HardFault_Handler1. xx.s 在启动文件&#xff0c;找到HardFault_Handler。并修改。2. 定义HardFault_Handler_C函数。&#xff08;主要是打印信息并存储Flash&#xff09;3. 根…...

MySQL主从同步-(二)搭建从机服务器

在docker中创建并启动MySQL从服务器&#xff1a;**端口3307docker run -d \-p 3307:3306 \-v /atguigu/mysql/slave1/conf:/etc/mysql/conf.d \-v /atguigu/mysql/slave1/data:/var/lib/mysql \-e MYSQL_ROOT_PASSWORD123456 \--name atguigu-mysql-slave1 \mysql:8.0.3创建MyS…...

Linux系列 备份与分享文档

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.备份与分享文档 1.使用压缩和解压缩工具 &#xff08;1&…...

SNI生效条件 - 补充nginx-host绕过实例复现中SNI绕过的先决条件

文章目录1.前置环境搭建2.测试SNI生效条件(时间)3. 证书对SNI的影响3.1 双方使用同一个证书&#xff1a;3.2 双方使用不同的证书与私钥4. 端口号区分测试4.1 端口号区分&#xff0c;证书区分&#xff1a;4.2 端口号区分,证书不区分&#xff1a;5.总结SNI运行机制6. SNI机制绕过…...

傻白探索Chiplet,Modular Routing Design for Chiplet-based Systems(十一)

阅读了Modular Routing Design for Chiplet-based Systems这篇论文&#xff0c;是关于多chiplet通信的&#xff0c;个人感觉核心贡献在于实现了 deadlock-freedom in multi-chiplet system&#xff0c;而不仅仅是考虑单个intra-chiplet的局部NoC可以通信&#xff0c;具体的一些…...

C语言静态库、动态库的封装和注意事项

1、动态库、静态库介绍 参考博客&#xff1a;《静态库和动态库介绍以及Makefile》&#xff1b; 2、代码目录结构和编译脚本 参考博客&#xff1a;《实际工作开发中C语言工程的目录结构分析》&#xff1b; 3、编写库的流程 (1)明确需求:需求是否合理、需求的使用场景、需求可能遇…...

MyBatis-Plus分页插件和MyBatisX插件

MyBatis-Plus分页插件和MyBatisX插件六、插件1、分页插件a>添加配置类b>测试八、代码生成器1、引入依赖2、快速生成十、MyBatisX插件1、新建spring boot工程a>引入依赖b>配置application.ymlc>连接MySQL数据库d>MybatisX逆向生成2、MyBatisX快速生成CRUD申明…...

年前无情被裁,面试大厂的这几个月…

2月份了&#xff0c;金三银四也即将来临&#xff0c;在这个招聘季&#xff0c;大厂也开始招人&#xff0c;但还是有很多人吐槽说投了很多简历&#xff0c;却迟迟没有回复… 另一面企业招人真的变得容易了吗&#xff1f;有企业HR吐槽&#xff0c;简历确实比以前多了好几倍&…...

基于Java的分片上传功能

起因&#xff1a;最近在工作中接到了一个大文件上传下载的需求&#xff0c;要求将文件上传到share盘中&#xff0c;下载的时候根据前端传的不同条件对单个或多个文件进行打包并设置目录下载。 一开始我想着就还是用老办法直接file.transferTo(newFile)就算是大文件&#xff0c…...

KDS安装步骤

KDS kinetis design studio 软件 第一步官网(https://www.nxp.com/ 注册账号下载set成功下载软件。 随着AI&#xff0c;大数据这些技术的快速发展&#xff0c;与此有关的知识也普及开来。如何在众多网站中寻找最有价值的信息&#xff0c;如何在最短的时间内获得最新的技…...

JavaSE-线程池(1)- 线程池概念

JavaSE-线程池&#xff08;1&#xff09;- 线程池概念 前提 使用多线程可以并发处理任务&#xff0c;提高程序执行效率。但同时创建和销毁线程会消耗操作系统资源&#xff0c;虽然java 使用线程的方式有多种&#xff0c;但是在实际使用过程中并不建议使用 new Thread 的方式手…...

开源代码的寿命为何只有1年?

说实话&#xff0c;如果古希腊的西西弗斯是一个在2016年编写开源代码的开发者&#xff0c;那他会有宾至如归的感觉。著名的西西弗斯处罚&#xff0c;是神话流传下来的&#xff0c;他被迫推一块巨大的石头上山&#xff0c;当登顶之后&#xff0c;只能眼睁睁看着它滚下去&#xf…...

完善登录功能--过滤器的使用

系列文章目录 Spring Boot读取配置文件内容的三种方式 Spring Boot自动配置–如何切换内置Web服务器 SpringBoot项目部署 上述为该系列部分文章&#xff0c;想了解更多可看我博客主页哦&#xff01; 文章目录系列文章目录前言一、创建自定义过滤器LoginCheckFilter二、在启动类…...

CSS基础:属性和关系选择器

字体属性 color 文本颜色 div{ color:red;} div{ color:#ff0000;} div{ color:rgb(255,0,0);} div{ color:rgba(255,0,0,.5);}font-size 文本大小 h1 {font-size:40px;} h2 {font-size:30px;} p {font-size:14px;}注意&#xff1a;chrome浏览器接受最小字体是12px font-we…...

设计模式:原型模式解决对象创建成本大问题

一、问题场景 现在有一只猫tom&#xff0c;姓名为: tom, 年龄为&#xff1a;1&#xff0c;颜色为&#xff1a;白色&#xff0c;请编写程序创建和tom猫属性完全相同的10只猫。 二、传统解决方案 public class Cat {private String name;private int age;private String color;…...

驱动开发(二)

一、驱动流程 驱动需要以下几个步骤才能完成对硬件的访问和操作&#xff1a; 模块加载函数 module_init注册主次设备号 <应用程序通过设备号找到设备>驱动设备文件 <应用程序访问驱动的方式> 1、手动创建 &#xff08;mknod&#xff09;2、程序自动创建file_oper…...

《狂飙》大结局,这22句经典台词值得细品

最近爆火的热播剧《狂飙》大家都看了吗&#xff1f; 剧情紧凑、演技炸裂、豆瓣评分9.0&#xff0c;可以说是开年评分最高的一部国产剧。 ​ 虽然大结局了。 里面有很多经典台词&#xff0c;值得每个人细细品味。 01 这世界不缺梦想 有本事你就去实现它 02 你这么善良 怎么跟坏…...

【计算机网络期末复习】第二章 物理层

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为想复习学校计算机网络课程的同学提供重点大纲&#xff0c;帮助大家渡过期末考~ &#x1f4da;专栏地址&#xff1a; ❤️如果有收获的话&#xff0c;欢迎点…...

多核异构核间通信-mailbox/RPMsg 介绍及实验

1. 多核异构核间通信 由于MP157是一款多核异构的芯片&#xff0c;其中既包含的高性能的A7核及实时性强的M4内核&#xff0c;那么这两种处理器在工作时&#xff0c;怎么互相协调配合呢&#xff1f; 这就涉及到了核间通信的概念了。 IPCC (inter-processor communication contr…...

【Rust日报】2023-02-11 从头开始构建云数据库 RisingWave - 为什么我们从 C++ 转向 Rust...

GTK4发布v0.60gtk4-rs代码库包含GTK4的Rust crates。还有个庞大的GObject库生态系统&#xff0c;其中许多库基于gtk-rs中包含的Rust绑定工具。 特别是&#xff1a;gtk-rs-core&#xff0c;一些核心库的绑定&#xff0c;例如 glib、gio、pango、graphenegstreamer-rs&#xff0c…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...