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

国民技术N32G430开发笔记(15)- IAP升级 树莓派串口发送数据

IAP升级 树莓派串口发送数据

1、树莓派接入usb转串口模块后,会生成/dev/ttyUSB0节点,因为树莓派内核已经编译usb_serial以及各模块的驱动。
我们直接对ttyUSB0节点编程即可。
2、协议同上一节
cmd + data_lenght + data0 + …+ datax + checksum
1、获取版本号 0x01 0x02 0x00 0x00 checksum
2、升级
1、进入升级模式 0x02 0x02 0x00 0x00 checksum
2、升级文件大小 0x03 0x04 0x00 0x00 0x00 0x00 checksum
3、数据包发送 0x04 0x80 0x00 0x00 0x00 0x00 … checksum
4、数据包发送完成 0x05 0x02 0x00 0x00 checksum

checksum采用crc16的检验方法。

3、升级过程:
1、发送升级模式命令。
2、发送文件大小命令
3、循环发送Application.bin的升级包,每包数据head+64个数据+checksum。
4、发送升级完成命令。
4、代码解析如下:
在这里插入图片描述
在build目录执行 cmake …;make 即可编译出uartiap。

CMakeLists.txt

cmake_minimum_required(VERSION 3.18.4)
project (uartIap)aux_source_directory(. C_SOURCES)
aux_source_directory(./UartIap C_SOURCES_UART)include_directories(./UartIap)add_executable(${PROJECT_NAME} ${C_SOURCES} ${C_SOURCES_UART})
target_link_libraries(${PROJECT_NAME} pthread)

n32g430_iap.c

