嵌入式IDE(1):IAR中ICF链接文件详解和实例分析

最近在使用NXP的提供的MCUXPresso IDE,除了Eclipse固有的优点外,我觉得它最大的优点就是在链接脚本的生成上,提供了非常直观的GUI配置界面。但这个IDE仅仅支持NXP相关的产品,而且调试的性能在某些情况下并不理想。而我们用得比较多的IDE是Keil和IAR,这两个IDE都有自己生成链接脚本的格式,本篇文章就来介绍一下与IAR的链接脚本生成相关的.icf(IAR Configuration File)后缀的IAR配置文件。

文章目录

  • 1 内存映射
  • 2 ICF语法分析
    • 2.1 工程的ICF文件
    • 2.2 define [exported] symbol和isdefinedsymbol
    • 2.3 define memory、define region、区域表达式和define block
    • 2.4 initialize by copy和do not initialize
    • 2.5 place at、keep和place in

本来打算把ICF文件中的每一个指令的格式都详细地介绍一遍,但发现里面的指令太多了,而且很多都用不到。完整的指令请参考:<EWARM_DevelopmentGuide.ENU.pdf>中的The linker configuration file章节。
所以本篇文章就以I.MX RT1176的IAR工程中的ICF文件为例进行分析,然后详细理解一下每个用到的指令格式。对于本节的ICF例子,除了RT1176内部的几个RAM外,还接了NOR Flash和SDRAM。所以如果懂了这个ICF配置文件,对于其它MCU的配置文件来说也不会有太大的问题。

1 内存映射

首先来看一下整个工程的内存映射表格:

类型名称起始地址大小
FlashNOR Flash0x300000000x1000000
RAMSDRAM0x800000000x3000000
RAMNCACHE_REGION0x830000000x1000000
RAMSRAM_DTC_cm70x200000000x40000
RAMSRAM_ITC_cm70x00x40000
RAMSRAM_OC10x202400000x80000
RAMSRAM_OC20x202c00000x80000
RAMSRAM_OC_ECC10x203400000x10000
RAMSRAM_OC_ECC20x203500000x10000

对于我们的工程来说,有以下几个内存:

  1. 两个256KB的紧耦合内存DTCMITCM
  2. 两个带ECC的片内RAM:OC1OC2
  3. 在映射的起始地址为0x30000000的FlexSPI1接口上接了一个16MB的NOR Flash
  4. 在映射的起始地址为0x80000000的FlexSPI2接口上接了一个64MB的SDRAM。其中,前48MB用于可缓存的区域,后16MB(NCACHE_REGION)用于不可缓存区域,通常直接与硬件进行交互的buffer需要设置为不可缓存。

2 ICF语法分析

2.1 工程的ICF文件

针对上面的内存映射,官方的SDK中提供的ICF文件如下:

