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

[AUTOSAR][诊断管理][ECU][$19] 读取ECU的DTC故障信息

一、简介

  1. 在车载诊断中常用的诊断协议有ISO 14229等,在协议中主要定义了诊断请求、诊断响应的报文格式及ECU该如何处理诊断请求的应用。
  2. 其中ISO 14229系列标准协议定义了用于行业内诊断通信的需求规范,也就是UDS。UDS主要应用于OSI七层模型的第七层——应用层,它支持的汽车总线包括:CAN、LIN、FlexRay、Ethernet及K-LINE。
  3. UDS中的服务根据其功能分为6大类,共26种。其中包含的0x19服务(ReadDTCInformation)则是UDS中的重中之重。那么我们今天就一起进入到19服务中,感受其中的奥秘。

二、 服务介绍

19服务(ReadDTCInformation)用于读取ECU的DTC故障信息,此服务允许客户端从服务器读取诊断故障代码(DTC)的相关信息。此服务包含28个子服务(Subfunction),常用的5种子服务如下:

  • 0x01 reportNumberOfDTCByStatusMask(读取客户端定义状态掩码匹配的DTC数量)
  • 0x02 reportDTCByStatusMask(读取客户端定义状态掩码匹配的DTC)
  • 0x04 reportDTCSnapshotRecordByDTCNumber(检索客户端定义DTC掩码的快照数据)
  • 0x06 reportDTCExtDataRecordByDTCNumber(读取某个DTC及其相关的扩展数据,扩展数据包括DTC状态,优先级,发生次数,时间戳,里程等。)
  • 0x0A reportSupportedDTC(读取ECU支持的所有DTC的状态,包含支持的各个DTC编号以及相关状态)

今天主要解析19服务中的04子服务,也就是检索客户端定义DTC的快照号对应的快照记录数据,在AUTOSAR中也叫冻结帧。

(1)子服务介绍

  1. 快照数据概念介绍
    前面讲19服务常用子服务的时候,提到了Subfunction为04的子服务,使用04子服务对服务端进行请求,可以获取DTC发生时记录的快照数据。那04子服务是如何获取快照数据的呢?首先我们需要理解什么是快照数据。从ISO 14229-1协议可知,快照数据为发生某一故障时记录的DTC的电压、发动机转速、时间戳等,从而使工程师在ECU出现故障时能及时了解车辆的历史和实时故障信息。

  2. 报文格式介绍
    接下来通过介绍19 04子服务请求和响应的报文格式,分析报文中各个字节的相关定义。

请求格式

在这里插入图片描述
从图1中可知,19 04的请求报文包括四个部分,其中服务ID和Subfunction就不用过多解释了。DTCMaskRecord表示某个故障的DTC,当系统检测到一个故障发生时,则会存储其对应的故障数值,这个故障数值就是DTC。通过读取DTC可知一个故障发生时的具体位置以及原因和类型。通常UDS中DTC占3个字节,OBD Ⅱ占2个字节,在ISO 15031-6中定义的DTC由两个字节根基和一个字节的故障类型组成。我们通常用到的DTC格式都是由ISO 15031-6中定义的。图2是ISO 15031-6中定义的DTC的两个字节根基,图中很详细地解释了每一个Bit的含义。

在这里插入图片描述
SnapshotRecordNumber需要提前定义,可以有多个。如SnapshotRecordNumber设置为FF,则表示读取所有的快照数据组。

响应格式

图3
图3为响应报文格式,当使用19 04对ECU进行请求时,ECU给出的肯定响应的报文格式由七部分组成。此时的DTCAndStatusRecord由三个字节的DTC和一个字节的StatusOfDTC组成,StatusOfDTC表示DTC的状态。假设现在的DTC状态为0x09,则Bit0和Bit3置1。如某个DTC一直存在并且确认,则在ECU响应的报文中的StatusOfDTC为0x09。如图4
图4
SnapshotRecordNumber这个字节表示DTC快照记录的组号;DTCSnapshotRecordNumberOfldentifiers表示快照DID的个数,占一个字节;Dataldentifier这部分由两个字节组成,表示快照数据对应的DID,DTCSnapshotRecord表示快照DID对应的具体数据。

三、示例代码

(1)19_read_dtc_info.c

