【NXP-MCXA153】SPI驱动移植
介绍
SPI总线由摩托罗拉公司
开发,是一种全双工同步串行总线
,由四个IO口组成:CS、SCLK、MISO、MOSI;通常用于CPU和外设之间进行通信,常见的SPI总线设备有:TFT LCD、QSPI FLASH、时钟模块、IMU等;NXP-MCXA153
开发板上集成了两路SPI总线,本次实验将重点介绍RT-Thread系统中SPI BSP驱动的移植过程
移植流程
以SPI0为例
① 在board里边添加相应的外设:配置spi0外设为复位状态、设置GPIO引脚功能
② 添加相应的Kconfig开关,用以指示相应的外设开启与关闭(本质是通过宏定义或者条件编译的方式)
③ 根据SDK_2_14_2_FRDM-MCXA153提供的spi示例工程编写spi总线驱动,需要实现几个关键的函数
- rt_hw_spi_init
- spi_configure
- spixfer
④ 添加相应的库文件依赖:fsl_lpspi.c、fsl_lpspi_edma.c
引脚对应关系
序号 | GPIO | function |
---|---|---|
1 | P1_3 | CS |
2 | P1_1 | SCLK |
3 | P1_2 | MISO |
4 | P1_0 | MOSI |
驱动文件
board.c
在rt_hw_board_init
函数里加入以下代码
edma_config_t userConfig = {0};
EDMA_GetDefaultConfig(&userConfig);
EDMA_Init(DMA0, &userConfig);
pin_mux.c
在BOARD_InitPins
函数里加入以下代码
#ifdef BSP_USING_SPI0RESET_ReleasePeripheralReset(kLPSPI0_RST_SHIFT_RSTn);const port_pin_config_t port1_0_pin56_config = {/* Internal pull-up/down resistor is disabled */kPORT_PullDisable,/* Low internal pull resistor value is selected. */kPORT_LowPullResistor,/* Fast slew rate is configured */kPORT_FastSlewRate,/* Passive input filter is disabled */kPORT_PassiveFilterDisable,/* Open drain output is disabled */kPORT_OpenDrainDisable,/* Low drive strength is configured */kPORT_LowDriveStrength,/* Normal drive strength is configured */kPORT_NormalDriveStrength,/* Pin is configured as LPSPI0_SDO */kPORT_MuxAlt2,/* Digital input enabled */kPORT_InputBufferEnable,/* Digital input is not inverted */kPORT_InputNormal,/* Pin Control Register fields [15:0] are not locked */kPORT_UnlockRegister};/* PORT1_0 (pin 56) is configured as LPSPI0_SDO */PORT_SetPinConfig(PORT1, 0U, &port1_0_pin56_config);const port_pin_config_t port1_1_pin57_config = {/* Internal pull-up/down resistor is disabled */kPORT_PullDisable,/* Low internal pull resistor value is selected. */kPORT_LowPullResistor,/* Fast slew rate is configured */kPORT_FastSlewRate,/* Passive input filter is disabled */kPORT_PassiveFilterDisable,/* Open drain output is disabled */kPORT_OpenDrainDisable,/* Low drive strength is configured */kPORT_LowDriveStrength,/* Normal drive strength is configured */kPORT_NormalDriveStrength,/* Pin is configured as LPSPI0_SCK */kPORT_MuxAlt2,/* Digital input enabled */kPORT_InputBufferEnable,/* Digital input is not inverted */kPORT_InputNormal,/* Pin Control Register fields [15:0] are not locked */kPORT_UnlockRegister};/* PORT1_1 (pin 57) is configured as LPSPI0_SCK */PORT_SetPinConfig(PORT1, 1U, &port1_1_pin57_config);const port_pin_config_t port1_2_pin58_config = {/* Internal pull-up/down resistor is disabled */kPORT_PullDisable,/* Low internal pull resistor value is selected. */kPORT_LowPullResistor,/* Fast slew rate is configured */kPORT_FastSlewRate,/* Passive input filter is disabled */kPORT_PassiveFilterDisable,/* Open drain output is disabled */kPORT_OpenDrainDisable,/* Low drive strength is configured */kPORT_LowDriveStrength,/* Normal drive strength is configured */kPORT_NormalDriveStrength,/* Pin is configured as LPSPI0_SDI */kPORT_MuxAlt2,/* Digital input enabled */kPORT_InputBufferEnable,/* Digital input is not inverted */kPORT_InputNormal,/* Pin Control Register fields [15:0] are not locked */kPORT_UnlockRegister};/* PORT1_2 (pin 58) is configured as LPSPI0_SDI */PORT_SetPinConfig(PORT1, 2U, &port1_2_pin58_config);const port_pin_config_t port1_3_pin59_config = {/* Internal pull-up/down resistor is disabled */kPORT_PullDisable,/* Low internal pull resistor value is selected. */kPORT_LowPullResistor,/* Fast slew rate is configured */kPORT_FastSlewRate,/* Passive input filter is disabled */kPORT_PassiveFilterDisable,/* Open drain output is disabled */kPORT_OpenDrainDisable,/* Low drive strength is configured */kPORT_LowDriveStrength,/* Normal drive strength is configured */kPORT_NormalDriveStrength,/* Pin is configured as LPSPI0_PCS0 */kPORT_MuxAlt2,/* Digital input enabled */kPORT_InputBufferEnable,/* Digital input is not inverted */kPORT_InputNormal,/* Pin Control Register fields [15:0] are not locked */kPORT_UnlockRegister};/* PORT1_3 (pin 59) is configured as LPSPI0_PCS0 */PORT_SetPinConfig(PORT1, 3U, &port1_3_pin59_config);
#endif
board/Kconfig
加入SPI0相关配置
menuconfig BSP_USING_SPIconfig BSP_USING_SPIbool "Enable SPI"select RT_USING_SPIdefault yif BSP_USING_SPIconfig BSP_USING_SPI0bool "Enable SPI0"default endif
drv_spi.c
spi驱动层修改如下
/** Copyright (c) 2006-2024, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date Author Notes* 2024-08-3 hywing The first version for MCXA*/
#include "rtdevice.h"
#include "drv_spi.h"
#include "fsl_common.h"
#include "fsl_lpspi.h"
#include "fsl_lpspi_edma.h"#define DMA_MAX_TRANSFER_COUNT (32767)enum
{
#ifdef BSP_USING_SPI0SPI1_INDEX,
#endif
};struct lpc_spi
{struct rt_spi_bus parent;LPSPI_Type *LPSPIx;clock_attach_id_t clock_attach_id;clock_div_name_t clock_div_name;clock_name_t clock_name;DMA_Type *DMAx;uint8_t tx_dma_chl;uint8_t rx_dma_chl;edma_handle_t dma_tx_handle;edma_handle_t dma_rx_handle;dma_request_source_t tx_dma_request;dma_request_source_t rx_dma_request;lpspi_master_edma_handle_t spi_dma_handle;rt_sem_t sem;char *name;
};static struct lpc_spi lpc_obj[] =
{
#ifdef BSP_USING_SPI0{.LPSPIx = LPSPI0,.clock_attach_id = kFRO12M_to_LPSPI0,.clock_div_name = kCLOCK_DivLPSPI0,.clock_name = kCLOCK_Fro12M,.tx_dma_request = kDma0RequestLPSPI0Tx,.rx_dma_request = kDma0RequestLPSPI0Rx,.DMAx = DMA0,.tx_dma_chl = 0,.rx_dma_chl = 1,.name = "spi0",},
#endif
};struct lpc_sw_spi_cs
{rt_uint32_t pin;
};rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin)
{rt_err_t ret = RT_EOK;struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));struct lpc_sw_spi_cs *cs_pin = (struct lpc_sw_spi_cs *)rt_malloc(sizeof(struct lpc_sw_spi_cs));cs_pin->pin = pin;rt_pin_mode(pin, PIN_MODE_OUTPUT);rt_pin_write(pin, PIN_HIGH);ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);return ret;
}static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
{rt_err_t ret = RT_EOK;
// struct lpc_spi *spi = RT_NULL;
// spi = (struct lpc_spi *)(device->bus->parent.user_data);
// ret = lpc_spi_init(spi->SPIx, cfg);return ret;
}static void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, status_t status, void *userData)
{struct lpc_spi *spi = (struct lpc_spi *)userData;rt_sem_release(spi->sem);}static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
{int i;lpspi_transfer_t transfer = {0};RT_ASSERT(device != RT_NULL);RT_ASSERT(device->bus != RT_NULL);RT_ASSERT(device->bus->parent.user_data != RT_NULL);struct lpc_spi *spi = (struct lpc_spi *)(device->bus->parent.user_data);struct lpc_sw_spi_cs *cs = device->parent.user_data;if (message->cs_take){rt_pin_write(cs->pin, PIN_LOW);}transfer.dataSize = message->length;transfer.rxData = (uint8_t *)(message->recv_buf);transfer.txData = (uint8_t *)(message->send_buf);// if(message->length < MAX_DMA_TRANSFER_SIZE)if (0){LPSPI_MasterTransferBlocking(spi->LPSPIx, &transfer);}else{uint32_t block, remain;block = message->length / DMA_MAX_TRANSFER_COUNT;remain = message->length % DMA_MAX_TRANSFER_COUNT;for (i = 0; i < block; i++){transfer.dataSize = DMA_MAX_TRANSFER_COUNT;if (message->recv_buf) transfer.rxData = (uint8_t *)(message->recv_buf + i * DMA_MAX_TRANSFER_COUNT);if (message->send_buf) transfer.txData = (uint8_t *)(message->send_buf + i * DMA_MAX_TRANSFER_COUNT);LPSPI_MasterTransferEDMA(spi->LPSPIx, &spi->spi_dma_handle, &transfer);rt_sem_take(spi->sem, RT_WAITING_FOREVER);}if (remain){transfer.dataSize = remain;if (message->recv_buf) transfer.rxData = (uint8_t *)(message->recv_buf + i * DMA_MAX_TRANSFER_COUNT);if (message->send_buf) transfer.txData = (uint8_t *)(message->send_buf + i * DMA_MAX_TRANSFER_COUNT);LPSPI_MasterTransferEDMA(spi->LPSPIx, &spi->spi_dma_handle, &transfer);rt_sem_take(spi->sem, RT_WAITING_FOREVER);}}if (message->cs_release){rt_pin_write(cs->pin, PIN_HIGH);}return message->length;
}static struct rt_spi_ops lpc_spi_ops =
{.configure = spi_configure,.xfer = spixfer
};int rt_hw_spi_init(void)
{int i;for (i = 0; i < ARRAY_SIZE(lpc_obj); i++){CLOCK_SetClockDiv(lpc_obj[i].clock_div_name, 1u);CLOCK_AttachClk(lpc_obj[i].clock_attach_id);lpc_obj[i].parent.parent.user_data = &lpc_obj[i];lpc_obj[i].sem = rt_sem_create("sem_spi", 0, RT_IPC_FLAG_FIFO);lpspi_master_config_t masterConfig;LPSPI_MasterGetDefaultConfig(&masterConfig);masterConfig.baudRate = 12 * 1000 * 1000;masterConfig.pcsToSckDelayInNanoSec = 1000000000U / masterConfig.baudRate * 1U;masterConfig.lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig.baudRate * 1U;masterConfig.betweenTransferDelayInNanoSec = 1000000000U / masterConfig.baudRate * 1U;LPSPI_MasterInit(lpc_obj[i].LPSPIx, &masterConfig, CLOCK_GetFreq(lpc_obj[i].clock_name));EDMA_CreateHandle(&lpc_obj[i].dma_tx_handle, lpc_obj[i].DMAx, lpc_obj[i].tx_dma_chl);EDMA_CreateHandle(&lpc_obj[i].dma_rx_handle, lpc_obj[i].DMAx, lpc_obj[i].rx_dma_chl);EDMA_SetChannelMux(lpc_obj[i].DMAx, lpc_obj[i].tx_dma_chl, lpc_obj[i].tx_dma_request);EDMA_SetChannelMux(lpc_obj[i].DMAx, lpc_obj[i].rx_dma_chl, lpc_obj[i].rx_dma_request);LPSPI_MasterTransferCreateHandleEDMA(lpc_obj[i].LPSPIx, &lpc_obj[i].spi_dma_handle, LPSPI_MasterUserCallback, &lpc_obj[i], &lpc_obj[i].dma_rx_handle, &lpc_obj[i].dma_tx_handle);rt_spi_bus_register(&lpc_obj[i].parent, lpc_obj[i].name, &lpc_spi_ops);}return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_spi_init);
SConscript
在Libraries/MCXA153/SConscript
文件里边加上以下代码
if GetDepend('BSP_USING_SPI'):src += ['MCXA153/drivers/fsl_lpspi.c']src += ['MCXA153/drivers/fsl_lpspi_edma.c']
测试用例
打开menuconfig使能spi0驱动
短接MISO和MOSI引脚(P1_0和P1_2)进行自发自收测试
测试程序
#include <rtthread.h>
#include "rtdevice.h"
#include "drv_spi.h"#define SPI_BUS_NAME "spi0"
#define SPI_DEV_NAME "spi00" static struct rt_spi_device *spi_device;static void spi_sample(void)
{ rt_err_t result; struct rt_spi_configuration cfg; uint8_t tx_buf[] = "Hello RT-Thread!"; uint8_t rx_buf[sizeof(tx_buf)]; rt_base_t cs = 1*32+3; rt_hw_spi_device_attach(SPI_BUS_NAME, SPI_DEV_NAME, cs);/* »ñÈ¡SPIÉ豸 */spi_device = (struct rt_spi_device *)rt_device_find(SPI_DEV_NAME);if (!spi_device){rt_kprintf("can't find %s device!\n", SPI_BUS_NAME);}/* ÅäÖÃSPIÉ豸 */cfg.data_width = 8;cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;cfg.max_hz = 12* 1000 * 1000;/* ÉèÖÃSPIÉ豸 */rt_spi_configure(spi_device, &cfg); result = rt_spi_transfer(spi_device, tx_buf, rx_buf, sizeof(tx_buf)); if (result == sizeof(tx_buf)) { rt_kprintf("Send: %s\n", tx_buf); rt_kprintf("Received: %s\n", rx_buf); } else { rt_kprintf("spi transfer failed! error code: %d\n", result); }
} int main(void)
{ spi_sample(); return 0;
}
运行结果
总结
- 另外,你也可以安装
MCUXpresso Config Tools v16
,通过图形方式配置时钟树、GPIO复用 - 完整的BSP驱动代码可以在RT-Thread的仓库找到
相关文章:

