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,=0X56000050
	ldr r0,=0x100
	str r0,[r1]
/*
*配置GPFDAT寄存器为低电平(0x56000054)--输出低电平
*/
	ldr r1,=0x56000054
	ldr r0,=0
	str 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	; 0x100
   8:	e5810000 	str	r0, [r1]
   c:	e59f100c 	ldr	r1, [pc, #12]	; 20 <halt+0x8>
  10:	e3a00000 	mov	r0, #0
  14:	e5810000 	str	r0, [r1]

00000018 <halt>:
  18:	eafffffe 	b	18 <halt>
  1c:	56000050 	undefined instruction 0x56000050
  20:	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 main

halt:
	b halt
	
all:
	arm-linux-gcc -c -o led.o led.c
	arm-linux-gcc -c -o start.o start.S
	arm-linux-ld -Ttext 0 start.o led.o -o led.elf
	arm-linux-objcopy -O binary -S led.elf led.bin
	arm-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-littlearm

Disassembly of section .text:

00000000 <_start>:
   0:	e3a0da01 	mov	sp, #4096	; 0x1000
   4:	eb000000 	bl	c <main>

00000008 <halt>:
   8:	eafffffe 	b	8 <halt>

0000000c <main>:
   c:	e1a0c00d 	mov	ip, sp
  10:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
  14:	e24cb004 	sub	fp, ip, #4	; 0x4
  18:	e24dd008 	sub	sp, sp, #8	; 0x8
  1c:	e3a03456 	mov	r3, #1442840576	; 0x56000000
  20:	e2833050 	add	r3, r3, #80	; 0x50
  24:	e50b3010 	str	r3, [fp, #-16]
  28:	e3a03456 	mov	r3, #1442840576	; 0x56000000
  2c:	e2833054 	add	r3, r3, #84	; 0x54
  30:	e50b3014 	str	r3, [fp, #-20]
  34:	e51b2010 	ldr	r2, [fp, #-16]
  38:	e3a03c01 	mov	r3, #256	; 0x100
  3c:	e5823000 	str	r3, [r2]
  40:	e51b2014 	ldr	r2, [fp, #-20]
  44:	e3a03000 	mov	r3, #0	; 0x0
  48:	e5823000 	str	r3, [r2]
  4c:	e3a03000 	mov	r3, #0	; 0x0
  50:	e1a00003 	mov	r0, r3
  54:	e24bd00c 	sub	sp, fp, #12	; 0xc
  58:	e89da800 	ldmia	sp, {fp, sp, pc}
Disassembly of section .comment:

00000000 <.comment>:
   0:	43434700 	cmpmi	r3, #0	; 0x0
   4:	4728203a 	undefined
   8:	2029554e 	eorcs	r5, r9, lr, asr #10
   c:	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 ,#4
	 bl len_on

	 ldr r0 ,=10000
	 bl Delay

	 mov r0 ,#5
	 bl len_on

halt:
	b halt

led.elf:     file format elf32-littlearm


Disassembly of section .text:

00000000 <_start>:
   0:	e3a0da01 	mov	sp, #4096	; 0x1000
   4:	e59fd018 	ldr	sp, [pc, #24]	; 24 <halt+0x4>
   8:	e3a00004 	mov	r0, #4
   c:	eb000006 	bl	2c <len_on>
  10:	e59f0010 	ldr	r0, [pc, #16]	; 28 <halt+0x8>
  14:	eb000022 	bl	a4 <Delay>
  18:	e3a00005 	mov	r0, #5
  1c:	eb000002 	bl	2c <len_on>

00000020 <halt>:
  20:	eafffffe 	b	20 <halt>
  24:	40001000 	andmi	r1, r0, r0
  28:	00002710 	andeq	r2, r0, r0, lsl r7

0000002c <len_on>:
  2c:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)
  30:	e28db000 	add	fp, sp, #0
  34:	e24dd014 	sub	sp, sp, #20
  38:	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, #4
  54:	1a000002 	bne	64 <len_on+0x38>
  58:	e51b300c 	ldr	r3, [fp, #-12]
  5c:	e3a02c01 	mov	r2, #256	; 0x100
  60:	e5832000 	str	r2, [r3]
  64:	e51b3010 	ldr	r3, [fp, #-16]
  68:	e3530005 	cmp	r3, #5
  6c:	1a000002 	bne	7c <len_on+0x50>
  70:	e51b300c 	ldr	r3, [fp, #-12]
  74:	e3a02b01 	mov	r2, #1024	; 0x400
  78:	e5832000 	str	r2, [r3]
  7c:	e51b3008 	ldr	r3, [fp, #-8]
  80:	e3a02000 	mov	r2, #0
  84:	e5832000 	str	r2, [r3]
  88:	e3a03000 	mov	r3, #0
  8c:	e1a00003 	mov	r0, r3
  90:	e28bd000 	add	sp, fp, #0
  94:	e8bd0800 	pop	{fp}
  98:	e12fff1e 	bx	lr
  9c:	56000050 	undefined instruction 0x56000050
  a0:	56000054 	undefined instruction 0x56000054

000000a4 <Delay>:
  a4:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)
  a8:	e28db000 	add	fp, sp, #0
  ac:	e24dd00c 	sub	sp, sp, #12
  b0:	e50b0008 	str	r0, [fp, #-8]
  b4:	e51b3008 	ldr	r3, [fp, #-8]
  b8:	e3530000 	cmp	r3, #0
  bc:	03a03000 	moveq	r3, #0
  c0:	13a03001 	movne	r3, #1
  c4:	e20330ff 	and	r3, r3, #255	; 0xff
  c8:	e51b2008 	ldr	r2, [fp, #-8]
  cc:	e2422001 	sub	r2, r2, #1
  d0:	e50b2008 	str	r2, [fp, #-8]
  d4:	e3530000 	cmp	r3, #0
  d8:	1afffff5 	bne	b4 <Delay+0x10>
  dc:	e28bd000 	add	sp, fp, #0
  e0:	e8bd0800 	pop	{fp}
  e4:	e12fff1e 	bx	lr

Disassembly of section .ARM.attributes:

00000000 <.ARM.attributes>:
   0:	00002541 	andeq	r2, r0, r1, asr #10
   4:	61656100 	cmnvs	r5, r0, lsl #2
   8:	01006962 	tsteq	r0, r2, ror #18
   c:	0000001b 	andeq	r0, r0, fp, lsl r0
  10:	00543405 	subseq	r3, r4, r5, lsl #8
  14:	01080206 	tsteq	r8, r6, lsl #4
  18:	04120109 	ldreq	r0, [r2], #-265	; 0x109
  1c:	01150114 	tsteq	r5, r4, lsl r1
  20:	01180317 	tsteq	r8, r7, lsl r3
  24:	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	; 0x820
   8:	312d676e 	teqcc	sp, lr, ror #14
   c:	312e362e 	teqcc	lr, lr, lsr #12
  10:	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, =0x53000000
	ldr r1, =0
	str r1, [r0]

 /*设置内存: sp栈* 我们判断是nor启动还是nand启动/

	mov r1, #0
	ldr 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 main


halt:
	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,=0X56000050
	ldr r0,=0x100
	str r0,[r1]
/*
*配置GPFDAT寄存器为低电平(0x56000054)--输出低电平
*/
	ldr r1,=0x56000054
	ldr r0,=0
	str r0,[r1]
	/*死循环*/
halt:
	b halt
	
		

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

postgresql|数据库|提升查询性能的物化视图解析

前言&#xff1a; 我们一般认为数字的世界是一个虚拟的世界&#xff0c;OK&#xff0c;但我们其实有些需求是和现实世界一模一样的&#xff0c;比如&#xff0c;数据库尤其是关系型数据库&#xff0c;希望在使用的数据库能够更快&#xff08;查询速度&#xff09;&#xff0c;…

亚马逊云AI应用科技创新下的Amazon SageMaker使用教程

目录 Amazon SageMaker简介 Amazon SageMaker在控制台的使用 模型的各项参数 pytorch训练绘图部分代码 Amazon SageMaker简介 亚马逊SageMaker是一种完全托管的机器学习服务。借助 SageMaker&#xff0c;数据科学家和开发人员可以快速、轻松地构建和训练机器学习模型&#…

765. 情侣牵手

765. 情侣牵手&#xff08;leetcode,数学思维题&#xff09;-------------------Java实现 题目表述 n 对情侣坐在连续排列的 2n 个座位上&#xff0c;想要牵到对方的手。 人和座位由一个整数数组 row 表示&#xff0c;其中 row[i] 是坐在第 i 个座位上的人的 ID。情侣们按顺…

头歌答案--爬虫实战

目录 urllib 爬虫 第1关&#xff1a;urllib基础 任务描述 第2关&#xff1a;urllib进阶 任务描述 requests 爬虫 第1关&#xff1a;requests 基础 任务描述 第2关&#xff1a;requests 进阶 任务描述 网页数据解析 第1关&#xff1a;XPath解析网页 任务描述 第…

汉明距离(Java)

两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y&#xff0c;计算并返回它们之间的汉明距离。 方法1:使用内置函数 class Solution {public int hammingDistance(int x, int y) {return Integer.bitCount(x ^ y);} }方法2:移位实…

技能培训知识付费服务预约小程序的效果如何

技能、证书往往是很多人生活的基本&#xff0c;行业岗位竞争激烈&#xff0c;每个人都希望有多种技能或工作所需&#xff0c;而需求持续增加下&#xff0c;相关技能培训机构也很多&#xff0c;比如常见的考证、钢琴培训、针灸培训、花艺培训等。 很多行业都需要学习或考证&…

mac homebrew.mxcl.php@5.6.plist

今天启动php5.6时 遇到了一个问题 servers % brew services start php5.6 Bootstrap failed: 5: Input/output error Try re-running the command as root for richer errors. Error: Failure while executing; /bin/launchctl bootstrap gui/501 /Users/ssh/Library/LaunchAge…

Spring源码系列-Spring事务

目录 声明式事务 事务传播行为 源码解析 开启事务 调用顺序 EnableTransactionManagement注解的两个作用 引入AutoProxyRegistrar后置处理器 引入ProxyTransactionManagerConfiguration配置类 加载切面 事务的Advisor的注册 事务Advice 事务PointCut 创建动态代理…

编程知识\_C与汇编深入分析

1. 汇编怎么调用C函数 1.1 直接调用 bl main 1.2 想传参数怎么办&#xff1f; 在arm中有个ATPCS规则(ARM-THUMB procedure call standard&#xff08;ARM-Thumb过程调用标准&#xff09;。 约定r0-r15寄存器的用途&#xff1a; r0-r3 调用者和被调用者之间传参数 r4-r11 函…

理解王自如,希望成为王自如

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 昨天看了王自如的采访视频&#xff0c;这两天刷了很多屏。 王自如说&#xff1a;我没看过格力给的工资条。在顶级的企业家身边工作&#xff0c;哪怕每天只是听她讲什么做什么&#xff0c;我都觉得是…

“富婆”通讯录——让你少奋斗50年

文章目录 一、项目需求分析二、通讯录各功能实现思路及代码准备工作2.1、打印一个菜单&#xff0c;提供用户选择功能2.2、添加联系人信息2.3、删除联系人信息2.4、查询联系人信息2.5、修改联系人信息2.6、显示所有联系人信息2.7、对所有联系人信息进行排序整理2.8、删除所有联系…

python速成

list类型中所有的方法(除sort之外)&#xff0c; 每一个方法附带一个实例&#xff1a;以及解释说明 append append(self, object, /) Append object to the end of the list. clear clear(self, /) Remove all items from list. 从列表中删除所有项目。 list_data [1,…

【开放视频+文档】Spinnaker多云持续部署实践

Hello, 首先&#xff0c;继续感谢大家持续的关注&#xff01; 这次我们已经将《Spinnaker实践》课程 实践文档课程笔记实验源码视频回放 全部免费开放给所有的技术人员。文档库视频基于语雀&#xff0c;扫描图片二维码可以获取语雀文档链接“https://www.yuque.com/devopsgr…

宋浩高等数学笔记(一)函数与极限

b站宋浩老师的高等数学网课&#xff0c;全套笔记已记完&#xff0c;不定期复习并发布更新。 章节顺序与同济大学第七版教材所一致。 目录 1.1映射与函数 1.2数列的极限 1.3函数的极限 1.4无穷小和无穷大 1.5极限运算准则 1.6极限存在准则and两个重要极限 1.7无穷小 1…

Java中的 向上转型 | 向下转型

目录 一.向上转型 直接赋值 总结&#xff1a; 通过传参 通过返回值 二.向下转型 instanceof 一.向上转型 向上转型其实就是创建一个子类对象&#xff0c;并将其当作父类对象来使用&#xff0c;一般语法格式如下&#xff1a; 父类类型 对象名 new 子类类型() 一般有以…

13. 高精度延时

13. 高精度延时 GPT 定时器简介GPT 定时器结构GPT 定时器工作模式 GPT 定时器相关寄存器GPTx_CRGPTx_PRGPTx_SRGPTx_CNTGPTx_OCR GPT 配置步骤程序编写bsp_delay.hbsp_delay.cmain GPT 定时器简介 GPT 定时器是一个 32 位向上定时器&#xff0c;也就是从0x00000000 开始向上递…

CCF ChinaSoft 2023 论坛巡礼 | CCF-华为胡杨林基金-形式化方法专项(海报)论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

Java实现音频转码,WAV、MP3、AMR互转

1.背景 最近在集成一款产品支持语音双向对讲&#xff0c;首先是采集小程序的音频下发给设备端&#xff0c;然后可以控制设备录音生成音频链路让小程序播放。在这个过程中发现&#xff0c;设备除了AMR格式的音频外&#xff0c;其他的音频都不支持&#xff0c;而微信小程序有不支…

LangChain应用全解析

一、Langchain基础 1.Langchain简介 (1)替换模型 from langchain.prompts import ChatPromptTemplatechat ChatOpenAI(temperature0) 使用代理ip llm ChatOpenAI(model_name"gpt-3.5-turbo", max_tokens2048, temperature0.5,openai_api_keyapi_key,openai_ap…

docker stop slow 解决

验证 NanoMQ stop slow 的问题 daemon 和非 daemon 两种方式 docker stop 都很慢 疑问是默认情况下&#xff0c;SIGTERM 会被处理。 模拟 docker 内发送 SIGTERM 信号 # The default signal for kill is TERM # pkill will send the specified signal (by defau…