/********************************************************************************
* @file    19_read_dtc_info.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2023-05-30
* @brief   读取DTC信息
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "modules.h"
#include "os_api.h"
#include "edebug.h"
#include "kv_sys.h"
#include "ecu_ble_uart.h"
/* Private includes ----------------------------------------------------------*/
#include "std_math.h"
#include "app_can.h"
#include "can_nm.h"
#include "app_nm.h"
#include "diag_main.h"
#if AUTOSAR_DIAG_DTC_SWITCH
#include "dtc_main.h"
#endif
/* Private define ------------------------------------------------------------*/
#define UDS_ID         0x19
#define MAX_BUFF_SIZE  150
/* Private typedef -----------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/***************软定时器创建***************/
/* Private func --------------------------------------------------------------*//*** @brief  通过状态掩码报告DTC数目* @param  *data: 数据指针* @param  len: 数据长度* @retval 0--成功  >0--错误*/
static int8_t uds19_01(uint8_t *data, uint16_t len, uint8_t *out) {if (len != 3) {LOGE("len err != 3, sub%02x", data[1]);send_nrc_data(UDS_ID, NRC_INCORRECT_MESSAGE_LENTH);return 1;}if (data[1] & 0x80) { // 无需应答LOGI("No answer required, sub%02x", data[1]);} else {// 回复正响应码  单帧格式: len, 服务ID|0x40, 子功能ID,out[0] = 6;  // 数据总长度= 服务号 + sub_id + mask + data + num(2byte)out[1] = UDS_ID | 0x40;   // 服务号,回复上位机需要 |0x40out[2] = data[1];out[3] = AUTOSAR_DIAG_DTC_STATE_BIT; // 获取DTC掩码out[4] = 0; // SAE_J2012-DA_DTCFormat_00uint16_t dtc_count = get_dtc_num_by_mask(data[2]);out[5] = (uint8_t)(dtc_count >> 8);out[6] = (uint8_t)(dtc_count & 0xFF);out[7] = 0xAA;app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, out, 8);}return 0;
}/*** @brief  通过状态掩码报告DTC* @param  *data: 数据指针* @param  len: 数据长度* @retval 0--成功  >0--错误*/
static int8_t uds19_02(uint8_t *data, uint16_t len, uint8_t *out) {if (len != 3) {LOGE("len err != 3, sub%02x", data[1]);send_nrc_data(UDS_ID, NRC_INCORRECT_MESSAGE_LENTH);return 1;}if (data[1] & 0x80) { // 无需应答LOGI("No answer required, sub%02x", data[1]);} else {// 回复正响应码  单帧格式: len, 服务ID|0x40, 子功能ID,out[1] = UDS_ID | 0x40;   // 服务号,回复上位机需要 |0x40out[2] = data[1];out[3] = AUTOSAR_DIAG_DTC_STATE_BIT; // 获取DTC掩码uint8_t d_len = 0;d_len = get_dtc_status_by_mask(data[2], &out[4], MAX_BUFF_SIZE - 4 - 1); // 4--数据头 1--连续帧头预留out[0] = 3 + d_len; // 数据总长度 = 服务号 + sub_id + mask + ndata// 判断数据长度,单帧还是连续帧发送if (out[0] > 7) {memmove(out + 1, out, out[0] + 1); // 单帧改连续帧格式,数据总长度 + 长度位,数据总长度 + 长度位out[0] = NWL_FIRST_FRAME << 4; // 数据帧格式(nwl_frame_st_t)if (g_tx_msg.data != 0) {free(g_tx_msg.data);g_tx_msg.data = NULL;}// 发送首帧(只含6byte data)后,剩余长度:去除 (服务号|sub_id|mask + D0D1D2)d_len = out[1] - 3 - 3;g_tx_msg.data = malloc(d_len);if (g_tx_msg.data == NULL) {send_nrc_data(UDS_ID, NRC_ACCESS_DENIED);return 2;}app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, out, 8);memcpy(g_tx_msg.data, out + 8, d_len);g_tx_msg.len = d_len;} else {memset(&out[out[0] + 1], 0xAA, 8 - out[0] - 1);  // 空白区填充指定值app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, out, 8);}}return 0;
}/*** @brief  通过DTC码报告DTC 快照记录* @param  *data: 数据指针* @param  len: 数据长度* @retval 0--成功  >0--错误*/
static int8_t uds19_04(uint8_t *data, uint16_t len, uint8_t *out) {uint32_t dtc_id;if (len != 6) {LOGE("len err != 6, sub%02x", data[1]);send_nrc_data(UDS_ID, NRC_INCORRECT_MESSAGE_LENTH);return 1;} else { // == 6uint8_t record_numb = data[5]; // 记录号if ((record_numb > SS_NB_MAX) && record_numb != 0xFF && record_numb != 0x00) {LOGE("record numb nonsupport:%02x, sub%02x", record_numb, data[1]);send_nrc_data(UDS_ID, NRC_REQUEST_OUT_OF_RANGE);return 2;}dtc_id = data[2];dtc_id <<= 8;dtc_id += data[3];dtc_id <<= 8;dtc_id += data[4];uint8_t SN = is_dtc_id(dtc_id); // 得到dtc id,对应的数组索引if (SN == 0xFF) {LOGE("dtc id id err:%02x, sub%02x", dtc_id, data[1]);send_nrc_data(UDS_ID, NRC_SUBFUNCTION_NOT_SUPPORTED);return 2;}if (data[1] & 0x80) { // 无需应答LOGI("No answer required, sub%02x", data[1]);} else {// 回复正响应码  单帧格式: len, 服务ID|0x40, 子功能ID,out[1] = UDS_ID | 0x40;   // 服务号,回复上位机需要 |0x40out[2] = data[1]; // SUB_ID 子功能IDout[3] = data[2]; // DTC_ID 低16bitout[4] = data[3]; // DTC_ID 高8bitout[5] = data[4]; // DTC_ID 低8bitout[6] = get_dtc_snap_shot_status(SN, record_numb); // DTC Status 最近一次错误状态out[7] = record_numb;out[8] = SS_TYPE_MAX_NUMBER;uint16_t d_len = 0;d_len = get_dtc_snap_shot_by_id(SN, record_numb, &out[9], MAX_BUFF_SIZE - 8 - 1); // 7--数据头 1--连续帧头预留// 数据总长度 = 服务号 + 子功能ID + DTC_ID(3byte) + DTC Status + record_numb + MAX_NUMBER + DATA_LENout[0] = 8 + d_len;memmove(out + 1, out, out[0] + 1); // 单帧改连续帧格式,数据总长度 + 长度位out[0] = NWL_FIRST_FRAME << 4; // 数据帧格式(nwl_frame_st_t)if (g_tx_msg.data != 0) {free(g_tx_msg.data);g_tx_msg.data = NULL;}// 发送首帧(只含6byte data)后,剩余长度:去除 (服务号 + 子功能ID + DTC_ID(3byte) + DTC Status)d_len = out[1] - 2 - 3 - 1;g_tx_msg.data = malloc(d_len);if (g_tx_msg.data == NULL) {send_nrc_data(UDS_ID, NRC_ACCESS_DENIED);return 3;}app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, out, 8);memcpy(g_tx_msg.data, out + 8, d_len);g_tx_msg.len = d_len;}}return 0;
}/*** @brief  通过DTC码报告DTC扩展数据记录* @param  *data: 数据指针* @param  len: 数据长度* @retval 0--成功  >0--错误*/
static int8_t uds19_06(uint8_t *data, uint16_t len, uint8_t *out) {uint32_t dtc_id;if (len != 6) {LOGE("len err != 6, sub%02x", data[1]);send_nrc_data(UDS_ID, NRC_INCORRECT_MESSAGE_LENTH);return 1;}uint8_t record_numb = data[5];  // 记录号if ((record_numb > SS_NB_MAX) && record_numb != 0xFF && record_numb != 0x00) {LOGE("record numb nonsupport:%02x, sub%02x", record_numb, data[1]);send_nrc_data(UDS_ID, NRC_REQUEST_OUT_OF_RANGE);return 2;}dtc_id = data[2];dtc_id <<= 8;dtc_id += data[3];dtc_id <<= 8;dtc_id += data[4];uint8_t SN = is_dtc_id(dtc_id); // 得到dtc id,对应的数组索引if (SN == 0xFF) {LOGE("dtc id id err:%02x, sub%02x", dtc_id, data[1]);send_nrc_data(UDS_ID, NRC_SUBFUNCTION_NOT_SUPPORTED);return 2;}if (data[1] & 0x80) { // 无需应答LOGI("No answer required, sub%02x", data[1]);} else {// 回复正响应码  单帧格式: len, 服务ID|0x40, 子功能ID,out[1] = UDS_ID | 0x40;   // 服务号,回复上位机需要 |0x40out[2] = data[1]; // SUB_ID 子功能IDout[3] = data[2]; // DTC_ID 低16bitout[4] = data[3]; // DTC_ID 高8bitout[5] = data[4]; // DTC_ID 低8bitout[6] = get_dtc_snap_shot_status(SN, record_numb); // DTC Status 最近一次错误状态out[7] = record_numb;//os_delay(1);uint16_t d_len = 0;d_len = get_dtc_snap_shot_ex_data(SN, record_numb, &out[8], MAX_BUFF_SIZE - 8 - 1); // 7--数据头 1--连续帧头预留// 数据总长度 = 服务号 + 子功能ID + DTC_ID(3byte) + DTC Status + record_numb  + DATA_LENout[0] = 7 + d_len;if (out[0] > 7) {memmove(out + 1, out, out[0] + 1); // 单帧改连续帧格式,数据总长度 + 长度位out[0] = NWL_FIRST_FRAME << 4; // 数据帧格式(nwl_frame_st_t)if (g_tx_msg.data != 0) {free(g_tx_msg.data);g_tx_msg.data = NULL;}// 发送首帧(只含6byte data)后, 去除 (服务号 + 子功能ID + DTC_ID(3byte) + DTC Status)d_len = out[1] - 2 - 3 - 1;g_tx_msg.data = malloc(d_len);if (g_tx_msg.data == NULL) {send_nrc_data(UDS_ID, NRC_ACCESS_DENIED);return 3;}memcpy(g_tx_msg.data, out + 8, d_len);g_tx_msg.len = d_len;app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, out, 8);} else {memset(&out[out[0] + 1], 0xAA, 8 - out[0] - 1);  // 空白区填充指定值app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, out, 8);}}return 0;
}/*** @brief  报告支持的全部DTC* @param  *data: 数据指针* @param  len: 数据长度* @retval 0--成功  >0--错误*/
static uint8_t uds19_0A(uint8_t *data, uint16_t len, uint8_t *out) {if (len != 2) {LOGE("len err != 2, sub%02x", data[1]);send_nrc_data(UDS_ID, NRC_INCORRECT_MESSAGE_LENTH);return 1;}if (data[1] & 0x80) { // 无需应答LOGI("No answer required, sub%02x", data[1]);} else {// 回复正响应码  单帧格式: len, 服务ID|0x40, 子功能ID, maskout[1] = UDS_ID | 0x40;   // 服务号,回复上位机需要 |0x40out[2] = data[1]; // SUB_ID 子功能IDout[3] = AUTOSAR_DIAG_DTC_STATE_BIT; // 掩码uint16_t d_len = 0;d_len = get_all_dtc_status(&out[4], MAX_BUFF_SIZE - 4 - 1); // 4--数据头 1--连续帧头预留// 数据总长度 = 服务号 + 子功能ID + 掩码  + DATA_LENout[0] = 3 + d_len;// LOGD("%u,%u\r\n", out[0], d_len);if (out[0] > 7) {memmove(out + 1, out, out[0] + 1); // 单帧改连续帧格式,数据总长度 + 长度位out[0] = NWL_FIRST_FRAME << 4; // 数据帧格式(nwl_frame_st_t)if (g_tx_msg.data != 0) {free(g_tx_msg.data);g_tx_msg.data = NULL;}// 发送首帧(只含6byte data)后, 去除 (服务号 + 子功能ID + DTC_ID(3byte) + DTC Status)d_len = out[1] - 2 - 3 - 1;g_tx_msg.data = malloc(d_len);if (g_tx_msg.data == NULL) {send_nrc_data(UDS_ID, NRC_ACCESS_DENIED);return 3;}memcpy(g_tx_msg.data, out + 8, d_len);LOGD("%x,%u,%x,%u\r\n", g_tx_msg.data[d_len-1], d_len, out[out[1]+1], out[1]+1);g_tx_msg.len = d_len;app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, out, 8);} else {memset(&out[out[0] + 1], 0xAA, 8 - out[0] - 1);  // 空白区填充指定值app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, out, 8);}}return 0;
}void uds19_main(nwl_msg_t* p) {uint8_t data[MAX_BUFF_SIZE];uint8_t d_len = 0;if (p->len < 2) {LOGE("len err < 2");send_nrc_data(UDS_ID, NRC_INCORRECT_MESSAGE_LENTH);goto end;}switch (p->data[1] & 0x7F) { // 子功能,bit7为应答位。  =1则不允许应答// 通过状态掩码报告DTC数目case 0x01: {if (uds19_01(p->data, p->len, data) != 0) {}break;}// 通过状态掩码报告DTCcase 0x02:if (uds19_02(p->data, p->len, data) != 0) {}break;// 通过DTC码报告DTC 快照记录case 0x04: {if (uds19_04(p->data, p->len, data) != 0) {}break;}// 通过DTC码报告DTC扩展数据记录case 0x06: {if (uds19_06(p->data, p->len, data) != 0) {}break;}// 报告支持的全部DTCcase 0x0A: {if (uds19_0A(p->data, p->len, data) != 0) {}break;}default:send_nrc_data(UDS_ID, NRC_SUBFUNCTION_NOT_SUPPORTED);break;}
end:return;
}#if AUTOSAR_DIAG_SWITCH && USE_UDS_19 && AUTOSAR_DIAG_DTC_SWITCH
DIAG_SERVICE_REG(UDS_ID, DIAG_NO_SECURITY_LEVEL, (DEFAULT_SESSION|EXTENDED_SESSION),(DIAG_PHYS_REQ|DIAG_FUNC_REQ), NULL, NULL, uds19_main);
#endif

相关文章:

[AUTOSAR][诊断管理][ECU][$19] 读取ECU的DTC故障信息

一、简介 在车载诊断中常用的诊断协议有ISO 14229等&#xff0c;在协议中主要定义了诊断请求、诊断响应的报文格式及ECU该如何处理诊断请求的应用。其中ISO 14229系列标准协议定义了用于行业内诊断通信的需求规范&#xff0c;也就是UDS。UDS主要应用于OSI七层模型的第七层——…...

前端精度问题 (id 返回的和传给后端的不一致问题)

eg: 后端返回 id 10976458979374929 前端获取到的: 10976458979374928 原因: js 中 Number类型范围-2^53 1 到 2^53 - 1 Number.isSafeInteger()用来判断一个整数是否落在这个范围之内。 java中 Long 类型的取值范围是-2^63 1 到 2^63 - 1, 比JavaScript中大很多&#xff0…...

WPF Material Design UI框架

前言 Material Design in xaml 是开源免费的ui框架&#xff0c;工控软件主打的就是简单界面。 以下简称MD 相关资源 MaterialDesignInXamlToolkit Github 地址 MD 快速启动 MD 案例压缩包 MD 框架使用 启动环境配置 安装Nuget包 App.xaml 配置 <Application x:Class&qu…...

C语言求 3*3 矩阵对角线之和

完整代码&#xff1a; // 求 3*3 矩阵对角线之和 #include<stdio.h>int main() {int n3;int arr[3][3];// 输入矩阵printf("请输入矩阵的元素:\n");for (int i 0; i < n; i){for (int j 0; j < n; j){scanf("%d", &arr[i][j]);}}int su…...

缓存分片中的哈希算法与一致性哈希算法

什么是缓存分片 在高并发场景下&#xff0c;缓存往往成为了瓶颈。这时候&#xff0c;我们可以通过缓存数据分片的方式来解决问题。所谓缓存数据分片&#xff0c;就是将缓存数据按照一定的规则分成多个片段&#xff0c;每个片段由不同的缓存节点负责。这样做有两个好处&#xf…...

线框图软件:Balsamiq Wireframes mac中文介绍

Balsamiq Wireframes mac是一款用于创建线框图的软件工具。它旨在帮助用户快速制作出清晰、简洁的界面原型&#xff0c;以便在设计和开发过程中进行协作和沟通。 Balsamiq Wireframes具有简单直观的用户界面&#xff0c;使用户能够快速添加和编辑各种用户界面元素&#xff0c;如…...

【wxWidgets实现透明wxPanel_核心实现_原创思想】

描述 wxWidgets 根本就没有实现过透明wxPanel容器,你设置wxTRANSPARENT_WINDOW,结果sorry 黑色,哈哈哈哈, 就是和你作对.想想当下那么漂亮的桌面, 背景, 透明, 特效.哎 悲哀啊,实现不了,就那死板的界面特性. 网上找了好久,也是乱七八糟,改底层代码还是算了吧,升级特要命.都是只…...

重大技术问题,iPhone 15 Pro Max面临“烧屏门”风波 | 百能云芯

近期&#xff0c;社交媒体平台上陆续涌现大量用户和数码博主就iPhone 15 Pro Max出现烧屏问题的投诉与评论。 烧屏问题是OLED屏幕常见的一个缺陷&#xff0c;这是由OLED屏幕发光机制引发的&#xff0c;OLED屏幕可视为由无数微小的灯泡-像素点构成&#xff0c;这些像素点可以独立…...

深度学习中的不确定性综述

领域学者&#xff1a; http://www.gatsby.ucl.ac.uk/~balaji/ 论文标题&#xff1a; A Survey of Uncertainty in Deep Neural Networks 论文链接&#xff1a; https://arxiv.org/pdf/2107.03342.pdf 概要 在过去的十年中&#xff0c;神经网络几乎遍及所有科学领域&#x…...

uni-app 小宠物 - 会说话的小鸟

在 template 中 <view class"container"><view class"external-shape"><view class"face-box"><view class"eye-box eye-left"><view class"eyeball-box eyeball-left"><span class"…...

POJ 3470 Walls 树上分桶

今天太晚了&#xff0c;代码先发上&#xff0c;思路明天说吧。 陌上花开&#xff0c;树上分桶 #include <iostream> #include <algorithm> #include <vector> using namespace std; /*** 对于y1不等于y2的&#xff0c;可以用datC求解&#xff0c;对于x1不等…...

HIVE-17824,删除hdfs分区信息,清理metastore元数据

当手动删除HDFS 分区数据时,但是并没有清理 Hive 中的分区元数据,删除操作无法自动更新hive分区表元数据。也就是从hdfs中删除大量分区数据,并没有执行如下命令: alter table drop partition commad 从hive 3.0.0开始可以使用MSCK的方法发现新分区或删除丢失的分区; MSCK [REPA…...

Python深度学习进阶与应用丨注意力(Attention)机制、Transformer模型、生成式模型、目标检测算法、图神经网络、强化学习详解等

目录 第一章 注意力&#xff08;Attention&#xff09;机制详解 第二章 Transformer模型详解 第三章 生成式模型详解 第四章 目标检测算法详解 第五章 图神经网络详解 第六章 强化学习详解 第七章 深度学习模型可解释性与可视化方法详解 更多应用 近年来&#xff0c;伴…...

javaEE -6(10000详解文件操作)

一&#xff1a;认识文件 我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备&#xff0c;当我们想要进行数据保存时&#xff0c;往往不是保存成一个整体&#xff0c;而是独立成一个个的单位进行保存&#xff0c;这个独立的单位就被抽象成文件的概念&#xff0c…...

图像处理之《基于多MSB预测和Huffman编码的加密图像可逆数据隐藏》论文精读

一、文章摘要 随着云存储和隐私保护的发展&#xff0c;可逆数据隐藏在加密图像中(RDHEI)作为一种技术越来越受到人们的关注&#xff0c;它可以&#xff1a;在图像加密领域嵌入额外的数据&#xff0c;确保嵌入的数据可以无差错地提取&#xff0c;原始图像可以无损地恢复。本文提…...

Nginx安装配置项目部署然后加SSL

个人操作笔记记录 第一步&#xff1a;把 nginx 的源码包nginx-1.8.0.tar.gz上传到 linux 系统 第二步&#xff1a;解压缩 tar zxvf nginx-1.8.0.tar.gz 第三步&#xff1a;进入nginx-1.8.0目录 使用 configure 命令创建一 makeFile 文件。 直接复制过去运行 ./configur…...

【算法练习Day26】分发饼干摆动序列 最大子数组和

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 分发饼干摆动序列最大子数组…...

redis缓存击穿/穿透/雪崩面试回答

面试官&#xff1a;什么是缓存穿透 ? 怎么解决 ? 候选人&#xff1a; 嗯~~&#xff0c;我想一下 缓存穿透是指查询一个一定不存在的数据&#xff0c;如果从存储层查不到数据则不写入缓存&#xff0c;这将导致这个不存在的数据每次请求都要到 DB 去查询&#xff0c;可能导致…...

Jmeter性能测试 —— TPS拐点寻找

寻找TPS性能拐点1、准备脚本①在本地电脑调试Jmeter压测脚本 ②上传到压测机Jmeter所在的服务器 2、执行压力测试①执行压测脚本 jmeter –n –t xianchengzuse.jmx ②记录业务压测数据 3、监控服务器性能指标 ①监控CPU输入top命令 ②监控内存 free –m ③jstat监控sweep和…...

科技资讯|苹果穿戴新专利,表带、服装等织物可变身柔性屏幕或扬声器

根据美国商标和专利局&#xff08;USPTO&#xff09;本周公示的清单&#xff0c;苹果公司获得了一项新的技术专利&#xff0c;可以在 Apple Watch 表带、服装等物品上&#xff0c;引入基于织物的柔性扬声器。 根据专利描述&#xff0c;通过在织物中嵌入声学组件&#xff08;例…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...