define symbol __ram_vector_table_size__        =  isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;
define symbol __ram_vector_table_offset__      =  isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0;define symbol m_interrupts_start       = 0x30002000;
define symbol m_interrupts_end         = 0x300023FF;define symbol m_text_start             = 0x30002400;
if (isdefinedsymbol(__use_flash64MB__)) {define symbol m_text_end               = 0x33FFFFFF;
} else{define symbol m_text_end               = 0x30FFFFFF;
}define symbol m_interrupts_ram_start   = 0x20000000;
define symbol m_interrupts_ram_end     = 0x20000000 + __ram_vector_table_offset__;define symbol m_data_start             = m_interrupts_ram_start + __ram_vector_table_size__;
define symbol m_data_end               = 0x2003FFFF;define symbol m_data2_start            = 0x202C0000;
define symbol m_data2_end              = 0x2033FFFF;define symbol m_data3_start            = 0x80000000;
define symbol m_data3_end              = 0x82FFFFFF;define symbol m_ncache_start                   = 0x83000000;
define symbol m_ncache_end                     = 0x83FFFFFF;define exported symbol __NCACHE_REGION_START   = m_ncache_start;
define exported symbol __NCACHE_REGION_SIZE    = m_ncache_end - m_ncache_start + 1;define symbol m_qacode_start           = 0x00000000;
define symbol m_qacode_end             = 0x0003FFFF;define exported symbol m_boot_hdr_conf_start = 0x30000400;
define symbol m_boot_hdr_ivt_start           = 0x30001000;
define symbol m_boot_hdr_boot_data_start     = 0x30001020;
define symbol m_boot_hdr_dcd_data_start      = 0x30001030;
define symbol m_boot_hdr_xmcd_data_start      = 0x30001040;/* Sizes */
if (isdefinedsymbol(__stack_size__)) {define symbol __size_cstack__        = __stack_size__;
} else {define symbol __size_cstack__        = 0x0400;
}if (isdefinedsymbol(__heap_size__)) {define symbol __size_heap__          = __heap_size__;
} else {define symbol __size_heap__          = 0x0400;
}define exported symbol __VECTOR_TABLE          = m_interrupts_start;
define exported symbol __VECTOR_RAM            = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start;
define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__;define memory mem with size = 4G;
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]| mem:[from m_text_start to m_text_end];
define region QACODE_region = mem:[from m_qacode_start to m_qacode_end];
define region DATA_region = mem:[from m_data_start to m_data_end];
define region DATA2_region = mem:[from m_data2_start to m_data2_end];
define region DATA3_region  = mem:[from m_data3_start to m_data3_end-__size_cstack__];
define region CSTACK_region = mem:[from m_data3_end-__size_cstack__+1 to m_data3_end];
define region NCACHE_region = mem:[from m_ncache_start to m_ncache_end];define block CSTACK    with alignment = 8, size = __size_cstack__   { };
define block HEAP      with alignment = 8, size = __size_heap__     { };
define block RW        { first readwrite, section m_usb_dma_init_data };
define block ZI         with alignment = 32  { first zi, section m_usb_dma_noninit_data };
define block NCACHE_VAR    { section NonCacheable , section NonCacheable.init };
define block QACCESS_CODE  { section CodeQuickAccess };
define block QACCESS_DATA  { section DataQuickAccess };initialize by copy { readwrite, section .textrw, section CodeQuickAccess, section DataQuickAccess };
do not initialize  { section .noinit };place at address mem: m_interrupts_start    { readonly section .intvec };
place at address mem: m_boot_hdr_conf_start { section .boot_hdr.conf };
place at address mem: m_boot_hdr_ivt_start { section .boot_hdr.ivt };
place at address mem: m_boot_hdr_boot_data_start { readonly section .boot_hdr.boot_data };
place at address mem: m_boot_hdr_dcd_data_start { readonly section .boot_hdr.dcd_data };
place at address mem: m_boot_hdr_xmcd_data_start { readonly section .boot_hdr.xmcd_data };keep{ section .boot_hdr.conf, section .boot_hdr.ivt, section .boot_hdr.boot_data, section .boot_hdr.dcd_data, section .boot_hdr.xmcd_data};place in TEXT_region                        { readonly };
place in DATA3_region                       { block RW };
place in DATA3_region                       { block ZI };
if (isdefinedsymbol(__heap_noncacheable__)) {place in NCACHE_region                    { last block HEAP };
} else {place in DATA3_region                     { last block HEAP };
}
place in NCACHE_region                      { block NCACHE_VAR };
place in CSTACK_region                      { block CSTACK };
place in QACODE_region                      { block QACCESS_CODE };
place in DATA_region                        { block QACCESS_DATA };

下面来一段段分析上面的ICF文件。

2.2 define [exported] symbol和isdefinedsymbol

define symbol __ram_vector_table_size__        =  isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;
define symbol __ram_vector_table_offset__      =  isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0;define symbol m_interrupts_start       = 0x30002000;
define symbol m_interrupts_end         = 0x300023FF;define symbol m_text_start             = 0x30002400;
if (isdefinedsymbol(__use_flash64MB__)) {define symbol m_text_end               = 0x33FFFFFF;
} else{define symbol m_text_end               = 0x30FFFFFF;
}define symbol m_interrupts_ram_start   = 0x20000000;
define symbol m_interrupts_ram_end     = 0x20000000 + __ram_vector_table_offset__;define symbol m_data_start             = m_interrupts_ram_start + __ram_vector_table_size__;
define symbol m_data_end               = 0x2003FFFF;define symbol m_data2_start            = 0x202C0000;
define symbol m_data2_end              = 0x2033FFFF;define symbol m_data3_start            = 0x80000000;
define symbol m_data3_end              = 0x82FFFFFF;define symbol m_ncache_start                   = 0x83000000;
define symbol m_ncache_end                     = 0x83FFFFFF;define exported symbol __NCACHE_REGION_START   = m_ncache_start;
define exported symbol __NCACHE_REGION_SIZE    = m_ncache_end - m_ncache_start + 1;define symbol m_qacode_start           = 0x00000000;
define symbol m_qacode_end             = 0x0003FFFF;