#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "uart.h"#define APPLICATION_PATH                "Application.bin"
#define UPGRADE_DATA_PACKAGES_LENGHT    0x40
#define UPGRADE_PACKAGES_LENGHT         0x40 + 0x04typedef enum{MI_FALSE  =   0,MI_TRUE   =   1,}MI_BOOL;typedef unsigned char   MI_U8;
typedef unsigned short  MI_U16;MI_U8 get_ver_cmd[6]            = {0x01,0x02,0x00,0x00,0x00,0x00};
MI_U8 update_cmd[6]             = {0x02,0x02,0x00,0x00,0x00,0x00};
MI_U8 file_size_cmd[8]          = {0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00};
MI_U8 file_package[UPGRADE_PACKAGES_LENGHT]         = {0x04,UPGRADE_DATA_PACKAGES_LENGHT};
MI_U8 update_complete_cmd[6]    = {0x05,0x02,0x00,0x00};
MI_U16 w_num = 0;static MI_U8 isRunning = 0;
char r_data[256] = {0};
sem_t sem;static MI_BOOL get_update_file_size(char * file_path,size_t *size)
{FILE *file;file = fopen(file_path,"rb");if (!file){perror("get_update_file_size fopen error\n");return MI_FALSE;}fseek(file, 0L, SEEK_END);*size = ftell(file);fclose(file);return MI_TRUE;
}static MI_U16 CRC16(MI_U8 * buf, MI_U16 len)
{MI_U16 i;MI_U16 crc = 0xffff;if (len == 0) {len = 1;}while (len--) {crc ^= *buf;for (i = 0; i<8; i++) {            if (crc & 1) {               crc >>= 1;        crc ^= 0xA001;            }      else {               crc >>= 1;            }       }     buf++;}return(crc);
}static MI_BOOL compare(MI_U8 *des,MI_U8 *src,int len)
{while (len--){if (*des != *src){return MI_FALSE;}des++;src++;}return MI_TRUE;
}static void send_get_version_cmd(int fd)
{int len = sizeof(get_ver_cmd);int crc = CRC16(get_ver_cmd,len-2);get_ver_cmd[len-2] = crc & 0x00ff;get_ver_cmd[len-1] = ((crc >> 8) & 0x00ff);serialWrite(fd,get_ver_cmd,sizeof(get_ver_cmd));
}static void send_enter_update_cmd(int fd)
{int len = sizeof(update_cmd);int crc = CRC16(update_cmd,len-2);update_cmd[len-2] = crc & 0x00ff;update_cmd[len-1] = ((crc >> 8) & 0x00ff);serialWrite(fd,update_cmd,sizeof(update_cmd));
}static MI_BOOL send_update_file_size_cmd(int fd)
{int len = sizeof(file_size_cmd);size_t file_size = 0;get_update_file_size(APPLICATION_PATH,&file_size);file_size_cmd[2] = (file_size >> 24 & (0xff));file_size_cmd[3] = (file_size >> 16 & (0xff));file_size_cmd[4] = (file_size >> 8 & (0xff));file_size_cmd[5] = (file_size & (0xff));int crc = CRC16(file_size_cmd,len-2);file_size_cmd[len-2] = crc & 0x00ff;file_size_cmd[len-1] = ((crc >> 8) & 0x00ff);serialWrite(fd,file_size_cmd,sizeof(file_size_cmd));return MI_TRUE;
}static MI_BOOL send_file_every_package(int fd)
{int len = sizeof(file_package);FILE *fp;size_t file_size;int package_num;MI_U8 package_buff[UPGRADE_DATA_PACKAGES_LENGHT] = {0};fp = fopen(APPLICATION_PATH,"rb");if (!fp){perror("fopen error\n");return MI_FALSE;}get_update_file_size(APPLICATION_PATH,&file_size);if (file_size % UPGRADE_DATA_PACKAGES_LENGHT == 0 ){package_num = file_size / UPGRADE_DATA_PACKAGES_LENGHT;}else{package_num = (file_size / UPGRADE_DATA_PACKAGES_LENGHT) + 1;}printf("pageage_num == %d\n",package_num);while (!feof(fp)/* condition */){/* code */int r_len = fread(package_buff,1,UPGRADE_DATA_PACKAGES_LENGHT,fp);// 最后读出来不满128 ,用0xff补全。if (r_len != UPGRADE_DATA_PACKAGES_LENGHT){for (int i=r_len;i<UPGRADE_DATA_PACKAGES_LENGHT;i++){package_buff[i] = 0xff;}}memcpy(&file_package[2],package_buff,sizeof(package_buff));int crc = CRC16(file_package,sizeof(file_package)-2);file_package[sizeof(file_package)-2] = crc & 0x00ff;file_package[sizeof(file_package)-1] = ((crc >> 8) & 0x00ff);usleep(30 * 1000);w_num++;printf("send package process == [%03d]\n", ((w_num * 100)/package_num));#if DEBUGfor(int i=0;i< len;i++){printf("0x%02x  ",file_package[i]);if ((i+1) % 16 == 0)printf("\n");}printf("\n");#endifmemset(r_data,0,sizeof(r_data));serialWrite(fd,file_package,len);sem_wait(&sem);
#if DEBUG// for(int i=0;i< len;i++)// {//     printf("0x%02x  ",r_data[i]);//     if ((i+1) % 16 == 0)//         printf("\n");// }// printf("\n");// int status = compare(r_data,file_package,20);// if (status)// {//     printf("send_file_every_package and receive cmd success!\n");// }// else// {//     perror("send_file_every_package not equal receive cmd\n");// }//printf("read len == %d  w_num == %d \n",len,w_num);#endif        }fclose(fp);return MI_TRUE;
}static MI_BOOL send_update_complete_cmd(int fd)
{int len = sizeof(update_complete_cmd);int crc = CRC16(update_complete_cmd,len-2);update_complete_cmd[len-2] = crc & 0x00ff;update_complete_cmd[len-1] = ((crc >> 8) & 0x00ff);serialWrite(fd,update_complete_cmd,sizeof(update_complete_cmd));return MI_TRUE;
}void *uart_read_thread(void *arg)
{int fd = *((int *)arg);size_t  size ;        sem_wait(&sem);while(isRunning){size = serialRead(fd,r_data,256); //阻塞方式去读#if DEBUG    if (size > 0){for(int i=0;i<size;i++){printf("0x%02x  ",r_data[i]);}printf("\n");}#endif    sem_post(&sem);}printf("uart_read_thread exit\n");pthread_exit(0);
}int main(int argc,char *argv[])
{int fd = 0;int ret;char w_data[] = "hello world\n";MI_U16 crc = 0;MI_BOOL status;pthread_t m_read_thread ;size_t update_file_size;sem_init(&sem, 0, 0);fd = serialOpen("/dev/ttyUSB0",115200);if (fd > 0){printf("open ttyUSB0 ok\n");}else{printf("open ttyUSB0 fail\n");return -1;}ret = pthread_create(&m_read_thread,NULL,uart_read_thread,&fd);if (ret){perror("pthread_create error\n");return -1;}else{isRunning = 1;sem_post(&sem);}sleep(1);// 获取一下N32G430C8L7的版本号memset(r_data,0,sizeof(r_data));send_get_version_cmd(fd);sem_wait(&sem);printf("get version == %s\n",r_data);memset(r_data,0,sizeof(r_data));send_enter_update_cmd(fd);sem_wait(&sem);status = compare(r_data,update_cmd,sizeof(update_cmd));if (status){printf("send_enter_update_cmd and receive cmd success!\n");}else{perror("send_enter_update_cmd not equal receive cmd\n");}get_update_file_size(APPLICATION_PATH,&update_file_size);printf("get update file size == %ld\n",update_file_size);memset(r_data,0,sizeof(r_data));send_update_file_size_cmd(fd);sem_wait(&sem);status = compare(r_data,file_size_cmd,sizeof(file_size_cmd));if (status){printf("send_update_file_size_cmd and receive cmd success!\n");}else{perror("send_update_file_size_cmd not equal receive cmd\n");}send_file_every_package(fd);memset(r_data,0,sizeof(r_data));send_update_complete_cmd(fd);sem_wait(&sem);pthread_cancel(m_read_thread);isRunning = 0;pthread_join(m_read_thread,NULL);serialClose(fd);printf("raspberryPi App exit!\n");
}

uart.c

#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include "uart.h"static speed_t getBaudRate(int baudRate)
{switch(baudRate) {case 0: return B0;case 50: return B50;case 75: return B75;case 110: return B110;case 134: return B134;case 150: return B150;case 200: return B200;case 300: return B300;case 600: return B600;case 1200: return B1200;case 1800: return B1800;case 2400: return B2400;case 4800: return B4800;case 9600: return B9600;case 19200: return B19200;case 38400: return B38400;case 57600: return B57600;case 115200: return B115200;case 230400: return B230400;case 460800: return B460800;case 500000: return B500000;case 576000: return B576000;case 921600: return B921600;case 1000000: return B1000000;case 1152000: return B1152000;case 1500000: return B1500000;case 2000000: return B2000000;case 2500000: return B2500000;case 3000000: return B3000000;case 3500000: return B3500000;case 4000000: return B4000000;default: return -1;}
}static int setParity(int fd,int dataBits,int stopBits,int parity)
{struct termios options;if (tcgetattr (fd, &options) != 0) {printf ("SetupSerial 1");return (-1);}options.c_cflag &= ~CSIZE;switch (dataBits) {case 7:options.c_cflag |= CS7;break;case 8:options.c_cflag |= CS8;break;default:fprintf (stderr, "Unsupported data size\n");return (-1);}switch (parity) {case 'n':case 'N':options.c_cflag &= ~PARENB; /* Clear parity enable */options.c_iflag &= ~INPCK;  /* Enable parity checking */break;case 'o':case 'O':options.c_cflag |= (PARODD | PARENB);options.c_iflag |= INPCK;   /* Disable parity checking */break;case 'e':case 'E':options.c_cflag |= PARENB;  /* Enable parity */options.c_cflag &= ~PARODD;options.c_iflag |= INPCK;   /* Disable parity checking */break;case 'S':case 's':           /*as no parity */options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;break;default:fprintf (stderr, "Unsupported parity\n");return (-1);}switch (stopBits) {case 1:options.c_cflag &= ~CSTOPB;break;case 2:options.c_cflag |= CSTOPB;break;default:fprintf (stderr, "Unsupported stop bits\n");return (-1);}/* Set input parity option */if (parity != 'n')options.c_iflag |= INPCK;tcflush (fd, TCIFLUSH);options.c_cc[VTIME] = 0x01;options.c_cc[VMIN] =  0xFF; /* Update the options and do it NOW *///qd to set raw mode, which is copied from weboptions.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP| INLCR | IGNCR | ICRNL | IXON);options.c_oflag &= ~OPOST;options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);options.c_cflag &= ~(CSIZE | PARENB);options.c_cflag |= CS8;if (tcsetattr (fd, TCSANOW, &options) != 0) {perror ("SetupSerial 3");return (-1);}return 0;
}int serialOpen(const char *path, int baudRate)
{int fd;speed_t speed;/* Check arguments */{speed = getBaudRate(baudRate);if (speed == -1) {printf("get Baud rate error\n");return -1;}}{fd = open(path, O_RDWR);if (fd == -1){printf("open serial error =%d\n",fd);return -1;}}/* Configure device */{struct termios cfg;if (tcgetattr(fd, &cfg)){printf("tcgetattr() failed\n");close(fd);return -1;}cfmakeraw(&cfg);cfsetispeed(&cfg, speed);cfsetospeed(&cfg, speed);if (tcsetattr(fd, TCSANOW, &cfg)){printf("tcsetattr() failed\n");close(fd);return -1;}}setParity(fd,8,1,'N');//printf("open Success==%d\n",fd);return fd;
}int serialWrite(int fd,char *writeData,int len)
{if (fd > 0){write(fd,writeData,len);}else{printf("[File]=%s[Function]=%s error\n",__FILE__,__FUNCTION__);return -1;}return 0;
}int serialRead(int fd,char *readData,int len)
{size_t size = 0;if (fd > 0){size = read(fd,readData,len);}else{printf("[File]=%s[Function]=%s error\n",__FILE__,__FUNCTION__);return -1;}return size;
}int serialClose(int fd)
{close(fd);return 0;
}

uart.h

#ifndef __UART_H__
#define __UART_H__int serialOpen(const char *path, int baudRate);
int serialWrite(int fd,char *writeData,int len);
int serialRead(int fd,char *readData,int len);
int serialClose(int fd);#endif

5、视频

屏幕录制2023-05-03 15.39.07

6、代码路径 : https://gitee.com/xiaoguo-tec_0/raspberrypi

相关文章:

国民技术N32G430开发笔记(15)- IAP升级 树莓派串口发送数据

IAP升级 树莓派串口发送数据 1、树莓派接入usb转串口模块后&#xff0c;会生成/dev/ttyUSB0节点&#xff0c;因为树莓派内核已经编译usb_serial以及各模块的驱动。 我们直接对ttyUSB0节点编程即可。 2、协议同上一节 cmd data_lenght data0 … datax checksum 1、获取版本…...

svo论文解读

SVO: Semi-Direct Visual Odometry for Monocular and Multi-Camera Systems 2016TRO MOTION ESTIMATION 1 Sparse Image Alignment 从上一帧的特征投影到当前帧&#xff0c;最小化重投影误差计算帧间位姿&#xff08;patch44&#xff09; 2 Relaxation Through Feature Alig…...

DolphinScheduler海豚调度教程

DolphinScheduler 教程 &#xff08;一&#xff09;入门指南 简介 关于Dolphin Apache DolphinScheduler是一个分布式易扩展的可视化DAG工作流任务调度开源系统。解决数据研发ETL 错综复杂的依赖关系&#xff0c;不能直观监控任务健康状态等问题。DolphinScheduler以DAG流式…...

ubuntu脚本解释器踩坑:#!/bin/bash 与 #!/bin/sh

前言&#xff1a; 博主正在写linux的脚本的时候遇到&#xff1a;xx.sh: 3: Syntax error: "(" unexpected 查看shell脚本语法没有问题&#xff0c;后面发现是解释器的原因。 一、不同的解释器 #!是特殊的表示符&#xff0c;其后面根的是此解释此脚本的shell的路径…...

小松鼠踩一踩游戏

文章目录 一、 介绍和知识点九、UnityFacade 门面设计模式二、 声音全局管理器测试音频代码UI全局管理器父类抽象类 BaseManager子类 UIManager 四、 UI按钮的引用父类 BasePanel子类主面板 MainPanel子类 游戏中 GamePanel子类 游戏结果 ResultPanel 角色动画器、控制角色移动…...

使用crontab命令同步时间

crontab命令可以用于在Linux系统中定期同步时间。常用的时间同步方法有: 1. 使用ntpdate同步时间 可以添加如下crontab任务: */5 * * * * /usr/sbin/ntpdate time.nist.gov http://xn–5time-rg2hnkqin4vhsb6x8meq6d7yxa.nist.gov/ NTP服务器同步一次时间。 2. 使用ntpd作为…...

TortoiseGit提示No supported authentication methods available异常

TortoiseGit他属于git的客户端&#xff0c;可有可无&#xff0c;说白了就是将git命令给我们整理成了可直接操作的按钮。 本地代码是使用了SSH的方式去拉取的代码&#xff0c;但是通过TortoiseGit pull代码的时候发生了如下异常&#xff0c;而GitBash却可以正常使用。 TortoiseG…...

基于哈希表的用户管理系统

三大模块&#xff1a; - 哈希表模块 哈希函数 哈希表创建 哈希表销毁 - 用户管理模块 显示 增 删 改 查 - 文件模块 从文件导入用户信息 将用户信息导出至文件 1.哈希函数 //hash函数&#xff08;质数除余法&#xff09; int Hash_Fun1(data_type key){int pos key%P;…...

GO数组切片-线性数据结构

数据结构 类型 什么是类型 &#xff1f; 内存中的二进制数据本身没有什么区别&#xff0c;就是一串0或1的组合。 内存中有一个字节内容是0x63&#xff0c;他究竟是深恶 字符串?字符&#xff1f;还是整数&#xff1f; 本来0x63表示数字 但是文字必须编码成为0和1的组合 才能记…...

C++ STL学习之【优先级队列】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 &#x1f307;前言&#x1f3d9;️正文1、优先级队列的使用1.1、基本功能1.2、优先级模式切换1.3、相关题目 2、模拟…...

keepalived脑裂现象

Keepealived最常见的问题是会出现脑裂现象&#xff1a; Master一直发送心跳消息给backup主机&#xff0c;如果中间的链路突然断掉&#xff0c;backup主机将无法收到master主机发送过来的心跳消息&#xff08;也就是vrrp报文&#xff09;&#xff0c;backup这时候会立即抢占mas…...

[stable-diffusion-art] 指北-1

https://stable-diffusion-art.com/beginners-guide/https://stable-diffusion-art.com/beginners-guide/ Stable Diffusion教程目录 - 知乎按&#xff1a; 这个外国教程站中的文章太好了&#xff0c;数量适当&#xff0c;质量很高可惜博文只能按时间浏览&#xff0c;所以整理…...

「C/C++」C/C++预处理器

博客主页&#xff1a;何曾参静谧的博客 文章专栏&#xff1a;「C/C」C/C学习 目录 一、宏替换 #define1. 定义常量2. 定义函数3. 定义代码块 二、条件编译 #if1. 使用 #ifdef、 #else 和 #endif2. 使用 #if 、#elif、#else和 #endif 编译不同版本的代码3. 使用 #ifndef 和 #def…...

java语言入门教程文章

好的&#xff0c;以下是Java语言入门教程&#xff1a; Java是一种高级编程语言&#xff0c;由Sun Microsystems于1995年推出。Java语言具有良好的可移植性和安全性&#xff0c;因此被广泛应用于Web应用程序、移动应用程序、企业应用程序等各个领域。本教程将带领初学者快速入门…...

基于灰狼算法的极限学习机(ELM)回归预测-附代码

基于灰狼算法的极限学习机(ELM)回归预测 文章目录 基于灰狼算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于灰狼算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;本文利用灰狼算法对极限学习机进行优化&#xff0c;并…...

【五一创作】ERP实施-委外业务-委外采购业务

委外业务主要有两种业务形态&#xff1a;委外采购和工序外协&#xff0c;委外采购主要是在MM模块中实现&#xff0c;工序外协主要由PP模块实现&#xff0c;工序外协中的采购订单创建和采购收货由MM模块实现。 委外采购概念 委外采购&#xff0c;有些企业也称为带料委外或者分包…...

DAY 54 数据库基础

数据库的基本概念 数据&#xff08;Data&#xff09;&#xff1a; 描述事务的符号记录包括数字、文字、图形、图像、声音、档案记录以”记录“形式按统一的格式进行存储 表&#xff1a; 将不同的记录组织在一起用来存储具体数据 数据库&#xff1a; 表的集合&#xff0c;…...

网络编程 总结二

一、TCP TCP模型 1. TCP搭建相关函数&#xff1a; 套接字Socket 1&#xff09;Socket函数&#xff1a; 2&#xff09;bind 3&#xff09;listen 4&#xff09;accept 5&#xff09;recv 注意&#xff1a; 1> TCP中的recv 可以替换成read&#xff1b; 2>TCP中的…...

消息称苹果Type-C口充电未设MFi限制,iOS17将更新Find My服务

根据国外科技媒体 iMore 报道&#xff0c;基于消息源 analyst941 透露的信息&#xff0c;苹果公司目前并未开发 MFi 限制。 根据推文信息内容&#xff0c;两款 iPhone 15 机型的最高充电功率为 20W&#xff0c;而 iPhone 15 Pro 机型的最高支持 27W 充电。 此前古尔曼表示苹…...

设计模式——工厂模式(简单工厂、工厂方法、抽象工厂)

是什么&#xff1f; 工厂模式的目的是将创建对象的具体过程隐藏起来&#xff0c;从而达到更高的灵活性 工厂模式分为&#xff1a;简单工厂模式、工厂方法模式、抽象工厂模式&#xff1b; 为什么&#xff1f; 在Java中&#xff0c;万物皆是对象&#xff0c;我们在使用的时候…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

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

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