【NXP-MCXA153】SPI驱动移植
介绍 SPI总线由摩托罗拉公司开发,是一种全双工同步串行总线,由四个IO口组成:CS、SCLK、MISO、MOSI;通常用于CPU和外设之间进行通信,常见的SPI总线设备有:TFT LCD、QSPI FLASH、时钟模块、IMU等;…...
Python if 编程题|Python一对一辅导教学
你好,我是悦创。 以下为 if 编程练习题: 1. 奇数乘积问题 题目描述: 编写一个程序,判断给定的两个整数是否都是奇数,如果是,返回它们的乘积;如果不是,返回它们的和。输入: num1, num2输出: n…...

机器学习——第十一章 特征选择与稀疏学习
11.1 子集搜索与评价 对一个学习任务来说,给定属性集,其中有些属性可能很关键、很有用,另一些属性则可能没什么用.我们将属性称为"特征" (feature) ,对当前学习任务有用的属性称为"相关特征" (relevant featu…...

花式表演无人机技术详解
花式表演无人机作为现代科技与艺术融合的典范,以其独特的飞行姿态、绚烂的灯光效果及精准的控制能力,在各类庆典、体育赛事、音乐会等合中展现出非凡的魅力。本文将从以下几个方面对花式表演无人机技术进行详细解析。 1. 三维建模与编程 在花式表演无人…...
服务器那点事--防火墙
Linux服务器那点事--防火墙 Ⅰ、开启关闭Ⅱ、放开端口 Ⅰ、开启关闭 禁止防火墙开机自启systemctl disable firewalld 关闭防火墙systemctl stop firewalld 查看防火墙状态systemctl status firewalldⅡ、放开端口 例如:放开3306端口 设置放开3306端口 [rootbpm2…...

C:每日一题:单身狗
一、题目: 在一个整型数组中,只有一个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。 整型数组 int arr[ ] {1,1,2,2,3,4,4} 二、思路分析: 1.,明确目标,选择…...

SQL之使用存储过程循环插入数据
1、已经创建了任务日志表 CREATE TABLE t_task_log (id bigint NOT NULL AUTO_INCREMENT,task_id bigint NOT NULL COMMENT 任务ID,read_time bigint NOT NULL COMMENT 单位秒,读取耗时,write_time bigint NOT NULL COMMENT 单位秒,写入耗时,read_size …...

智慧楼宇公厕系统小程序,提高卫生间管理使用效率
在当今的智慧楼宇中,公厕系统的管理和使用效率成为了衡量楼宇品质的重要指标之一。智慧楼宇公厕系统小程序的出现,为解决这一问题带来了全新的思路和方法。 一、检查公厕环境数据 智慧公厕系统不仅关注如厕的基本需求,还注重提升如厕环境的质…...
深度剖析:云数据库与传统数据库的显著差异
【若您对以下内容感兴趣,欢迎关注或联系我们】 在当今数字化时代,数据库技术不断演进,云数据库和传统数据库作为两种主要的数据库类型,在多个方面存在明显区别。下面我们将深入探讨这些差异。 一、部署方式 云数据库࿱…...

# 利刃出鞘_Tomcat 核心原理解析(六)
利刃出鞘_Tomcat 核心原理解析(六) 一、Tomcat专题 - 内容 1、Web 应用配置 2、Tomcat 管理配置 3、JVM 配置 4、Tomcat 集群 5、Tomcat 安全 6、Tomcat 性能调优 7、Tomcat 附加功能。 二、Tomcat专题 - Web应用配置介绍 1、Web.xml 配置文件…...

双亲委派模型
优质博文:IT-BLOG-CN 虚拟机设计团队把类加载阶段中的 “通过一个类的全限定名来获取描述此类的二进制字节流” 这个动作放到 Java虚拟机外部去实现,以便应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。 从Java虚拟机…...
Linux下ETCD安装、配置、命令
目录 1. ETCD简介 2. ETCD的安装 2.1 准备环境 2.2 下载ETCD 2.3 解压和移动文件 2.4 验证安装 3. ETCD的配置 3.1 基本配置 3.2 配置文件 3.3 集群配置 4. ETCD的常用命令 4.1 插入键值对 4.2 读取键值对 4.3 删除键值对 4.4 监视键的变化 4.5 列出所有键值 …...

【QT】静态库与动态库
文章目录 开始之前一、静态库(static Library)定义使用场景特点程序示例 二、动态库(dynamic Library)定义使用场景特点。程序示例第二种调用 开始之前 测试环境:Qt 5.15.2 Based on Qt 6.4.3(MSVC 2019, x86_64) 操作系统:Windows11 专业版 编程语言&am…...

R的行和列命名和类型的转换
下面内容摘录自: 4章8节:用R做数据重塑,行列命名和数据类型转换-CSDN博客 欢迎订阅我们专栏 一、行和列命名 在数据科学和统计分析中,命名是组织和管理数据的一个重要部分。尤其是在处理复杂的多维数据集时,为行和列命…...

某通用系统0day审计过程
前言 代码审计篇章都是自己跟几个师傅们一起审计的1day或者0day(当然都是小公司较为简单),禁止未经允许进行转载,发布到博客的用意主要是想跟师傅们能够交流下审计的思路,毕竟审计的思路也是有说法的,或者是相互源码共享也OK&…...
windows C++-高级并发和异步(一)
并发和异步的由来已经很久了,对于从xp开始编程的人来说,这个概念并不陌生,但问题在于,在早期,这两个技术被认为是操作系统提供的服务,而非编程语言的概念。 事情发生变化的原因,和C标准不断变迁…...

Java FX 学习
声明:参考视频 一. Stage与Scene 舞台与场景:JavaFX应用程序将Ul容器定义为舞台(Stage)与场景(Scene)Stage类是顶级容器,它对应于窗体,其内容由Scene决定。Scene类是所有可视化内容…...

【走迷宫】
题目 DFS代码 #include<bits/stdc.h> using namespace std; const int N 110; int matrix[N][N]; int n, m; int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, -1}; int dis[N][N]; void dfs(int x, int y, int cnt) {if(cnt > dis[n-1][m-1]) return;if(x n-1 &&a…...
linux(debian)迁移var数据到已分配逻辑卷的物理盘
文章目录 0 背景1 查看当前情况1.1 查看磁盘空间1.2 列出所有可用块设备的信息,而且还能显示他们之间的依赖关系1.3 查看可用磁盘1.4 查看卷组 2 卷组中创建逻辑卷3 创建文件系统4 创建临时文件夹并挂载,然后备份源文件5 修改开机挂载配置5.1 查看原配置…...

【产品那些事】什么是应用程序安全态势管理(ASPM)?
文章目录 前言当前应用安全(AppSec)推进遇到的问题关于ASPM的定义 为什么需要ASPM:B端客户核心需求ASPM产品关键策略理想状态下的ASPMASPM与CSPM的区别国内外产品参考 前言 随着现代软件开发实践的快速演变,特别是在敏捷开发和 DevOps 的推动下…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...