这一段中出现了两个ICF语法:

(1)isdefinedsymbol(name):当name被定义了返回1,否则返回0

(2)define symbol:定义一个变量

  • 语法:define [ exported ] symbol name = expr;
  • 参数:name为变量名,expr为变量的值,exported可省略,若定义则可以在程序中使用extern来获取此变量的值

现在来分析一下上面的链接文件:

(1)__ram_vector_table__在其它地方没有定义,即__ram_vector_table_size____ram_vector_table_offset__的值都为0。所以,m_interrupts_ram_startm_interrupts_ram_end都为0x20000000。

实际上,由于程序是运行在NOR Flash中的,程序镜像起始处的中断向量表也映射到了NOR Flash中,而不是保存在RAM中。所以实际上上面的这几个变量并没有被使用到,可以直接忽略。

真正使用的向量表变量是m_interrupts_start(0x30002000)和m_interrupts_end(0x300023FF),长度为0x3FF+1=0x400,可以去启动的.s数一下,程序最开始的向量长度确实是填充到了0x400处。

  • 至于为什么向量表从NOR Flash的0x2000偏移处开始,这是因为I.MX系列单片机都需要一个IVT头供芯片固有的ROM BootLoader进行引导,这个头在使用NOR Flash XIP时,长度为0x2000。这里不用过多纠结。

(2)m_text_start(0x30002400)和m_text_end(0x30FFFFFF)紧跟着向量表,就是后续的代码段链接的位置了,大小为16MB。

(3)m_data_startm_data_end;m_data2_startm_data2_end;m_data3_startm_data3_end;m_ncache_startm_ncache_end;m_qacode_startm_qacode_end

这三个变量分别定义了DTCMOC2SDRAM(可缓存部分)、SDRAM(不可缓存部分)和ITCM的内存起始和结束地址。
(4)__NCACHE_REGION_START__NCACHE_REGION_SIZE:定义了不可缓存内存的起始和结束地址,这个部分用了export,这是因为不可缓存部分需要在程序的MPU代码中进行配置。


接着往下分析:

/* 这里定义的是IVT头中不同参数的偏移,这里不做分析 */
define exported symbol m_boot_hdr_conf_start = 0x30000400;
define symbol m_boot_hdr_ivt_start           = 0x30001000;
define symbol m_boot_hdr_boot_data_start     = 0x30001020;
define symbol m_boot_hdr_dcd_data_start      = 0x30001030;
define symbol m_boot_hdr_xmcd_data_start      = 0x30001040;/* Sizes */
if (isdefinedsymbol(__stack_size__)) {define symbol __size_cstack__        = __stack_size__;
} else {define symbol __size_cstack__        = 0x0400;
}if (isdefinedsymbol(__heap_size__)) {define symbol __size_heap__          = __heap_size__;
} else {define symbol __size_heap__          = 0x0400;
}define exported symbol __VECTOR_TABLE          = m_interrupts_start;
define exported symbol __VECTOR_RAM            = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start;
define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__;

(1)__size_cstack____size_heap__为程序的栈、堆大小的相关变量,后面会使用到。

  • 实际上在这个工程中使用了FreeRTOS,所以只需要保证这里面的栈大小能够运行FreeRTOS的初始化函数就行了,后面的堆、栈都由FreeRTOS管理,从分配给FreeRTOS的空间中分配。

(2)__VECTOR_TABLE(0x30002000)、__VECTOR_RAM(0x30002000)和__RAM_VECTOR_TABLE_SIZE(0)
将这三个变量export给程序。实际上在这个工程中没有使用到这三个变量,这三个变量原本是用来将保存在Flash中的向量表拷贝到RAM中的,所以如果使用的是non-XIP的Flash,如NAND Flash,就会用到这三个变量。

