01:2440----点灯大师

目录

一:点亮一个LED

1:原理图

2:寄存器

3:2440的框架和启动过程

A:框架

B:启动过程 

4:代码

5:ARM知识补充

6:c语言和汇编的应用

A:代码

B:分析汇编语言

C:内存空间

7:内部机制

二:点亮2个灯

三:流水灯

四:按键控制LED

1:原理图

2:寄存器配置

3:代码


一:点亮一个LED

1:原理图

        当LED输入低电平时出现电压差, LED被点亮  (n的意思是低电平有效)

        LED1 LED2 LED4分别接在 GPF4,5,6的IO口上

2:寄存器

        配置GPFCON寄存器的[9:8]位为0b01-----输出模式 ;  GPFCON--设置串口的模式

         GPFDAT寄存器: 当该端口配置为输入端口时,对应的位为引脚状态。当端口配置为输出端口时,引脚状态与对应的位相同。当端口配置为功能引脚时,将读取未定义值。

        GPF4对应GPFDAT寄存器的第4位, GPF[4]----0低电平/1高电平

        GPFDAT寄存器--设置串口具体输出的内容

3:2440的框架和启动过程

A:框架

注意: CPU----里面有许多寄存器(R0~R15) ; 在CPU里面的寄存器是可以直接访问的.

         GPIO控制器----里面有各种引脚,当然也包括我们今天使用的GPF4引脚;  GPIO控制器里面也有寄存器(GPFCON, GPCDAT),不过这里面的寄存器需要地址访问, 不能向CPU里面的寄存器直接访问.  在芯片手册中有寄存器的地址.

B:启动过程 

大多数的ARM芯片都是从0地址启动的, 当然这也包括我们讲述的2440

NOR启动 : NOR Flash基地址为0 ,  片内RAM的地址为0x4000 0000

        CPU读取出NOR第一个指令(前4个字节),执行

        CPU继续在读取出其他的指令在执行;   一边读取一边执行

Nand启动 : 片内4KARM基地址为0,  NOR启动不可访问

        2440硬件把Nand的前4K内容复制到片内RAM上,  然后CPU从0地址取出第条指令执行

4:代码

/*
*点亮一个LED
*/
.text
.global _start_start:
/* 配置GPFCON(0X56000050)寄存器的[9:8]位为01--输出模式*/ldr r1,=0X56000050ldr r0,=0x100str r0,[r1]
/*
*配置GPFDAT寄存器为低电平(0x56000054)--输出低电平
*/ldr r1,=0x56000054ldr r0,=0str r0,[r1]/*死循环*/
halt:b halt

        我们采用的是交叉编译的方法---使用window书写汇编代码-----将汇编代码传给虚拟机-----在虚拟机下将传来的汇编代码编译为bin文件-----在将bin文件传给window-------window烧写bin文件给Linux开发板;      我们使用的是GPIO控制器里面的寄存器所以必须使用地址进行访问

5:ARM知识补充

       程序计数器 R15: 寄存器 R15 保存程序计数器(PC),它总是用于特殊的用途。它经常可用于通用寄存器RO~R14 所使用的位置(即在指令编码中 R15 与 RO~R14 的地位一样,只是指令执行的结果不同),因此,可以认为它是一个通用寄存器。但是对于它的使用还有许多与指令相关的限制或特殊情况。这些将在具体的指令描述中介绍。通常,如果 R15 使用的方式超出了这些限制,那么指令将是不可预测的。

        当指令对 R15 的读取没有超过任何对 R15 使用的限制时,读取的值是指令的地址加上 8个字节。由于 ARM 指令总是以字为单位,结果的 Bit[1:0]总是为 0。这种读取 PC 的方式主要用于对附近的指令和数据进行快速、与位置无关的寻址,包括程序中与位置无关的转移。


        当使用 STR或 STM 指令保存 R15 时,出现了上述规则的一个例外。这些指令可将指令地址加 8字节保存(与其它指令读取 R15 一样)或将指令自身地址加 12 字节(将来还可能出现别的数据)。偏移量 8 还是 12(或是其它数值)取决于 ARM 的实现(也就是说,与芯片有关)。对于某个具体的芯片,它是个常量。这样使用 STR 和 STM 指令是不可移植的。


        由于这个例外,最好避免使用 STR 和 STM 指令来保存 R15。如果很难做到,那么应当在程序中使用合适的指令序列来确定当前使用的芯片所使用的偏移量

