技巧小结:外部总线访问FPGA寄存器
概述
需求:stm32
的fsmc
总线挂载fpga
,stm32
需要访问fpga
内部寄存器
1、分散加载文件将变量存放到指定地址即FPGA寄存器地址
sct
文件指定变量存储地址,从而可以直接访问外设,(28335
也可以,不过用的是cmd文件
),stm32
可以将变量指定存放到0x6000 0000
地址即外部总线对应的这个地址,而外部总线上这段地址可以是挂载的fpga
,也可以是sram
等,如果是fpga
,fpga会
提供寄存器供stm32
访问,因此这样访问fpga
十分方便;典型代码:
1、修改sct文件新建段FPGA_ADC_REG 0x60000000 UNINIT 0x00000010 { ; adc data*(.fpga_adc_reg) ; 确保段名fpga_adc_reg与代码中一致}
2、源代码定义变量并指定存放地址为段__attribute__((section(".fpga_adc_reg"))) volatile ST_REG ADC_REG[16];
3、直接访问变量就是访问FPGA寄存器ADC_REG[i].all=i;
2、将FPGA寄存器基地址按照指定的结构体形式进行强制类型转换
- 还有一种是定一个一个大的结构体变量
struct fpga
,其内部变量的排布格式和fpga
提供的一致,然后再将0x6000 0000
地址强转为struct fpga
类型,对结构体成员的访问也就是对fpga
的访问了,这种形式类似于很多stm32
底层外设驱动开发格式;典型代码:
1、定义类型
typedef struct
{ST_REG ST_ADC_REG[16]; // adc地址范围0x6000 0000 ~ 0x6000 0010ST_REG ST_PWM_REG[16]; // pwm地址范围0x6000 0010 ~ 0x6000 0020}ST_FPGA_REG; //FPGA所有的寄存器按此结构和顺序排布,如果有空隙则用rsd占位
2、强转类型
#define fpga_all_regs (*(volatile ST_FPGA_REG*)0x60000000)
3、访问地址
fpga_all_regs.ST_ADC_REG[i].all=i;
3、指针单独访问FPGA的每个寄存器地址
- 还有一种就是更简单的:地址全部都用宏定义,因为
fpga
挂在0x6000 0000
地址,每个fpga
的变量都是基于此地址偏移,stm32
可以直接访问地址,就可以拿到变量值。需要宏定义基地址、偏移地址等等。典型代码:
1、宏定义地址
#define FPGA_ADDR (0x60000000)
#define FPGA_ADC_OFFSET (0x0)
#define FPGA_ADC_BASE (unsigned char*)(FPGA_ADDR+FPGA_ADC_OFFSET)
2、访问地址*(FPGA_ADC_BASE+i) = i;
一、FSMC模块
1、FSMC控制寄存器
2、FSMC表示的地址范围:
二、访问方式
1、分散加载sct文件指定变量存储地址
sct
文件指定变量存储地址,从而可以直接访问外设,(28335
也可以,不过用的是cmd文件
),stm32
可以将变量指定存放到0x6000 0000
地址即外部总线对应的这个地址,而外部总线上这段地址可以是挂载的fpga
,也可以是sram
等,如果是fpga
,fpga会
提供寄存器供stm32
访问,因此这样访问fpga
十分方便;
代码例子:
(1)修改分散加载文件生成两个section(段区域)
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x08000000 0x00100000 { ; load region size_regionER_IROM1 0x08000000 0x00100000 { ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)}RW_IRAM1 0x20000000 0x00020000 {.ANY (+RW +ZI)}FPGA_ADC_REG 0x60000000 UNINIT 0x00000010 { ; adc data*(.fpga_adc_reg) ; 确保段名fpga_adc_reg与代码中一致}FPGA_PWM_REG 0x60000010 UNINIT 0x00000010 { ; pwm data*(.fpga_pwm_reg) ; 确保段名fpga_pwm_reg与代码中一致}
}
FPGA_ADC_REG
这个地方的名字随便起,并不会用到,但是段名fpga_adc_reg
是会使用到的!!!UNINIT
表示此段无需初始化!!!
(2)定义变量并通过attribute存放到指定地址(执行地址)
typedef struct
{unsigned char bit0:1;unsigned char bit1:1;unsigned char bit2:1;unsigned char bit3:1;unsigned char bit4:1;unsigned char bit5:1;unsigned char bit6:1;unsigned char bit7:1;
}ST_BITS; //位域,按位访问typedef union
{unsigned char all;ST_BITS bits;
}ST_REG; //按位或者整体访问__attribute__((section(".fpga_adc_reg"))) volatile ST_REG ADC_REG[16];
__attribute__((section(".fpga_pwm_reg"))) volatile ST_REG PWM_REG[16];
ST_REG
这种形式既可以按位访问地址,也可以按字节访问地址;volatile
表示此变量会被外部设备修改,编译器优化后的代码必须每次都要从内存中访问此变量,而不能从寄存器缓冲中访问;
(3)查看map分配
Load Region LR_IROM1 (Base: 0x08000000, Size: 0x000002f4, Max: 0x00100000, ABSOLUTE)Execution Region ER_IROM1 (Exec base: 0x08000000, Load base: 0x08000000, Size: 0x000002d4, Max: 0x00100000, ABSOLUTE)Exec Addr Load Addr Size Type Attr Idx E Section Name Object0x08000000 0x08000000 0x00000188 Data RO 30 RESET startup_stm32f40xx.o0x08000188 0x08000188 0x00000000 Code RO 36 * .ARM.Collect$$$$00000000 mc_w.l(entry.o)0x08000188 0x08000188 0x00000004 Code RO 39 .ARM.Collect$$$$00000001 mc_w.l(entry2.o)0x0800018c 0x0800018c 0x00000004 Code RO 42 .ARM.Collect$$$$00000004 mc_w.l(entry5.o)0x08000190 0x08000190 0x00000000 Code RO 44 .ARM.Collect$$$$00000008 mc_w.l(entry7b.o)0x08000190 0x08000190 0x00000000 Code RO 46 .ARM.Collect$$$$0000000A mc_w.l(entry8b.o)0x08000190 0x08000190 0x00000008 Code RO 47 .ARM.Collect$$$$0000000B mc_w.l(entry9a.o)0x08000198 0x08000198 0x00000004 Code RO 54 .ARM.Collect$$$$0000000E mc_w.l(entry12b.o)0x0800019c 0x0800019c 0x00000000 Code RO 49 .ARM.Collect$$$$0000000F mc_w.l(entry10a.o)0x0800019c 0x0800019c 0x00000000 Code RO 51 .ARM.Collect$$$$00000011 mc_w.l(entry11a.o)0x0800019c 0x0800019c 0x00000004 Code RO 40 .ARM.Collect$$$$00002712 mc_w.l(entry2.o)0x080001a0 0x080001a0 0x00000024 Code RO 31 .text startup_stm32f40xx.o0x080001c4 0x080001c4 0x00000024 Code RO 55 .text mc_w.l(init.o)0x080001e8 0x080001e8 0x00000002 Code RO 1 i.SystemInit main.o0x080001ea 0x080001ea 0x0000000e Code RO 59 i.__scatterload_copy mc_w.l(handlers.o)0x080001f8 0x080001f8 0x00000002 Code RO 60 i.__scatterload_null mc_w.l(handlers.o)0x080001fa 0x080001fa 0x0000000e Code RO 61 i.__scatterload_zeroinit mc_w.l(handlers.o)0x08000208 0x08000208 0x0000009c Code RO 2 i.main main.o0x080002a4 0x080002a4 0x00000030 Data RO 57 Region$$Table anon$$obj.oExecution Region RW_IRAM1 (Exec base: 0x20000000, Load base: 0x080002d4, Size: 0x00000400, Max: 0x00020000, ABSOLUTE)Exec Addr Load Addr Size Type Attr Idx E Section Name Object0x20000000 - 0x00000400 Zero RW 28 STACK startup_stm32f40xx.oExecution Region FPGA_ADC_REG (Exec base: 0x60000000, Load base: 0x080002d4, Size: 0x00000010, Max: 0x00000010, ABSOLUTE, UNINIT)Exec Addr Load Addr Size Type Attr Idx E Section Name Object0x60000000 0x080002d4 0x00000010 Data RW 3 .fpga_adc_reg main.oExecution Region FPGA_PWM_REG (Exec base: 0x60000010, Load base: 0x080002e4, Size: 0x00000010, Max: 0x00000010, ABSOLUTE, UNINIT)Exec Addr Load Addr Size Type Attr Idx E Section Name Object0x60000010 0x080002e4 0x00000010 Data RW 4 .fpga_pwm_reg main.o
0x20000000
是默认的RAM
区域,也是片上RAM对应的地址
,用给其他所有的RW和ZI变量,这里的0x20000000
是执行地址,即程序运行后要访问变量时是访问执行地址
;
0x60000000
是FSMC
模块对应给FPGA
寄存器变量的地址,这里的0x60000000
是执行地址,即程序运行后要访问FPGA
寄存器时是访问执行地址0x60000000
;加载地址是0x080002d4
,也就是为RW属性
,变量需要从ROM
的0x080002d4
取出数据加载到执行地址0x60000000
里作为初值!而.fpga_adc_reg
是这个区域内部的一个段,也就是用户程序会用到的段
。
(4)访问变量
for(unsigned char i = 0; i<16;i++){ADC_REG[i].all=i;PWM_REG[i].bits.bit0 = i+0;}
ADC_REG[0]的地址就是0x60000000
ADC_REG[1]的地址就是0x60000001
ADC_REG[2]的地址就是0x60000002
...
ADC_REG[15]的地址就是0x6000000FPWM_REG[0]的地址就是0x60000010
...
PWM_REG[15]的地址就是0x6000001F
2.地址强转为自定义的结构体类型
还有一种是定一个一个大的结构体变量struct fpga
,其内部变量的排布格式和fpga
提供的一致,然后再将0x6000 0000
地址强转为struct fpga
类型,对结构体成员的访问也就是对fpga
的访问了,这种形式类似于很多stm32
底层外设驱动开发格式;
代码例子:
(1)定义FPGA寄存器的格式
typedef struct
{unsigned char bit0:1;unsigned char bit1:1;unsigned char bit2:1;unsigned char bit3:1;unsigned char bit4:1;unsigned char bit5:1;unsigned char bit6:1;unsigned char bit7:1;
}ST_BITS; //位域,按位访问typedef union
{unsigned char all;ST_BITS bits;
}ST_REG; //按位或者整体访问typedef struct
{ST_REG ST_ADC_REG[16]; // adc地址范围0x6000 0000 ~ 0x6000 0010ST_REG ST_PWM_REG[16]; // pwm地址范围0x6000 0010 ~ 0x6000 0020}ST_FPGA_REG; //FPGA所有的寄存器按此结构和顺序排布,如果有空隙则用rsd占位
fpga
提供两组寄存器,分别是ADC
和PWM
模块的,两者的寄存器紧挨着放置,顺序就是ST_FPGA_REG
声明的那样。
(2)定义FPGA寄存器的地址
#define FPGA_ADDR (0x60000000)
(3)强制转换FPGA寄存器的地址为ST_FPGA_REG类型
#define fpga_all_regs (*(volatile ST_FPGA_REG*)FPGA_ADDR)
这里需要进一步理解指针:指针提供两个信息:从哪个地址开始按照什么格式区看后面的数据。比如,(ST_FPGA_REG*)0x60000000
表示从0x60000000
地址访问数据,这个地址后面的数据要按照ST_FPGA_REG
格式去阅读和访问(即指针指向的类型);带上*号
表示对此地址解引用即访问此地址,需要按照ST_FPGA_REG格式
去访问。
(4)访问FPGA的寄存器值
for(unsigned char i = 0; i<16;i++){ fpga_all_regs.ST_ADC_REG[i].all=i;fpga_all_regs.ST_PWM_REG[i].bits.bit0 = i+0;}
3.指针访问宏定义的地址
还有一种就是更简单的:地址全部都用宏定义,因为fpga
挂在0x6000 0000
地址,每个fpga
的变量都是基于此地址偏移,stm32
可以直接访问地址,就可以拿到变量值。需要宏定义基地址、偏移地址等等。
代码例子:
(1)定义FPGA寄存器地址
#define FPGA_ADDR (0x60000000)#define FPGA_ADC_OFFSET (0x0)
#define FPGA_PWM_OFFSET (0x10)//需要指定地址的类型即指向哪种数据类型,默认设置为unsigned char
#define FPGA_ADC_BASE (unsigned char*)(FPGA_ADDR+FPGA_ADC_OFFSET)
#define FPGA_PWM_BASE (unsigned char*)(FPGA_ADDR+FPGA_PWM_OFFSET)#define FPGA_ADC_SIZE (0x10)
#define FPGA_PWM_SIZE (0x10)
宏定义定义地址时需要指定地址的指向类型,可以默认为unsigned char
。
(2)访问FPGA寄存器
for(unsigned char i = 0; i<FPGA_ADC_SIZE; i++){ *(FPGA_ADC_BASE+i) = i;*(FPGA_PWM_BASE+i) = i+1; //此时无法使用结构体按位访问了(*(ST_REG*)(FPGA_ADC_BASE+i)).all = i;(*(ST_REG*)(FPGA_PWM_BASE+i)).bits.bit0 = i+1; //强转之后就能用结构体按位访问了}
对地址直接解引用访问则为unsigned char
类型,无法按位访问。可以先强制转换为ST_REG
类型,就可以对字节进行按位访问
了。
三、所有代码
所有代码
1、sct文件
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x08000000 0x00100000 { ; load region size_regionER_IROM1 0x08000000 0x00100000 { ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)}RW_IRAM1 0x20000000 0x00020000 {.ANY (+RW +ZI)}FPGA_ADC_REG 0x60000000 UNINIT 0x00000010 { ; adc data*(.fpga_adc_reg) ; 确保段名fpga_adc_reg与代码中一致}FPGA_PWM_REG 0x60000010 UNINIT 0x00000010 { ; pwm data*(.fpga_pwm_reg) ; 确保段名fpga_pwm_reg与代码中一致}
}
2、map表
==============================================================================Memory Map of the imageImage Entry point : 0x08000189Load Region LR_IROM1 (Base: 0x08000000, Size: 0x000002d4, Max: 0x00100000, ABSOLUTE)Execution Region ER_IROM1 (Exec base: 0x08000000, Load base: 0x08000000, Size: 0x000002b4, Max: 0x00100000, ABSOLUTE)Exec Addr Load Addr Size Type Attr Idx E Section Name Object0x08000000 0x08000000 0x00000188 Data RO 30 RESET startup_stm32f40xx.o0x08000188 0x08000188 0x00000000 Code RO 36 * .ARM.Collect$$$$00000000 mc_w.l(entry.o)0x08000188 0x08000188 0x00000004 Code RO 39 .ARM.Collect$$$$00000001 mc_w.l(entry2.o)0x0800018c 0x0800018c 0x00000004 Code RO 42 .ARM.Collect$$$$00000004 mc_w.l(entry5.o)0x08000190 0x08000190 0x00000000 Code RO 44 .ARM.Collect$$$$00000008 mc_w.l(entry7b.o)0x08000190 0x08000190 0x00000000 Code RO 46 .ARM.Collect$$$$0000000A mc_w.l(entry8b.o)0x08000190 0x08000190 0x00000008 Code RO 47 .ARM.Collect$$$$0000000B mc_w.l(entry9a.o)0x08000198 0x08000198 0x00000004 Code RO 54 .ARM.Collect$$$$0000000E mc_w.l(entry12b.o)0x0800019c 0x0800019c 0x00000000 Code RO 49 .ARM.Collect$$$$0000000F mc_w.l(entry10a.o)0x0800019c 0x0800019c 0x00000000 Code RO 51 .ARM.Collect$$$$00000011 mc_w.l(entry11a.o)0x0800019c 0x0800019c 0x00000004 Code RO 40 .ARM.Collect$$$$00002712 mc_w.l(entry2.o)0x080001a0 0x080001a0 0x00000024 Code RO 31 .text startup_stm32f40xx.o0x080001c4 0x080001c4 0x00000024 Code RO 55 .text mc_w.l(init.o)0x080001e8 0x080001e8 0x00000002 Code RO 1 i.SystemInit main.o0x080001ea 0x080001ea 0x0000000e Code RO 59 i.__scatterload_copy mc_w.l(handlers.o)0x080001f8 0x080001f8 0x00000002 Code RO 60 i.__scatterload_null mc_w.l(handlers.o)0x080001fa 0x080001fa 0x0000000e Code RO 61 i.__scatterload_zeroinit mc_w.l(handlers.o)0x08000208 0x08000208 0x0000007c Code RO 2 i.main main.o0x08000284 0x08000284 0x00000030 Data RO 57 Region$$Table anon$$obj.oExecution Region RW_IRAM1 (Exec base: 0x20000000, Load base: 0x080002b4, Size: 0x00000400, Max: 0x00020000, ABSOLUTE)Exec Addr Load Addr Size Type Attr Idx E Section Name Object0x20000000 - 0x00000400 Zero RW 28 STACK startup_stm32f40xx.oExecution Region FPGA_ADC_REG (Exec base: 0x60000000, Load base: 0x080002b4, Size: 0x00000010, Max: 0x00000010, ABSOLUTE, UNINIT)Exec Addr Load Addr Size Type Attr Idx E Section Name Object0x60000000 0x080002b4 0x00000010 Data RW 3 .fpga_adc_reg main.oExecution Region FPGA_PWM_REG (Exec base: 0x60000010, Load base: 0x080002c4, Size: 0x00000010, Max: 0x00000010, ABSOLUTE, UNINIT)Exec Addr Load Addr Size Type Attr Idx E Section Name Object0x60000010 0x080002c4 0x00000010 Data RW 4 .fpga_pwm_reg main.o==============================================================================
3、源代码
/* 1、分散加载文件指定变量存放地址 */
typedef struct
{unsigned char bit0:1;unsigned char bit1:1;unsigned char bit2:1;unsigned char bit3:1;unsigned char bit4:1;unsigned char bit5:1;unsigned char bit6:1;unsigned char bit7:1;
}ST_BITS; //位域,按位访问typedef union
{unsigned char all;ST_BITS bits;
}ST_REG; //按位或者整体访问__attribute__((section(".fpga_adc_reg"))) volatile ST_REG ADC_REG[16];
__attribute__((section(".fpga_pwm_reg"))) volatile ST_REG PWM_REG[16]; /* 2、强制转换地址为结构体格式 */
typedef struct
{ST_REG ST_ADC_REG[16]; // adc地址范围0x6000 0000 ~ 0x6000 0010ST_REG ST_PWM_REG[16]; // pwm地址范围0x6000 0010 ~ 0x6000 0020}ST_FPGA_REG; //FPGA所有的寄存器按此结构和顺序排布,如果有空隙则用rsd占位#define FPGA_ADDR (0x60000000)
#define fpga_all_regs ( *(volatile ST_FPGA_REG*)FPGA_ADDR)/* 3、指针访问 */
#define FPGA_ADC_OFFSET (0x0)
#define FPGA_PWM_OFFSET (0x10)//需要指定地址的类型即指向哪种数据类型,默认设置为unsigned char
#define FPGA_ADC_BASE (unsigned char*)(FPGA_ADDR+FPGA_ADC_OFFSET)
#define FPGA_PWM_BASE (unsigned char*)(FPGA_ADDR+FPGA_PWM_OFFSET)#define FPGA_ADC_SIZE (0x10)
#define FPGA_PWM_SIZE (0x10)/*** 主函数*/
int main(void)
{ unsigned char i= 0;/* 1、分散加载文件指定变量存放地址 */for(i = 0; i<16;i++){ADC_REG[i].all=i;PWM_REG[i].bits.bit0 = i+0;}/* 2、强制转换地址为结构体格式 */for(i = 0; i<16;i++){ fpga_all_regs.ST_ADC_REG[i].all=i;fpga_all_regs.ST_PWM_REG[i].bits.bit0 = i+0;}/* 3、指针访问 */for(i = 0; i<FPGA_ADC_SIZE; i++){ *(FPGA_ADC_BASE+i) = i;*(FPGA_PWM_BASE+i) = i+1; //此时无法使用结构体按位访问了(*(ST_REG*)(FPGA_ADC_BASE+i)).all = i;(*(ST_REG*)(FPGA_PWM_BASE+i)).bits.bit0 = i+1; //强转之后就能用结构体按位访问了}while(1){}}
相关文章:

技巧小结:外部总线访问FPGA寄存器
概述 需求:stm32的fsmc总线挂载fpga,stm32需要访问fpga内部寄存器 1、分散加载文件将变量存放到指定地址即FPGA寄存器地址 sct文件指定变量存储地址,从而可以直接访问外设,(28335也可以,不过用的是cmd文件…...
Qt客户端技巧 -- 窗口美化 -- 圆角窗口
不解析,直接给代码例子 利用窗口重绘事件处理函数paintEvent main.cpp #include <QtCore/qglobal.h> #if QT_VERSION > 0x050000 #include <QtWidgets/QApplication> #else #include <QtGui/QApplication> #endif#include "roundedwin…...
Go语言爬虫系列教程5:HTML解析技术以及第三方库选择
Go语言爬虫系列教程5:HTML解析技术以及第三方库选择 在上一章中,我们使用正则表达式提取网页内容,但这种方法有局限性。对于复杂的HTML结构,我们需要使用专门的HTML解析库。在这一章中,我们将介绍HTML解析技术以及如何…...
理解JavaScript中map和parseInt的陷阱:一个常见的面试题解析
前言 在JavaScript面试中,map和parseInt的组合常常被用作考察候选人对这两个方法理解深度的题目。让我们通过一个简单的例子来深入探讨其中的原理。 问题现象 [1, 2, 3].map(parseInt) // 输出结果是什么?很多人可能会预期输出[1, 2, 3],但…...
文件上传漏洞深度解析:检测与绕过技术矩阵
文件上传漏洞深度解析:检测与绕过技术矩阵 引言:无处不在的文件上传风险 在当今的Web应用生态系统中,文件上传功能几乎无处不在。从社交媒体分享图片到企业文档管理系统,用户上传文件已成为现代Web应用的核心功能之一。然而&…...
3.2 HarmonyOS NEXT跨设备任务调度与协同实战:算力分配、音视频协同与智能家居联动
HarmonyOS NEXT跨设备任务调度与协同实战:算力分配、音视频协同与智能家居联动 在万物互联的全场景时代,设备间的高效协同是释放分布式系统潜力的关键。HarmonyOS NEXT通过分布式任务调度技术,实现了跨设备算力动态分配与任务无缝流转&#…...
Elasticsearch 海量数据写入与高效文本检索实践指南
Elasticsearch 海量数据写入与高效文本检索实践指南 一、引言 在大数据时代,企业和组织面临着海量数据的存储与检索需求。Elasticsearch(以下简称 ES)作为一款基于 Lucene 的分布式搜索和分析引擎,凭借其高可扩展性、实时搜索和…...

jenkins集成gitlab发布到远程服务器
jenkins集成gitlab发布到远程服务器 前面我们讲了通过创建maven项目部署在jenkins本地服务器,这次实验我们将部署在远程服务器,再以nginx作为前端项目做一个小小的举例 1、部署nginx服务 [rootweb ~]# docker pull nginx [rootweb ~]# docker images …...
AI问答-vue3+ts+vite:http://www.abc.com:3022/m-abc-pc/#/snow 这样的项目 在服务器怎么部署
为什么记录有子路径项目的部署,因为,通过子路径可以区分项目,那么也就可以实现微前端架构,并且具有独特优势,每个项目都是绝对隔离的。 要将 Vue3 项目(如路径为 http://www.abc.com:3022/m-saas-pc/#/sno…...

当主观认知遇上机器逻辑:减少大模型工程化中的“主观性”模糊
一、人类与机器的认知差异 当自动驾驶汽车遇到紧急情况需要做出选择时,人类的决策往往充满矛盾:有人会优先保护儿童和老人,有人坚持"不主动变道"的操作原则。这种差异背后,体现着人类特有的情感判断与价值选择。而机器的…...

会计 - 金融负债和权益工具
一、金融负债和权益工具区分的基本原则 (1)是否存在无条件地避免交付现金或其他金融资产的合同义务 如果企业不能无条件地避免以交付现金或其他金融资产来履行一项合同义务,则该合同义务符合金融负债的义务。 常见的该类合同义务情形包括:- 不能无条件避免的赎回; -强制…...
.net Span类型和Memory类型
.NET 中 Span 类型和 Memory 类型的深度剖析 在 .NET 编程的世界里,高效处理内存是提升程序性能的关键。Span<T> 和 Memory<T> 类型的出现,为开发者提供了强大而灵活的工具,用于高效地访问和操作连续内存区域。今天,…...

Dify工具插件开发和智能体开发全流程
想象一下,你正在开发一个 AI 聊天机器人,想让它能实时搜索 Google、生成图像,甚至自动规划任务,但手动集成这些功能耗时又复杂。Dify 来了!这个开源的 AI 应用平台让你轻松开发工具插件和智能体策略插件,快…...
ES6——对象扩展之Set对象
在ES6(ECMAScript 2015)中,Set 对象允许存储任何类型的唯一值,无论是原始值还是对象引用。Set 对象有一些有用的方法,可以操作集合中的数据。以下是一些常用的 Set 对象方法: 方法描述 add 向 Set 对象添加…...

AI书签管理工具开发全记录(十三):TUI基本框架搭建
文章目录 AI书签管理工具开发全记录(十三):TUI基本框架搭建前言 📝1.TUI介绍 🔍2. 框架选择 ⚙️3. 功能梳理 🎯4. 基础框架搭建⚙️4.1 安装4.2 参数设计4.3 绘制ui4.3.1 设计结构体4.3.2 创建头部4.3.3 创…...
<2>-MySQL库的操作
目录 一,创建数据库 二,查看字符集和校验规则 三,修改数据库 四,删除数据库 五,备份和恢复数据库 六,查看连接 一,创建数据库 创建一个名为bin_db的数据库,并设置字符集为utf8…...
Apache DolphinScheduler 和 Apache Airflow 对比
Apache DolphinScheduler 和 Apache Airflow 都是开源的工作流调度平台,用于管理和编排复杂的数据处理任务和管道。以下是对两者在功能、架构、使用场景等方面的对比,用中文清晰说明: 1. 概述 Apache DolphinScheduler: 一个分布…...

初识结构体,整型提升及操作符的属性
目录 一、结构体成员访问操作符1.1 结构体二、操作符的属性:优先级、结合性2.1 优先级2.2 结合性C 运算符优先级 三、表达式求值3.1 整型提升3.2 算数转化 总结 一、结构体成员访问操作符 1.1 结构体 C语言已经提供了内置类型,如:char,shor…...

检测到 #include 错误。请更新 includePath。已为此翻译单元(D:\软件\vscode\test.c)禁用波形曲线
原文链接:【VScodeMinGw】安装配置教程 下载mingw64 打开可以看到bin文件夹下是多个.exe文件,gcc.exe地址在环境配置中要用到 原文链接:VSCode中出现“#include错误,请更新includePath“问题,解决方法 重新VScode后…...
python --导出数据库表结构(pymysql)
import pymysql from pymysql.cursors import DictCursor from typing import Optional, Dict, List, Anyclass DBSchemaExporter:"""MySQL数据库表结构导出工具,支持提取表和字段注释使用示例:>>> exporter DBSchemaExporter("local…...
如何自动部署GitLab项目
如何自动部署 原理 GitLab有预制的钩子, 在代码提交/合并等事件中,会自动调用WebHoos, 即向该URL发送POST请求在布署服务器上监听该POST, 验证通过后执行相关的布置Shell脚本, 即可完成自动布署 配置环境 安装Python和Pip 2.如果需要, 安装python的requests模块和argparse模…...
在 Windows 系统上运行 Docker 容器中的 Ubuntu 镜像并显示 GUI
在 Windows 上安装一个 X Server(如 VcXsrv 或 X410),Ubuntu 容器通过网络将图形界面转发到 Windows。 步骤: 安装 X Server: 推荐使用VcXsrv,免费开源。 安装后运行 XLaunch,选择࿱…...
基于 COM 的 XML 解析技术(MSXML) 的总结
✅ 一、COM 与 MSXML 简要说明 🔷 什么是 COM? COM(Component Object Model)是一种 Windows 平台下的组件技术,可以实现在不重新编译代码的前提下复用组件。 特点: 用 接口调用方式 解耦依赖;…...
多分辨率 LCD 的 GUI 架构设计与实现
1.1多分辨率显示系统的挑战与解决方案 1.1.1 分辨率适配的核心问题 在嵌入式系统中,同时支持不同分辨率的 LCD(如 240160、320480 等)面临以下挑战: 布局适配:同一界面元素在不同分辨率下需要调整大小和位置 字体显示:小分辨率屏幕需要更小的字体,而大分辨率需要更清…...

2025年,百度智能云打响AI落地升维战
如果说从AI到Agent是对于产品落地形态的共识,那么如今百度智能云打响的恰是一个基于Agent进行TO B行业表达的AI生产力升维战。 在这个新的工程体系能力里,除了之前百度Create大会上提出的面向Agent的RAG能力等通用能力模块,对更为专业、个性…...

Seed1.5-VL登顶,国产闭源模型弯道超车丨多模态模型5月最新榜单揭晓
随着图像、文本、语音、视频等多模态信息融合能力的持续增强,多模态大模型在感知理解、逻辑推理和内容生成等任务中的综合表现不断提升,正在展现出愈发接近人类的智能水平。多模态能力也正在从底层的感知理解,迈向具备认知、推理、决策能力的…...
SON.stringify()和JSON.parse()之间的转换
1.JSON.stringify() 作用:将对象、数组转换成字符串 const obj {code: "500",message: "出错了", }; const jsonString JSON.stringify(obj); console.log(jsonString);//"{"code":"Mark Lee","message"…...
【学习笔记】构造函数+重载相关
【学习笔记】构造函数重载相关 一、构造函数 构造函数在创建对象的过程就会执行,带参数与不带参数,带参数的构造函数会默认将成员变量赋值传进去的参数。 class Layer { private:int layer_id; // 层IDstd::string layer_json; // 层的JSON配置…...
JVM——打开JVM后门的钥匙:反射机制
引入 在Java的世界里,反射机制(Reflection)就像一把万能钥匙,能够打开JVM的“后门”,让开发者在运行时突破静态类型的限制,动态操控类的内部结构。想象一下,传统的Java程序如同按菜单点菜的食客…...

第3章——SSM整合
一、整合持久层框架MyBatis 1.准备数据库表及数据 创建数据库:springboot 使用IDEA工具自带的mysql插件来完成表的创建和数据的准备: 创建表 表创建成功后,为表准备数据,如下: 2.创建SpringBoot项目 使用脚手架创建…...