2.3 define memory、define region、区域表达式和define block

先来看一下下面将新出现的ICF语法:
(1)define memory :定义一块内存

  • 语法:define memory [ name ] with size = size_expr [ ,unit-size ];
  • 参数:name为内存名,expr为内存大小,unit-size可省略,若定义它必须赋值为bitsize_expr(位)或bytesize_expr(字节),表示前面内存大小的单位,默认为字节。

(2)define region:定义一块可以放置特定的代码段和数据段的区域。一个区域由一个或多个内存范围组成,每个内存范围都是在特定内存中连续的字节序列。

  • 语法:define [ ram | rom ] region_name = region-expr;
  • 参数:region_name为区域名,[ ram | rom ]可省略,分别表示该region为RAM或ROM。region-expr是区域表达式,使用区域表达式可以组合多个内存范围,这些内存范围可以不连续,甚至不在同一块内存中。在(3)中介绍。

(3)区域表达式

  • 语法:[ memory-name: ][from expr { to expr | size expr } [ repeat expr [ displacement expr ]]]
  • 参数:memory-name为内存区域的名称,如果只有一块内存,可省略此项;from expr { to expr | size expr分别为内存区域的起始地址、终止地址和大小;repeat expr表示同一个内存中分的多个内存范围;displacement exprrepeat序列中从前一个内存范围开始的偏移,默认大小为size

同时区域之间还可以有一些运算:

  • A | B:A和B的并集
  • A & B:A和B的交集
  • A - B:A排除B的集合

(4)define block:块指令定义了一个连续的内存区域,该区域可能包含一组可能为空的段或其他块。
语法:

define [ movable ] block name
[ with param, param... ]
{
extended-selectors
}
[ except
{
section-selectors
} ];其中param可以为下面之一:
size = expr
minimum size = expr
maximum size = expr
expanding size
alignment = expr
end alignment = expr
fixed order
alphabetical order
static base [basename]

块指令比较复杂,参数比较多,有很多参数也用不到,这里就不具体地解释每一个参数了,下面会直接通过解释例子中的几个块指令的含义来帮助大家看懂ICF文件。具体指令的定义可以参考手册p521的define block directive


继续往下分析ICF文件,接下来就是定义一些内存、区域和块:

/* 定义一整个大小为2^32=4G的内存,即芯片的最大寻址范围 */
define memory mem with size = 4G;
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]| mem:[from m_text_start to m_text_end];
define region QACODE_region = mem:[from m_qacode_start to m_qacode_end];
define region DATA_region = mem:[from m_data_start to m_data_end];
define region DATA2_region = mem:[from m_data2_start to m_data2_end];
define region DATA3_region  = mem:[from m_data3_start to m_data3_end-__size_cstack__];
define region CSTACK_region = mem:[from m_data3_end-__size_cstack__+1 to m_data3_end];
define region NCACHE_region = mem:[from m_ncache_start to m_ncache_end];define block CSTACK    with alignment = 8, size = __size_cstack__   { };
define block HEAP      with alignment = 8, size = __size_heap__     { };
define block RW        { first readwrite, section m_usb_dma_init_data };
define block ZI         with alignment = 32  { first zi, section m_usb_dma_noninit_data };
define block NCACHE_VAR    { section NonCacheable , section NonCacheable.init };
define block QACCESS_CODE  { section CodeQuickAccess };
define block QACCESS_DATA  { section DataQuickAccess };

上面的脚本中定义了多个内存区域,其中TEXT_region即代码段的范围,即NOR Flash中0x30002000后开始放代码的区域;QACODE_region即ITCM的区域;DATA_region即DTCM的区域;DATA2_region即SRAM_OC2的区域;DATA3_region即SDRAM的可cacheable区域;CSTACK_region为栈的区域,这里定义为DATA3_region的最后__size_cstack__字节区域;NCACHE_region即SDRAM的non-cacheable区域。