在2440中R15(pc)的偏移量为8, 注意取决于他对数据的读取方式

x的地址=x的地址+8

        当他在读取地址A指令的时候

        已经在对地址A+4的指令进行译码

        已经在读取地址A+8的指令

分析反汇编的代码:

led_on.elf:     file format elf32-littlearm
Disassembly of section .text:
00000000 <_start>:0:	e59f1014 	ldr	r1, [pc, #20]	; 1c <halt+0x4>4:	e3a00c01 	mov	r0, #256	; 0x1008:	e5810000 	str	r0, [r1]c:	e59f100c 	ldr	r1, [pc, #12]	; 20 <halt+0x8>10:	e3a00000 	mov	r0, #014:	e5810000 	str	r0, [r1]00000018 <halt>:18:	eafffffe 	b	18 <halt>1c:	56000050 	undefined instruction 0x5600005020:	56000054 	undefined instruction 0x56000054

由于我们使用的是伪指令;  他是不存在的指令,最会被拆分真正的几条ARM指令;

上面的汇编代码都是由伪指令拆分而来的

优点 : 他可以表示任意值;   

        ARM指令===>32位,但是如果使用MOV的话并不能表示32位, 因为MOV32位中的一些位是用来表示他自己的,剩下的不够32位,  剩下的不够32位也只能表示一些立即数

ldr r1,=0X56000050=====>伪指令

6:c语言和汇编的应用

A:代码

我们需要写一个汇编代码, 给main函数设置内存, 调用main函数

int main()
{unsigned int *pGPFCON = (unsigned int *)0x56000050;unsigned int *pGPFDAT = (unsigned int *)0x56000054;/* 配置GPF4为输出引脚 */*pGPFCON = 0x100;/* 设置GPF4输出0 */*pGPFDAT = 0;return 0;
}

.text
.global _start_start:/* 设置内存: sp 栈 */ldr sp, =4096  /* nand启动 */
//	ldr sp, =0x40000000+4096  /* nor启动 *//* 调用main */bl mainhalt:b halt
all:arm-linux-gcc -c -o led.o led.carm-linux-gcc -c -o start.o start.Sarm-linux-ld -Ttext 0 start.o led.o -o led.elfarm-linux-objcopy -O binary -S led.elf led.binarm-linux-objdump -D led.elf > led.dis
clean:rm *.bin *.o *.elf *.dis

我们使用makefile来编译, 避免重复多次的编译 

可以看到x.ids文件中的地址和给板子烧录的bin文件地址一致;

B:分析汇编语言

r0~r3寄存器负责----调用者和被调用者的传递参数的问题;

r4~r11寄存器在函数中,可能被使用, 所以在人口中保存他们, 在出口中恢复他们;


led.elf:     file format elf32-littlearmDisassembly of section .text:00000000 <_start>:0:	e3a0da01 	mov	sp, #4096	; 0x10004:	eb000000 	bl	c <main>00000008 <halt>:8:	eafffffe 	b	8 <halt>0000000c <main>:c:	e1a0c00d 	mov	ip, sp10:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}14:	e24cb004 	sub	fp, ip, #4	; 0x418:	e24dd008 	sub	sp, sp, #8	; 0x81c:	e3a03456 	mov	r3, #1442840576	; 0x5600000020:	e2833050 	add	r3, r3, #80	; 0x5024:	e50b3010 	str	r3, [fp, #-16]28:	e3a03456 	mov	r3, #1442840576	; 0x560000002c:	e2833054 	add	r3, r3, #84	; 0x5430:	e50b3014 	str	r3, [fp, #-20]34:	e51b2010 	ldr	r2, [fp, #-16]38:	e3a03c01 	mov	r3, #256	; 0x1003c:	e5823000 	str	r3, [r2]40:	e51b2014 	ldr	r2, [fp, #-20]44:	e3a03000 	mov	r3, #0	; 0x048:	e5823000 	str	r3, [r2]4c:	e3a03000 	mov	r3, #0	; 0x050:	e1a00003 	mov	r0, r354:	e24bd00c 	sub	sp, fp, #12	; 0xc58:	e89da800 	ldmia	sp, {fp, sp, pc}
Disassembly of section .comment:00000000 <.comment>:0:	43434700 	cmpmi	r3, #0	; 0x04:	4728203a 	undefined8:	2029554e 	eorcs	r5, r9, lr, asr #10c:	2e342e33 	mrccs	14, 1, r2, cr4, cr3, {1}10:	Address 0x10 is out of bounds.

C:内存空间

        内存空间被分为三个部分:代码段(text segment,即程序代码)、数据段(data segment,即变量)和栈段(stack segment)。数据段从下往上增长,而栈从上向下增长图。在这两者之间是空闲的地址空间。栈的增长是随着程序的执行自动进行的,而数据的扩展则需要通过brk 系统调用来显式地完成,brk有一个参数来指定数据段的结束地址,它可比当前值大(表示扩展数据段 ),或是比当前值小(表示缩小数据段 )。当然,这个参数必须小于指针,否则栈和数据段将会重叠,这是不允许的。

7:内部机制

二:点亮2个灯

        上面我们实现了被调用者给调用者传递参数;

        我们这里学习---调用者给被调用者传递参数

int len_on(int num)
{/*设置寄存器 点亮LED2*/unsigned int* GPFCON = 0x56000050;unsigned int* GPFDAT = 0x56000054;if (num == 4){/*设置输出模式*/*GPFCON = 0x100;}if (num == 5){/*设置输出模式*/*GPFCON = 0x400;}/*输出低电平*/*GPFDAT = 0;return 0;
}
void Delay(int n)
{while (n--);
}
/*
*点亮一个LED
*/
.text
.global _start_start:/*设置内存: sp栈*/ldr sp,=4096 /*nand启动*/ldr sp,=0x40000000+4096/*nor启动*/mov r0 ,#4bl len_onldr r0 ,=10000bl Delaymov r0 ,#5bl len_onhalt:b halt

led.elf:     file format elf32-littlearmDisassembly of section .text:00000000 <_start>:0:	e3a0da01 	mov	sp, #4096	; 0x10004:	e59fd018 	ldr	sp, [pc, #24]	; 24 <halt+0x4>8:	e3a00004 	mov	r0, #4c:	eb000006 	bl	2c <len_on>10:	e59f0010 	ldr	r0, [pc, #16]	; 28 <halt+0x8>14:	eb000022 	bl	a4 <Delay>18:	e3a00005 	mov	r0, #51c:	eb000002 	bl	2c <len_on>00000020 <halt>:20:	eafffffe 	b	20 <halt>24:	40001000 	andmi	r1, r0, r028:	00002710 	andeq	r2, r0, r0, lsl r70000002c <len_on>:2c:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)30:	e28db000 	add	fp, sp, #034:	e24dd014 	sub	sp, sp, #2038:	e50b0010 	str	r0, [fp, #-16]3c:	e59f3058 	ldr	r3, [pc, #88]	; 9c <len_on+0x70>40:	e50b300c 	str	r3, [fp, #-12]44:	e59f3054 	ldr	r3, [pc, #84]	; a0 <len_on+0x74>48:	e50b3008 	str	r3, [fp, #-8]4c:	e51b3010 	ldr	r3, [fp, #-16]50:	e3530004 	cmp	r3, #454:	1a000002 	bne	64 <len_on+0x38>58:	e51b300c 	ldr	r3, [fp, #-12]5c:	e3a02c01 	mov	r2, #256	; 0x10060:	e5832000 	str	r2, [r3]64:	e51b3010 	ldr	r3, [fp, #-16]68:	e3530005 	cmp	r3, #56c:	1a000002 	bne	7c <len_on+0x50>70:	e51b300c 	ldr	r3, [fp, #-12]74:	e3a02b01 	mov	r2, #1024	; 0x40078:	e5832000 	str	r2, [r3]7c:	e51b3008 	ldr	r3, [fp, #-8]80:	e3a02000 	mov	r2, #084:	e5832000 	str	r2, [r3]88:	e3a03000 	mov	r3, #08c:	e1a00003 	mov	r0, r390:	e28bd000 	add	sp, fp, #094:	e8bd0800 	pop	{fp}98:	e12fff1e 	bx	lr9c:	56000050 	undefined instruction 0x56000050a0:	56000054 	undefined instruction 0x56000054000000a4 <Delay>:a4:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)a8:	e28db000 	add	fp, sp, #0ac:	e24dd00c 	sub	sp, sp, #12b0:	e50b0008 	str	r0, [fp, #-8]b4:	e51b3008 	ldr	r3, [fp, #-8]b8:	e3530000 	cmp	r3, #0bc:	03a03000 	moveq	r3, #0c0:	13a03001 	movne	r3, #1c4:	e20330ff 	and	r3, r3, #255	; 0xffc8:	e51b2008 	ldr	r2, [fp, #-8]cc:	e2422001 	sub	r2, r2, #1d0:	e50b2008 	str	r2, [fp, #-8]d4:	e3530000 	cmp	r3, #0d8:	1afffff5 	bne	b4 <Delay+0x10>dc:	e28bd000 	add	sp, fp, #0e0:	e8bd0800 	pop	{fp}e4:	e12fff1e 	bx	lrDisassembly of section .ARM.attributes:00000000 <.ARM.attributes>:0:	00002541 	andeq	r2, r0, r1, asr #104:	61656100 	cmnvs	r5, r0, lsl #28:	01006962 	tsteq	r0, r2, ror #18c:	0000001b 	andeq	r0, r0, fp, lsl r010:	00543405 	subseq	r3, r4, r5, lsl #814:	01080206 	tsteq	r8, r6, lsl #418:	04120109 	ldreq	r0, [r2], #-265	; 0x1091c:	01150114 	tsteq	r5, r4, lsl r120:	01180317 	tsteq	r8, r7, lsl r324:	Address 0x00000024 is out of bounds.Disassembly of section .comment:00000000 <.comment>:0:	3a434347 	bcc	10d0d24 <__bss_end__+0x10c8c3c>4:	74632820 	strbtvc	r2, [r3], #-2080	; 0x8208:	312d676e 	teqcc	sp, lr, ror #14c:	312e362e 	teqcc	lr, lr, lsr #1210:	2e342029 	cdpcs	0, 3, cr2, cr4, cr9, {1}14:	00332e34 	eorseq	r2, r3, r4, lsr lr

        对于2440他的内部同样存在看门狗, 我们在程序中没有对看门狗进行操作; 所以他在一段时间就会复位. 

三:流水灯


void Delay(int n)
{while (n--);
}int main(void)
{int i = 4;/*设置寄存器 点亮LED2*/volatile unsigned int* GPFCON = (volatile unsigned int*)0x56000050;volatile unsigned int* GPFDAT = (volatile unsigned int*)0x56000054;/*设置GPF4/5/6位位输出模式*/*GPFCON &= ~((3 << 8) | (3 << 10) | (3 << 12)); //3对应0b11 清位*GPFCON |= ((1 << 8) | (1 << 10) | (1 << 12)); //置1-设置位输出模式/*GPFDAT寄存器配置 */*GPFDAT &= ~((1 << 4) | (1 << 5) | (1 << 6)); //清位*GPFDAT |= ((1 << 4) | (1 << 5) | (1 << 6)); //把GPFDAT寄存器的4 5 6 位置1--灭灯/*led4 0x100 led5 0x400 */while (1){	if (i == 7)i = 4;*GPFDAT &= ~(1 << i);Delay(10000);*GPFDAT |= (1 << i);Delay(10000);i++;		}return 0;
}

/*
*点亮一个LED
*/
.text
.global _start_start:
/* 关闭看门狗 */ldr r0, =0x53000000ldr r1, =0str r1, [r0]/*设置内存: sp栈* 我们判断是nor启动还是nand启动/mov r1, #0ldr r0, [r1] /* 读出原来的值备份 */str r1, [r1] /* 0->[0] */ ldr r2, [r1] /* r2=[0] */cmp r1, r2   /* r1==r2? 如果相等表示是NAND启动 */ldr sp, =0x40000000+4096 /* 先假设是nor启动 */moveq sp, #4096  /* nand启动 */streq r0, [r1]   /* 恢复原来的值 */bl mainhalt:b halt

1:看门狗问题的解决

        看门狗定时器控制(WTCON)寄存器WTCON寄存器允许用户启用/禁用看门狗定时器,选择来自4个不同源的时钟信号,启用/禁用中断,启用/禁用看门狗定时器输出。看门狗定时器用于S3C2440A上电后功能异常重启时恢复;如果不希望控制器重启,则关闭看门狗定时器

我们可以看到当 Reset enable/disable (重新启用/禁用) 设置WTCON寄存器位0时, 2400就会关闭我们的寄存器

2:如何区分是nar启动还是nand启动

        nor启动 : 可以向内存一样读, 但是不能向内存一样写; (如果一定要写的话需要发送一定格式的数据才可以写)

        nand : 可读取写

方法: 分辨是nor/nand启动
     * 写0到0地址, 再读出来
     * 如果得到0, 表示0地址上的内容被修改了, 它对应ram, 这就是nand启动 (nand-- 可读取写)
     * 否则就是nor启动  (只能读)

四:按键控制LED

1:原理图

平时他为高电平,  当按键按下他为低电平;  

2:寄存器配置

GPG3

GPF

按键位输入模式

3:代码

void Delay(int n)
{while (n--);
}#define GPFCON (*((volatile unsigned int*)0x56000050))
#define GPFDAT (*((volatile unsigned int*)0x56000054))
#define GPGCON  (*((volatile unsigned int*)0x56000060))
#define GPGDAT (*((volatile unsigned int*)0x56000064))
int main(void)
{/*volatile unsigned int* GPFCON = (volatile unsigned int*)0x56000050;volatile unsigned int* GPFDAT = (volatile unsigned int*)0x56000054;volatile unsigned int* GPGCON = (volatile unsigned int*)0x56000060;volatile unsigned int* GPGDAT = (volatile unsigned int*)0x56000064;*//*设置GPF4/5/6位p 位输出模式*/GPFCON &= ~((3 << 8) | (3 << 10) | (3 << 12)); //3对应0b11 清位GPFCON |= ((1 << 8) | (1 << 10) | (1 << 12)); //置1-设置位输出模式/*设置GPF0和GPF2按键位输入模式*/GPFCON &= ~((3 << 0) | (3 << 4));/*GPG3位输入模式*/GPGCON &= ~(3 << 6);while (1){	if (GPFDAT & (1 << 0)) /* s2 --> gpf6 */{/* 松开 */GPFDAT |= (1 << 6);}else{/* 按下 */GPFDAT &= ~(1 << 6);}if (GPFDAT & (1 << 2)) /* s3 --> gpf5 */{/* 松开 */GPFDAT |= (1 << 5);}else{/* 按下 */GPFDAT &= ~(1 << 5);}if ((GPGDAT & (1 << 3))==0) /* s4 --> gpf4 */{/* 按下 */GPFDAT &= ~(1 << 4);}else{/* 松开 */GPFDAT |= (1 << 4);	}}return 0;
}
/*
*点亮一个LED
*/
.text
.global _start_start:
/* 配置GPFCON(0X56000050)寄存器的[9:8]位为01--输出模式*/ldr r1,=0X56000050ldr r0,=0x100str r0,[r1]
/*
*配置GPFDAT寄存器为低电平(0x56000054)--输出低电平
*/ldr r1,=0x56000054ldr r0,=0str r0,[r1]/*死循环*/
halt:b halt

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

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

相关文章

汽车操纵稳定性matlab仿真

1、内容简介 略 14-可以交流、咨询、答疑 2、内容说明 汽车操纵稳定性matlab仿真&#xff0c;包含完整的论文 操纵动力学、两自由度 摘要&#xff1a;当今&#xff0c;仿真技术日益广泛地应用于汽车工程领域&#xff0c;操纵稳定性研究越来越多地使用成熟的计算机仿真理论…

MongoDB基础知识~

引入MongoDB&#xff1a; 在面对高并发&#xff0c;高效率存储和访问&#xff0c;高扩展性和高可用性等的需求下&#xff0c;我们之前所学习过的关系型数据库(MySql,sql server…)显得有点力不从心&#xff0c;而这些需求在我们的生活中也是随处可见的&#xff0c;例如在社交中…

高防CDN:护航网络安全的卓越之选

在当今数字化时代&#xff0c;网络攻击与日俱增&#xff0c;为了确保网站和应用程序的稳定运行&#xff0c;高防CDN&#xff08;高防御内容分发网络&#xff09;应运而生。选择高防CDN的理由不仅源于其强大的防护性能&#xff0c;还体现了其与硬件防火墙异曲同工的奥妙。 选择高…

【蓝桥杯软件赛 零基础备赛20周】第3周——填空题

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 文章目录 00. 2023年第14届参赛数据0. 上一周答疑1. 填空…

进亦忧,退亦忧,Github Copilot 集成进入 Visual Studio 带来的思考

开篇想到《岳阳楼记》的结尾&#xff1a; 不以物喜&#xff0c;不以己悲&#xff1b;居庙堂之高则忧其民&#xff1b;处江湖之远则忧其君。是进亦忧&#xff0c;退亦忧。然则何时而乐耶&#xff1f;其必曰&#xff1a;“先天下之忧而忧&#xff0c;后天下之乐而乐”乎。未来30…

【信息安全原理】——传输层安全(学习笔记)

&#x1f4d6; 前言&#xff1a;为保证网络应用&#xff0c;特别是应用广泛的Web应用数据传输的安全性&#xff08;机密性、完整性和真实性&#xff09;&#xff0c;可以在多个网络层次上采取安全措施。本篇主要介绍传输层提供应用数据安全传输服务的协议&#xff0c;包括&…

python异常、模块与包

1.异常 异常&#xff1a;当检测到一个错误时&#xff0c;Python解释器就无法继续执行了&#xff0c;反而出现了一些错误的提示&#xff0c;这就是所谓的“异常”&#xff0c;也就是我们常说的BUG。 1.1捕获异常 基本语法&#xff1a; try:可能发生错误代码 except:如果出现…

数据分析实战 | SVM算法——病例自动诊断分析

目录 一、数据分析及对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型应用及评价 一、数据分析及对象 CSV文件——“bc_data.csv” 数据集链接&#xff1a;https://download.csdn.net/download/m0_70452407/88…

阿里云国际站:全球加速GA

文章目录 一、前言 二、阿里云全球加速的概念 三、阿里云全球加速的功能优势 四、阿里云全球加速的原理 五、阿里云全球加速的应用场景 六、写在最后 一、前言 随着互联网的快速发展&#xff0c;网站速度已经成为了用户访问体验的一个重要指标。阿里云加速作为一种新的技…

黑马程序员微服务Docker实用篇

Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署…

CCNA课程实验-13-PPPoE

目录 实验条件网络拓朴需求 配置实现基础配置模拟运营商ISP配置ISP的DNS配置出口路由器OR基础配置PC1基础配置 出口路由器OR配置PPPOE拨号创建NAT(PAT端口复用) PC1测试结果 实验条件 网络拓朴 需求 OR使用PPPoE的方式向ISP发送拨号的用户名和密码&#xff0c;用户名&#xf…

【案例】超声波测距系统设计

1.1 总体设计 1.1.1 概述 学习了明德扬至简设计法和明德扬设计规范&#xff0c;本人用FPGA设计了一个测距系统。该系统采用超声波进行测量距离再在数码管上显示。在本案例的设计过程中包括了超声波的驱动、三线式数码管显示等技术。经过逐步改进、调试等一系列工作后&#xf…

【数据结构】树与二叉树(十三):递归复制二叉树(算法CopyTree)

文章目录 5.2.1 二叉树二叉树性质引理5.1&#xff1a;二叉树中层数为i的结点至多有 2 i 2^i 2i个&#xff0c;其中 i ≥ 0 i \geq 0 i≥0。引理5.2&#xff1a;高度为k的二叉树中至多有 2 k 1 − 1 2^{k1}-1 2k1−1个结点&#xff0c;其中 k ≥ 0 k \geq 0 k≥0。引理5.3&…

vue,react虚拟dom

Virtual DOM 前言 在传统的Web开发中&#xff0c;直接操作真实的DOM通常是一个昂贵且低效的操作。为了解决这个问题&#xff0c;Virtual DOM&#xff08;虚拟DOM&#xff09;被引入为一个中间层&#xff0c;允许开发者在内存中进行操作&#xff0c;从而避免频繁且不必要的真实D…

深度学习的集体智慧:最新发展综述

一、说明 我们调查了来自复杂系统的想法&#xff0c;如群体智能、自组织和紧急行为&#xff0c;这些想法在机器学习中越来越受欢迎。人工神经网络正在影响我们的日常生活&#xff0c;从执行预测性任务&#xff08;如推荐、面部识别和对象分类&#xff09;到生成任务&#xff08…

git的分支及标签使用及情景演示

目录 一. 环境讲述 二.分支 1.1 命令 1.2情景演练 三、标签 3.1 命令 3.2 情景演示 ​编辑 一. 环境讲述 当软件从开发到正式环境部署的过程中&#xff0c;不同环境的作用如下&#xff1a; 开发环境&#xff1a;用于开发人员进行软件开发、测试和调试。在这个环境中…

【Spring Boot 源码学习】初识 SpringApplication

Spring Boot 源码学习系列 初识 SpringApplication 引言往期内容主要内容1. Spring Boot 应用程序的启动2. SpringApplication 的实例化2.1 构造方法参数2.2 Web 应用类型推断2.3 加载 BootstrapRegistryInitializer2.4 加载 ApplicationContextInitializer2.5 加载 Applicatio…

Codeforces Round 788 (Div. 2) E. Hemose on the Tree(树上构造)

题目 t(t<5e4)组样例&#xff0c;每次给定一个数p&#xff0c; 表示一棵节点数为的树&#xff0c; 以下n-1条边&#xff0c;读入树边 对于n个点和n-1条边&#xff0c;每个点需要赋权&#xff0c;每条边需要赋权&#xff0c; 权值需要恰好构成[1,2n-1]的排列 并且当你赋…

阿里云ACK(Serverless)安装APISIX网关及APISIX Ingress Controller

在k8s上安装apisix全家&#xff0c;通过helm安装很简单&#xff0c;但是会遇到一些问题。 安装 首先登录阿里云控制台&#xff0c;在ACK集群详情页&#xff0c;进入CloudShell&#xff0c;执行下面helm命令安装apisix、apisix-ectd、apisix-dashboard和apisix-ingress-contro…

汽车ECU的虚拟化技术初探(一)

目录 1.为什么要提汽车ECU的虚拟化&#xff1f; 2.虚拟化技术分类 2.1 硬件虚拟化 2.2 操作系统虚拟化 问题引入&#xff1a; Hypervisor是如何来管理和隔离硬件资源&#xff0c;保证各个不同功能的应用程序的资源使用安全和资源调度&#xff1f;没有MMU就做不了虚拟化&am…