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

ICM20948 DMP代码详解(15)

接前一篇文章:ICM20948 DMP代码详解(14)

上一回开始对icm20948_sensor_setup函数中第3段代码即inv_icm20948_initialize函数进行解析。为了便于理解和回顾,再次贴出其源码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Setup.c中,如下:

int inv_icm20948_initialize(struct inv_icm20948 * s, const uint8_t *dmp3_image, uint32_t dmp3_image_size)
{if(s->serif.is_spi) {/* Hardware initialization */// No image to be loaded from flash, no pointer to pass.if (inv_icm20948_initialize_lower_driver(s, SERIAL_INTERFACE_SPI, dmp3_image, dmp3_image_size)) {return -1;}}else {/* Hardware initialization */// No image to be loaded from flash, no pointer to pass.if (inv_icm20948_initialize_lower_driver(s, SERIAL_INTERFACE_I2C, dmp3_image, dmp3_image_size)) {return -1;}}return 0;
}

该函数主要是调用了inv_icm20948_initialize_lower_driver,其在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948DataBaseDriver.c中,代码如下:

/** Should be called once on power up. Loads DMP3, initializes internal variables needed 
*   for other lower driver functions.
*/
int inv_icm20948_initialize_lower_driver(struct inv_icm20948 *s, enum SMARTSENSOR_SERIAL_INTERFACE type, const uint8_t *dmp3_image, uint32_t dmp3_image_size)
{int result = 0;static unsigned char data;// set static variables->sAllowLpEn = 1;s->s_compass_available = 0;// ICM20948 do not support the proximity sensor for the moment.// s_proximity_available variable is nerver changess->s_proximity_available = 0;// Set varialbes to default valuesmemset(&s->base_state, 0, sizeof(s->base_state));s->base_state.pwr_mgmt_1 = BIT_CLK_PLL;s->base_state.pwr_mgmt_2 = BIT_PWR_ACCEL_STBY | BIT_PWR_GYRO_STBY | BIT_PWR_PRESSURE_STBY;s->base_state.serial_interface = type;result |= inv_icm20948_read_mems_reg(s, REG_USER_CTRL, 1, &s->base_state.user_ctrl);result |= inv_icm20948_wakeup_mems(s);result |= inv_icm20948_read_mems_reg(s, REG_WHO_AM_I, 1, &data);/* secondary cycle mode should be set all the time */data = BIT_I2C_MST_CYCLE|BIT_ACCEL_CYCLE|BIT_GYRO_CYCLE;// Set default mode to low power moderesult |= inv_icm20948_set_lowpower_or_highperformance(s, 0);// Disable Ivory DMP.if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI)   s->base_state.user_ctrl = BIT_I2C_IF_DIS;elses->base_state.user_ctrl = 0;result |= inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);//Setup Ivory DMP.result |= inv_icm20948_load_firmware(s, dmp3_image, dmp3_image_size);if(result)return result;elses->base_state.firmware_loaded = 1;result |= inv_icm20948_set_dmp_address(s);// Turn off all sensors on DMP by default.//result |= dmp_set_data_output_control1(0);   // FIXME in DMP, these should be off by default.result |= dmp_icm20948_reset_control_registers(s);// set FIFO watermark to 80% of actual FIFO sizeresult |= dmp_icm20948_set_FIFO_watermark(s, 800);// Enable Interrupts.data = 0x2;result |= inv_icm20948_write_mems_reg(s, REG_INT_ENABLE, 1, &data); // Enable DMP Interruptdata = 0x1;result |= inv_icm20948_write_mems_reg(s, REG_INT_ENABLE_2, 1, &data); // Enable FIFO Overflow Interrupt// TRACKING : To have accelerometers datas and the interrupt without gyro enables.data = 0XE4;result |= inv_icm20948_write_mems_reg(s, REG_SINGLE_FIFO_PRIORITY_SEL, 1, &data);// Disable HW temp fixinv_icm20948_read_mems_reg(s, REG_HW_FIX_DISABLE,1,&data);data |= 0x08;inv_icm20948_write_mems_reg(s, REG_HW_FIX_DISABLE,1,&data);// Setup MEMs properties.s->base_state.accel_averaging = 1; //Change this value if higher sensor sample avergaing is required.s->base_state.gyro_averaging = 1;  //Change this value if higher sensor sample avergaing is required.inv_icm20948_set_gyro_divider(s, FIFO_DIVIDER);       //Initial sampling rate 1125Hz/19+1 = 56Hz.inv_icm20948_set_accel_divider(s, FIFO_DIVIDER);      //Initial sampling rate 1125Hz/19+1 = 56Hz.// Init the sample rate to 56 Hz for BAC,STEPC and B2Sdmp_icm20948_set_bac_rate(s, DMP_ALGO_FREQ_56);dmp_icm20948_set_b2s_rate(s, DMP_ALGO_FREQ_56);// FIFO Setup.result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_CFG, BIT_SINGLE_FIFO_CFG); // FIFO Config. fixme do once? burst write?result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_RST, 0x1f); // Reset all FIFOs.result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_RST, 0x1e); // Keep all but Gyro FIFO in reset.result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_EN, 0x0); // Slave FIFO turned off.result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_EN_2, 0x0); // Hardware FIFO turned off.s->base_state.lp_en_support = 1;if(s->base_state.lp_en_support == 1)inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 1);result |= inv_icm20948_sleep_mems(s);   return result;
}

上一回讲了函数一开始的成员设置,本回继续往下对该函数进行解析。当前来到以下代码片段:

	result |= inv_icm20948_read_mems_reg(s, REG_USER_CTRL, 1, &s->base_state.user_ctrl);

inv_icm20948_read_mems_reg函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Transport.c中,代码如下:

/**
*  @brief      Read data from a register on MEMs.
*  @param[in]  Register address
*  @param[in]  Length of data
*  @param[in]  Data to be written
*  @return     0 if successful.
*/
int inv_icm20948_read_mems_reg(struct inv_icm20948 *s, uint16_t reg, unsigned int length, unsigned char *data)
{int result = 0;unsigned int bytesRead = 0;unsigned char regOnly = (unsigned char)(reg & 0x7F);unsigned char i, dat[INV_MAX_SERIAL_READ];unsigned char power_state = inv_icm20948_get_chip_power_state(s);if((power_state & CHIP_AWAKE) == 0)   // Wake up chip since it is asleepresult = inv_icm20948_set_chip_power_state(s, CHIP_AWAKE, 1);if(check_reg_access_lp_disable(s, reg))   // Check if register needs LP_EN to be disabledresult |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 0);  //Disable LP_ENresult |= inv_set_bank(s, reg >> 7);while (bytesRead<length) {int thisLen = min(INV_MAX_SERIAL_READ, length-bytesRead);if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI) {result |= inv_icm20948_read_reg(s, regOnly+bytesRead, &dat[bytesRead], thisLen);} else {result |= inv_icm20948_read_reg(s, regOnly+bytesRead, &data[bytesRead],thisLen);}if (result)return result;bytesRead += thisLen;}if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI) {for (i=0; i< length; i++) {*data= dat[i];data++;}}if(check_reg_access_lp_disable(s, reg))    // Check if register needs LP_EN to be enabled  result |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 1);  //Enable LP_ENreturn result;
}

要弄懂这个函数,必须先弄清楚其中的几个函数。一个一个来看。

(1)inv_icm20948_get_chip_power_state函数

inv_icm20948_get_chip_power_state函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948DataBaseDriver.c中,代码如下:

/*!*******************************************************************************   @return    Current wake status of the Ivory chip.*******************************************************************************/
uint8_t inv_icm20948_get_chip_power_state(struct inv_icm20948 *s)
{return s->base_state.wake_state;
}

其实就是得到s->base_state.wake_state的值。前文书中曾讲到,在inv_icm20948_initialize_lower_driver函数中对于s->base_state整个进行了清零,因此这时的值必然是0。

(2)inv_icm20948_set_chip_power_state函数

inv_icm20948_set_chip_power_state函数也是在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948DataBaseDriver.c中,代码如下:

/*!*******************************************************************************   @brief     This function sets the power state of the Ivory chip *				loop*   @param[in] Function - CHIP_AWAKE, CHIP_LP_ENABLE*   @param[in] On/Off - The functions are enabled if previously disabled and disabled if previously enabled based on the value of On/Off.*******************************************************************************/ 
int inv_icm20948_set_chip_power_state(struct inv_icm20948 *s, unsigned char func, unsigned char on_off)
{int status = 0;switch(func) {case CHIP_AWAKE:    if(on_off){if((s->base_state.wake_state & CHIP_AWAKE) == 0) {// undo sleep_ens->base_state.pwr_mgmt_1 &= ~BIT_SLEEP;status = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);s->base_state.wake_state |= CHIP_AWAKE;inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds}} else {if(s->base_state.wake_state & CHIP_AWAKE) {// set sleep_ens->base_state.pwr_mgmt_1 |= BIT_SLEEP;status = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);s->base_state.wake_state &= ~CHIP_AWAKE;inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds}}break;case CHIP_LP_ENABLE:if(s->base_state.lp_en_support == 1) {if(on_off) {if( (inv_icm20948_get_lpen_control(s)) && ((s->base_state.wake_state & CHIP_LP_ENABLE) == 0)){s->base_state.pwr_mgmt_1 |= BIT_LP_EN; // lp_en ONstatus = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);s->base_state.wake_state |= CHIP_LP_ENABLE;}} else {if(s->base_state.wake_state & CHIP_LP_ENABLE){s->base_state.pwr_mgmt_1 &= ~BIT_LP_EN; // lp_en offstatus = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);s->base_state.wake_state &= ~CHIP_LP_ENABLE;inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds}}}break;default:break;}// end switchreturn status;
}

这要结合inv_icm20948_read_mems_reg函数中的调用来看,代码片段如下:

	if((power_state & CHIP_AWAKE) == 0)   // Wake up chip since it is asleepresult = inv_icm20948_set_chip_power_state(s, CHIP_AWAKE, 1);if(check_reg_access_lp_disable(s, reg))   // Check if register needs LP_EN to be disabledresult |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 0);  //Disable LP_EN

一共两次调用,一次是CHIP_AWAKE,另一次是CHIP_LP_ENABLE。正好对应inv_icm20948_set_chip_power_state函数中switch的两个case。依次看一下这两个分支:

1)case CHIP_AWAKE

相应代码片段如下:

		case CHIP_AWAKE:    if(on_off){if((s->base_state.wake_state & CHIP_AWAKE) == 0) {// undo sleep_ens->base_state.pwr_mgmt_1 &= ~BIT_SLEEP;status = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);s->base_state.wake_state |= CHIP_AWAKE;inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds}} else {if(s->base_state.wake_state & CHIP_AWAKE) {// set sleep_ens->base_state.pwr_mgmt_1 |= BIT_SLEEP;status = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);s->base_state.wake_state &= ~CHIP_AWAKE;inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds}}break;

如果inv_icm20948_set_chip_power_state函数的第3个参数unsigned char on_off传入的值为1,同时状态与本次设置不同,则清除s->base_state.pwr_mgmt_1中的BIT_SLEEP位;写入ICM20948的REG_PWR_MGMT_1寄存器;之后将s->base_state.wake_state中的CHIP_AWAKE置位,并延时100us。

如果on_off传入的值为0,同时状态与本次设置不同,则置位s->base_state.pwr_mgmt_1中的BIT_SLEEP位;写入ICM20948的REG_PWR_MGMT_1寄存器;之后清除s->base_state.wake_state中的CHIP_AWAKE位,并延时100us。

2)case CHIP_LP_ENABLE

相应代码片段如下:

		case CHIP_LP_ENABLE:if(s->base_state.lp_en_support == 1) {if(on_off) {if( (inv_icm20948_get_lpen_control(s)) && ((s->base_state.wake_state & CHIP_LP_ENABLE) == 0)){s->base_state.pwr_mgmt_1 |= BIT_LP_EN; // lp_en ONstatus = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);s->base_state.wake_state |= CHIP_LP_ENABLE;}} else {if(s->base_state.wake_state & CHIP_LP_ENABLE){s->base_state.pwr_mgmt_1 &= ~BIT_LP_EN; // lp_en offstatus = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);s->base_state.wake_state &= ~CHIP_LP_ENABLE;inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds}}}break;

在s->base_state.lp_en_support设置的情况下,判断体代码才有效。此时并未设置过,还是之前在inv_icm20948_initialize_lower_driver函数中设置的清零状态。

不过这里也先解析一下,免得以后还得回来再解析。

如果inv_icm20948_set_chip_power_state函数的第3个参数unsigned char on_off传入的值为1,同时状态与本次设置不同,则置位s->base_state.pwr_mgmt_1中的BIT_LP_EN位;写入ICM20948的REG_PWR_MGMT_1寄存器;之后将s->base_state.wake_state中的CHIP_LP_ENABLE置位,并延时100us。

如果on_off传入的值为0,同时状态与本次设置不同,则清除s->base_state.pwr_mgmt_1中的BIT_LP_EN位;写入ICM20948的REG_PWR_MGMT_1寄存器;之后清除s->base_state.wake_state中的CHIP_LP_ENABLE位,并延时100us。

inv_icm20948_set_chip_power_state函数中还有三个函数要讲一下,分别是:

1)inv_icm20948_write_single_mems_reg_core函数

2)inv_icm20948_get_lpen_control函数

3)inv_icm20948_sleep_100us函数

对于这三个函数的解析,请看下回。

相关文章:

ICM20948 DMP代码详解(15)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;14&#xff09; 上一回开始对icm20948_sensor_setup函数中第3段代码即inv_icm20948_initialize函数进行解析。为了便于理解和回顾&#xff0c;再次贴出其源码&#xff0c;在EMD-Core\sources\Invn\Devices\Drivers\IC…...

NC 和为K的连续子数组

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个无序…...

JS设计模式之装饰者模式:优雅的给对象增添“魔法”

引言 在前端开发中&#xff0c;我们经常会遇到需要在不修改已有代码的基础上给对象添加新的行为或功能的情况。而传统的继承方式并不适合这种需求&#xff0c;因为继承会导致类的数量急剧增加&#xff0c;且每一个子类都会固定地实现一种特定的功能扩展。 装饰者模式则提供了…...

准备好了吗?JAVA从业AI开发的学习路线详解

作为一个拥有扎实 Java 基础的人&#xff0c;想要涉足人工智能&#xff08;AI&#xff09;应用开发&#xff0c;你已经在编程能力方面打下了很好的基础。Java 是一种通用的、强类型的语言&#xff0c;非常适合于开发高性能的应用程序&#xff0c;尤其是在后端服务和大规模分布式…...

神经网络通俗理解学习笔记(1)

神经网络通俗理解学习笔记&#xff08;1&#xff09; 神经网络原理激活函数前向传播和反向传播多层感知机代码实现加载数据网络结构损失函数优化器训练测试保存 回归问题一元线性回归多元线性回归多项式回归 线性回归代码实现数据生成设置超参数初始化参数可视化Pytorch模型实现…...

有n个人,他们需要分配m元钱(m>n),每个人至少分到1元钱,且每个人分到的钱数必须是整数。请问有多少种分配方案?

分配方案 描述 有n个人&#xff0c;他们需要分配m元钱(m>n)&#xff0c;每个人至少分到1元钱&#xff0c;且每个人分到的钱数必须是整数。请问有多少种分配方案? 输入 一行&#xff0c;两个整数&#xff0c;分别是人数n与钱数m&#xff0c;用一个空格隔开。 输出 一行&am…...

光耦——创新引擎 助推中国经济高质量发展

近年来&#xff0c;中国经济正处于转型升级的关键时期&#xff0c;高质量发展成为经济发展的重要目标。在这一伟大征程中&#xff0c;光耦作为一种关键性的电子元器件&#xff0c;正在发挥着重要的作用&#xff0c;助力中国经济迈向更加光明的未来。 光耦概念及工作原理 ▲光耦…...

Go 中 RPC 的使用教程

前言 RPC&#xff08;Remote Procedure Call&#xff09;是一种允许程序调用远程服务器上函数的方法&#xff0c;调用过程对于开发者来说像是调用本地函数一样方便。Go 语言自带了强大的 net/rpc 库&#xff0c;能够让开发者轻松实现基于 Go 的 RPC 服务。本文将介绍 Go 中 RP…...

挖耳勺可以伸进耳朵多深?安全可视挖耳勺推荐!

一般来说&#xff0c;挖耳勺不应该伸进耳朵太深&#xff0c;外耳道的长度大约在2.5厘米到3.5厘米之间&#xff0c;但不建议将挖耳勺伸进超过外耳道外1/3的深度&#xff0c;也就是大概1厘米左右较为安全。因为如果伸得太深&#xff0c;很容易损伤外耳道皮肤&#xff0c;引起疼痛…...

SuperMap GIS基础产品FAQ集锦(20240911)

一、SuperMap iObjects Java 问题1&#xff1a;【iObject Python】Objects Python产品有哪些能力特性和优势&#xff1f; 11.2.0 【解决办法】iObjects Python产品包含传统GIS功能&#xff08;基于iObjects Java扩展的功能接口&#xff09;和AI GIS功能模块。 其中传统GIS功能…...

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compo…...

ChatGPT提示词优化大师使用指南

我希望你成为我的ChatGPT提示词优化大师。 您的目标是帮助我根据自己的需要制定尽可能最好的提示。 你提供的提示应该是站在我向ChatGPT发起请求的角度来写的。我的初始提示词如下&#xff1a;此处填入你的初始提示词 ChatGPT提示词生成器 我希望你充当提示词生成器。 比如&…...

计算机毕业设计 智能推荐旅游平台 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

【拥抱AI】基于多种数据分段工具的优缺点分析

最近在深入了解RAG方面的知识&#xff0c;其中数据清洗和数据分段是创建知识库的重要步骤。数据清洗目前暂时选用了MinerU&#xff0c;然后就需要针对数据分段进行选型。 以下是我了解到的几种数据分段工具&#xff0c;简单总结了一下它们的优缺点&#xff0c;权当笔记分享&am…...

在 Windows 系统上,文件传输到虚拟机(VM)可以通过 VS Code 的图形界面(GUI)或命令行工具进行操作

在 Windows 系统上&#xff0c;文件传输到虚拟机&#xff08;VM&#xff09;可以通过 VS Code 的图形界面&#xff08;GUI&#xff09;或命令行工具进行操作。以下是几种方法&#xff1a; ### 方法 1: 使用 VS Code 图形界面 1. **连接到远程 VM**&#xff1a; - 在 VS Cod…...

kafka的主要功能

Apache Kafka 是一个分布式流处理平台&#xff0c;它最初由 LinkedIn 开发&#xff0c;后来捐赠给了 Apache Software Foundation&#xff0c;并成为了 Apache 的顶级项目。Kafka 设计用于处理实时数据流&#xff0c;并且提供了高性能、可扩展性和持久性。下面是 Kafka 的主要功…...

vue3中provide和inject详解

provide和inject是什么 provide 和 inject 是 Vue.js 框架中提供的一种依赖注入机制。这种机制允许一个祖先组件&#xff08;提供者&#xff09;向其所有子孙组件&#xff08;使用者&#xff09;提供数据或方法&#xff0c;而不需要通过逐层组件传递属性&#xff08;props&…...

相约华中科技大学,移动云技术论坛来了!NineData创始人CEO叶正盛将分享《数据库全球实时传输技术实践》的主题演讲

2024年9月12日&#xff0c;中国移动云能力中心将在华中科技大学举办“智算浪潮下数据库发展论坛”&#xff0c;共同探讨数据库技术与应用的创新&#xff0c;分享算力网络时代数据库未来发展的洞见。本次论坛&#xff0c;NineData 创始人&CEO 叶正盛受邀参会&#xff0c;并来…...

华为 昇腾 310P 系列 AI 处理器支持 140Tops 的 AI 算力。

1、产品简介 模组是基于昇腾 310P 系列 AI 处理器设计而成&#xff0c;可实现图像、视频等多种数据分析 与推理计算。超强的视频编解码能力以及支持 140Tops 的 AI 算力。在边缘侧及端侧的嵌入式计算 领域&#xff0c;有着极高的性价比&#xff0c;具有超强算力、 超高能效、…...

基于单片机的小型生态鱼缸控制器设计

本设计以STC89C52单片机为核心&#xff0c;利用DS18B20温度传感器和LCD1602液晶显示器实时采集和显示当前环境温度&#xff0c;并根据与预设温度阈值的比较结果控制加热棒或风扇进行加热或制冷操作。此外&#xff0c;该控制器还利用DS1302完成计时功能&#xff0c;在预设时间点…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...