接下来就是定义多个block了,其中CSTACKHEAP分别为栈和堆的块,它要求这里面的内存8字节对齐,大小分别为__size_cstack____size_heap__RW中的first是一个extended-selectors表达式(参考p540),这里表示将readwrite块放置在包含RW块(即RW块的父集)的最前面,这里可以定义多个section-selectors,用逗号隔开,所以后面的section m_usb_dma_init_data定义了一个名为m_usb_dma_init_data的section在这个块中;ZIRW类似,它额外要求32字节对齐;NCACHE_VARQACCESS_CODEQACCESS_DATA 都是定义了一个特定名称section在这个block中。

  • 比如这里section定义的m_usb_dma_init_data,可以在程序中使用#pragma(location=m_usb_dma_init_data)__attribute__((section("m_usb_dma_init_data")))来定义变量到RW
  • readwrite(RW)、readonlyzi为ICF文件内置的三个block,分别为读写段、只读段和bss段。readwrite段默认包含了程序中有初始值的变量,readonly段默认包含了程序的代码,zi段默认包含了程序中没有初始值的变量。

2.4 initialize by copy和do not initialize

(1)initialize by copy
语法(具体参考P527):

initialize { by copy | manually }
[ with param, param... ]
{
section-selectors
}
[ except
{
section-selectors
} ];

这里的by copy表示复制一个段,这也很好理解,比如对于RW段来说,只要不是bss段的有初始值的变量,这些初始值是会占据编译出来的image的大小的,也就是这些初始值是保存在Flash中,然后上电后再拷贝到RAM中的,这里定义的RW段是RAM,所以再"copy"一段到Flash中。

(2)do not initialize:与initialize by copy相反,一般用于bss段

继续往下看ICF文件:

initialize by copy { readwrite, section .textrw, section CodeQuickAccess, section DataQuickAccess };
do not initialize  { section .noinit };

就是根据定义的某个section是否会存放有初始值的变量,手动定义sectioninitialize by copydo not initialize

2.5 place at、keep和place in

(1)place at

[ "name": ]
place [ noload ] at { address [ memory: ] address |
start of region_expr [ with mirroring to mirror_address ] |
end of region_expr [ with mirroring to mirror_address ] }
{
extended-selectors
}
[ except
{
section-selectors
} ];

该指令用于将sectionsblocks放置在特定地址或者区域的开头或末尾。
(2)keep

keep
{
[ { section-selectors | block name }
[ , {section-selectors | block name }... ] ]
}
[ except
{
section-selectors
} ];

这里的keep和链接脚本ld文件中的keep的作用一样,用于控制链接器在生成可执行文件或库时保留特定的sectionsblocks,防止链接器优化过程中丢弃未被引用的sectionsblocks
(3)place in

[ "name": ]
place [ noload ] in region-expr
[ with mirroring to mirror_address ]
{
extended-selectors
}
[ except{
section-selectors
} ];

place in会防止sectionblock到一个特定的区域。如果有多个sectionblock,则它们之间放置的顺序是随机的,如果想指定这个顺序可以用block表达式,一般用不到。


继续往下看链接脚本:

place at address mem: m_interrupts_start    { readonly section .intvec };
place at address mem: m_boot_hdr_conf_start { section .boot_hdr.conf };
place at address mem: m_boot_hdr_ivt_start { section .boot_hdr.ivt };
place at address mem: m_boot_hdr_boot_data_start { readonly section .boot_hdr.boot_data };
place at address mem: m_boot_hdr_dcd_data_start { readonly section .boot_hdr.dcd_data };
place at address mem: m_boot_hdr_xmcd_data_start { readonly section .boot_hdr.xmcd_data };
keep{ section .boot_hdr.conf, section .boot_hdr.ivt, section .boot_hdr.boot_data, section .boot_hdr.dcd_data, section .boot_hdr.xmcd_data};place in TEXT_region                        { readonly };
place in DATA3_region                       { block RW };
place in DATA3_region                       { block ZI };
if (isdefinedsymbol(__heap_noncacheable__)) {place in NCACHE_region                    { last block HEAP };
} else {place in DATA3_region                     { last block HEAP };
}
place in NCACHE_region                      { block NCACHE_VAR };
place in CSTACK_region                      { block CSTACK };
place in QACODE_region                      { block QACCESS_CODE };
place in DATA_region                        { block QACCESS_DATA };

上面的place at就是将后面大括号里的section放置到前面指定的地址中,而这些section可以在程序中使用例如__attribute__((section(".boot_hdr.boot_data"), used))的语句放置到指定段中。这里的几个段实际上是I.MX RT系列单片机的启动头,通过这种方式可以在C文件中更改启动头的内容。

  • 上面定义的6个section应该都是readonly才对,我的猜测是可写可不写,因为这里已经强制了放置的地址,这里的地址都在Flash,应该默认就已经表示都是readonly。可惜IAR没有生成像Makefile那样标准的链接脚本,不然可以对比一下前后的差别。

后面的place in就是将前面定义的各个block(由多个section组成)放置到前面定义的各个region(代表一个或多个地址范围)中。其中last block HEAP中的last和前面遇到的first一样,也是extended-selectors中的定义,表示放置该region的最后面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/77282.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【kafka】kafka重要的集群参数配置

如何规划Kafka 对于实际应用的生产环境中&#xff0c;需要尽量先规划设计好集群&#xff0c;避免后期业务上线后费力调整。在考量部署方案时需要通盘考虑&#xff0c;不能仅从单个维度上进行评估&#xff0c;下面是几个重要的维度的考量和建议&#xff1a; 这里重点说说操作系…

MYBATIS-PLUS入门使用、踩坑记录

转载&#xff1a; mybatis-plus入门使用、踩坑记录 - 灰信网&#xff08;软件开发博客聚合&#xff09; 首先引入MYBATIS-PLUS依赖&#xff1a; SPRING BOOT项目&#xff1a; <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus…

Spring Boot + Vue的网上商城之客服系统实现

Spring Boot Vue的网上商城之客服系统实现 在网上商城中&#xff0c;客服系统是非常重要的一部分&#xff0c;它能够为用户提供及时的咨询和解答问题的服务。本文将介绍如何使用Spring Boot和Vue.js构建一个简单的网上商城客服系统。 思路 在本教程中&#xff0c;我们学习了…

Debian 使用 systemd 自动挂载 Samba

本文地址&#xff1a;blog.lucien.ink/archives/540 写成了一键脚本&#xff0c;直接执行即可。 需要注意的是&#xff0c;挂载的路径和 systemd service 的名字要对应上&#xff0c;比如挂载的路径为 /mnt/nas 那 service 的文件名应为 mnt-nas.service。 #!/usr/bin/env ba…

C++信息学奥赛1170:计算2的N次方

#include <iostream> #include <string> #include <cstring>using namespace std;int main() {int n;cin >> n; // 输入一个整数nint arr[100];memset(arr, -1, sizeof(arr)); // 将数组arr的元素初始化为-1&#xff0c;sizeof(arr)表示arr数组的字节…

数据结构和算法之冒泡排序

冒泡排序是一种简单的排序算法&#xff0c;它重复地遍历要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果它们的顺序错误就交换位置&#xff0c;直到没有再需要交换的元素。该算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 #mermaid-svg-0y56kW…

【Linux】:Centos7安装Kafka

目录 一.先安装zookeeper并启动 二.安装kafka 一.先安装zookeeper并启动 1.下载 https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.8.2/apache-zookeeper-3.8.2-bin.tar.gz 2.上传到Linux任意目录下 3.解压到/user/local/文件夹下 [rootlocalhost app]# tar …

分类预测 | Matlab实现基于BP-Adaboost数据分类预测

分类预测 | Matlab实现基于BP-Adaboost数据分类预测 目录 分类预测 | Matlab实现基于BP-Adaboost数据分类预测效果一览基本介绍研究内容程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于BP-Adaboost数据分类预测&#xff08;Matlab完整程序和数据&#xff09; 2.多特征输入…

刷刷刷——双指针算法

双指针算法 这里的双指针&#xff0c;可能并不是真正意义上的指针&#xff0c;而是模拟指针移动的过程。 常见的有两种&#xff1a; 双指针对撞&#xff1a; 即在顺序结构中&#xff0c;指针从两端向中间移动&#xff0c;然后逐渐逼近 终止条件一般是&#xff1a; left ri…

Java面试笔试acm版输入

首先区分scanner.nextInt()//输入一个整数&#xff0c;只能读取一个数&#xff0c;空格就停止。 scanner.next()//输入字符串&#xff0c;只能读取一个字符串&#xff0c;空格就停止&#xff0c;但是逗号不停止。 scanner.nextLine() 读取一行&#xff0c;换行停止&#xff0c…

Excel、Jira、Bugfree 应该选哪个做bug管理?深度对比

如何选择最适合您团队的Bug管理系统&#xff1f;本指南提供了全面的选型建议&#xff0c;并深度对比了7类主流工具如PingCode、Jira、 Mantis等&#xff0c;涵盖功能、成本、易用性等多个关键因素。适用于软件开发团队、项目经理和决策者。 一、适合的BUG管理工具在产品开发中的…

Pytorch 机器学习专业基础知识+神经网络搭建相关知识

文章目录 一、三种学习方式二、机器学习的一些专业术语三、模型相关知识四、常用的保留策略五、数据处理六、解决过拟合与欠拟合七、成功的衡量标准 一、三种学习方式 有监督学习&#xff1a; 1、分类问题 2、回归问题 3、图像分割 4、语音识别 5、语言翻译 无监督学习 1、聚类…

Web Component -- 即将爆发的原生的 UI 组件化标准

Web Component 概述 Web Component 是一种用于构建可复用用户界面组件的技术&#xff0c;开发者可以创建自定义的 HTML 标签&#xff0c;并将其封装为包含逻辑和样式的独立组件&#xff0c;从而在任何 Web 应用中重复使用。 每个 Web Component 都具有自己的 DOM 和样式隔离&a…

2023-09-12 LeetCode每日一题(课程表 IV)

2023-03-29每日一题 一、题目编号 1462. 课程表 IV二、题目链接 点击跳转到题目位置 三、题目描述 你总共需要上 numCourses 门课&#xff0c;课程编号依次为 0 到 numCourses-1 。你会得到一个数组 prerequisite &#xff0c;其中 prerequisites[i] [ai, bi] 表示如果你…

JDBC操作SQLite的工具类

直接调用无需拼装sql 注入依赖 <dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.43.0.0</version></dependency>工具类 import org.sqlite.SQLiteConnection;/*** Author cpf* Dat…

轮播图禁用手势滑动

要禁用手势滑动&#xff0c;并只允许自动轮播&#xff0c;你可以使用autoplayDisableOnInteraction属性来实现。以下是如何在Flutter中使用flutter_swiper插件进行配置&#xff1a; 首先&#xff0c;在pubspec.yaml文件中添加flutter_swiper插件的依赖项&#xff1a; dependen…

华为CD32键盘使用教程

华为CD32键盘使用教程 用爱发电写的教程&#xff01; 最后更新时间&#xff1a;2023.9.12 型号&#xff1a;华为有线键盘CD32 基本使用 此键盘在不安装驱动的情况下可以直接使用&#xff0c;但是不安装驱动指纹识别是无法使用的&#xff01;并且NFC功能只支持华为的部分电脑…

VL-Adapter: 针对视觉和语言(Vision-and-Language)的参数高效迁移学习

VL-ADAPTER: Parameter-Efficient Transfer Learning for Vision-and-Language Tasks 22年发表在CVPR UNC大学 Abstract 将介绍VL-BART和VL-T5这两个模型&#xff08;adapter-based parameter-efficient transfer learning techniques&#xff09; 评估这俩模型通过一个统一…

科技资讯|苹果虚拟纸可在Vision Pro中为广告、书籍等提供MR内容和动画

近日&#xff0c;美国专利商标局正式授予苹果一项与虚拟纸张相关的专利。这是与虚拟纸张这项发明相关的第二项专利&#xff0c;鉴于苹果 Vision Pro 将于明年上市&#xff0c;那么我们离苹果实现虚拟纸张的发明又近了一步。 虚拟纸张将能够包含 2D、3D 和动画等 MR内容&#…

JavaScript中循环遍历数组、跳出循环和继续循环

循环遍历数组 上个文章我们简单的介绍for循环&#xff0c;接下来&#xff0c;我们使用for循环去读取数据的数据&#xff0c;之前我们写过这样的一个数组&#xff0c;如下&#xff1a; const ITshareArray ["张三","二愣子","2033-1997","…