assembly 使用裸机组件在RP2040上启动Core 1

e7arh2l6  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(122)

根据我对documentation,2.8.2的理解,启动内核1的过程是通过FIFO发送一个值序列,最后的3个值是向量表、堆栈指针和入口点,而内核1会将这些值回送给您。
从文档提供的C代码中,我写出了这个程序集:

.cpu cortex-m0
    .thumb
ent:
    ldr r0, =0x20001000
    mov sp, r0              @init stack pointer

    ldr r0, =0xe000ed08
    ldr r3, [r0]            @vector table offset register
core:
    mov r7, pc
    b fifo_drain
    sev
    mov r1, #0
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #0
    bne core

    mov r7, pc
    b fifo_drain
    sev
    mov r1, #0
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #0
    bne core

    mov r1, #1
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #1
    bne core

    mov r1, r3              @vector table
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, r3
    bne core

    mov r1, sp              @stack pointer
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, sp
    bne core

    mov r1, pc
    add r1, #2              @entry point
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read

    ldr r0, =0xd0000000
    ldr r1, [r0]
    cmp r1, #1
    beq led

通过FIFO发送的值序列为{0,0,1,vt,sp,ent},当值没有返回时,序列重新开始。入口点仅为最后4行,内核从SIO读取CPUID寄存器,如果CPU id为1,则打开LED(GPIO 25)。
这个序列似乎在向量表的循环中卡住了,这是有道理的,因为我几乎不理解它,FIFO只是不回显它。而且,文档在入口点旁边有一个注解,上面写着“不要忘记thumb位!",不管这是什么意思。
编辑:
更新代码,相同问题:

.cpu cortex-m0
    .thumb
ent:
    ldr r0, =0x20001000
    mov sp, r0              @init stack pointer

    ldr r0, =0xe000ed08
    ldr r1, =0x20000000
    str r1, [r0]            @init vtor

    ldr r0, =0xd0000000
    ldr r1, [r0]
    cmp r1, #1
    beq led
    
    b core
    
.thumb_func
core:
    mov r7, pc
    b fifo_drain
    mov r1, #0
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #0
    bne core
    
    mov r7, pc
    b fifo_drain
    mov r1, #0
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #0
    bne core
    
    mov r1, #1
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #1
    bne core
    
    ldr r3, =0x20000000
    mov r1, r3              @vector table
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, r3
    bne core
    
    mov r1, sp              @stack pointer
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, sp
    bne core
    
    ldr r3, =0x20000001
    mov r1, r3              @entry point
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, r3
    bne core
    
    b loop
    
.thumb_func
fifo_stat:
    ldr r0, =0xd0000050
    ldr r1, [r0]
    mov r2, #15
    and r1, r1, r2
    mov pc, r7

.thumb_func
fifo_writ:
    ldr r0, =0xd0000050
    ldr r3, [r0]
    mov r2, #2
    and r3, r3, r2
    beq fifo_writ
    
    ldr r0, =0xd0000054
    str r1, [r0]
    sev
    mov pc, r7

.thumb_func
fifo_read:
    ldr r0, =0xd0000050
    ldr r3, [r0]
    mov r2, #1
    and r3, r3, r2
    beq _wfe

    ldr r0, =0xd0000058
    ldr r1, [r0]
    mov pc, r7

.thumb_func
fifo_drain:
    ldr r0, =0xd0000058
    ldr r1, [r0]
    ldr r0, =0xd0000050
    ldr r1, [r0]
    mov r2, #1
    and r1, r1, r2
    bne fifo_drain
    sev
    mov pc, r7
    
.thumb_func
_wfe:
    wfe
    b fifo_read

.thumb_func
led:
    movs r1, #32            @io_bank
    ldr r0, =0x4000f000
    str r1, [r0]            @release reset on io_bank

    movs r1, #5             @sio
    ldr r0, =0x400140cc
    str r1, [r0]            @assign sio to gpio25_ctrl

    movs r1, #1
    lsl r1, r1, #25
    
    ldr r0, =0xd0000024
    str r1, [r0]            @enable output

    ldr r0, =0xd0000014
    str r1, [r0]            @turn on the led
    
.thumb_func
loop:
    nop
    b loop
eoxn13cs

eoxn13cs1#

我的核心零代码是C和汇编语言的混合体。我想我们可以解决你的问题。
我的引导程序看起来像这样

.cpu cortex-m0
.thumb

    ldr r1,=0xD0000000 ;@SIO_CPUID
    ldr r0,[r1]
    cmp r0,#0
    bne core_one

    ;@ core_zero
    ldr r0,=0x20002000
    mov sp,r0
    bl zero_entry
    b .

core_one:
    ;@ core_one
    bl notmain
    b .

.align
.ltorg

;@ ----------------------------------
.balign 0x100

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

.globl SEV
.thumb_func
SEV:
    sev
    bx lr

.globl WFE
.thumb_func
WFE:
    wfe
    bx lr

.globl DELAY
.thumb_func
DELAY:
    sub r0,#1
    bne DELAY
    bx lr

我链接了0x 20000000,并为sram/0x 20000000构建了uf 2文件,作为二进制文件的目的地。
我的核心零代码看起来像这样

extern void PUT32 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );

extern void SEV ( void );
extern void WFE ( void );

#define SIO_BASE                    0xD0000000

#define SIO_FIFO_ST                 (SIO_BASE+0x50)
#define SIO_FIFO_WR                 (SIO_BASE+0x54)
#define SIO_FIFO_RD                 (SIO_BASE+0x58)

static void fifo_flush ( void )
{
    while(1)
    {
        if((GET32(SIO_FIFO_ST)&0x1) == 0) break; //zero if empty
        GET32(SIO_FIFO_RD);
    }
    SEV();
}

static unsigned int fifo_send ( unsigned int cmd )
{
    while(1)
    {
        if((GET32(SIO_FIFO_ST)&0x2) != 0) break; //one if ready
    }
    PUT32(SIO_FIFO_WR,cmd);
    SEV();
    while(1)
    {
        if((GET32(SIO_FIFO_ST)&0x1) == 0) //zero if  empty
        {
            WFE();
        }
        else
        {
            break;
        }
    }
    return(GET32(SIO_FIFO_RD));
}

unsigned int zero_entry ( void )
{
    unsigned int ra;

    while(1)
    {
        fifo_flush();
        ra=fifo_send(0);
        if(ra!=0) continue;
        fifo_flush();
        ra=fifo_send(0);
        if(ra!=0) continue;
        ra=fifo_send(1);
        if(ra!=1) continue;
        ra=fifo_send(0x20000000); //vector_table
        if(ra!=0x20000000) continue;
        ra=fifo_send(0x20003000);    //stack pointer
        if(ra!=0x20003000) continue;
        ra=fifo_send(0x20000001);    //entry
        if(ra!=0x20000001) continue;
        break;
    }
    return(0);
}

如果感兴趣的话,我的核心代码看起来像这样

void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
void DELAY ( unsigned int );

#define RESETS_BASE                 0x4000C000

#define RESETS_RESET_RW             (RESETS_BASE+0x0+0x0000)
#define RESETS_RESET_XOR            (RESETS_BASE+0x0+0x1000)
#define RESETS_RESET_SET            (RESETS_BASE+0x0+0x2000)
#define RESETS_RESET_CLR            (RESETS_BASE+0x0+0x3000)

#define RESETS_WDSEL_RW             (RESETS_BASE+0x4+0x0000)
#define RESETS_WDSEL_XOR            (RESETS_BASE+0x4+0x1000)
#define RESETS_WDSEL_SET            (RESETS_BASE+0x4+0x2000)
#define RESETS_WDSEL_CLR            (RESETS_BASE+0x4+0x3000)

#define RESETS_RESET_DONE_RW        (RESETS_BASE+0x8+0x0000)
#define RESETS_RESET_DONE_XOR       (RESETS_BASE+0x8+0x1000)
#define RESETS_RESET_DONE_SET       (RESETS_BASE+0x8+0x2000)
#define RESETS_RESET_DONE_CLR       (RESETS_BASE+0x8+0x3000)

#define SIO_BASE                    0xD0000000

#define SIO_GPIO_OUT_RW             (SIO_BASE+0x10)
#define SIO_GPIO_OUT_SET            (SIO_BASE+0x14)
#define SIO_GPIO_OUT_CLR            (SIO_BASE+0x18)
#define SIO_GPIO_OUT_XOR            (SIO_BASE+0x1C)

#define SIO_GPIO_OE_RW              (SIO_BASE+0x20)
#define SIO_GPIO_OE_SET             (SIO_BASE+0x24)
#define SIO_GPIO_OE_CLR             (SIO_BASE+0x28)
#define SIO_GPIO_OE_XOR             (SIO_BASE+0x2C)

#define IO_BANK0_BASE               0x40014000

#define IO_BANK0_GPIO25_STATUS_RW   (IO_BANK0_BASE+0x0C8+0x0000)
#define IO_BANK0_GPIO25_STATUS_XOR  (IO_BANK0_BASE+0x0C8+0x1000)
#define IO_BANK0_GPIO25_STATUS_SET  (IO_BANK0_BASE+0x0C8+0x2000)
#define IO_BANK0_GPIO25_STATUS_CLR  (IO_BANK0_BASE+0x0C8+0x3000)

#define IO_BANK0_GPIO25_CTRL_RW     (IO_BANK0_BASE+0x0CC+0x0000)
#define IO_BANK0_GPIO25_CTRL_XOR    (IO_BANK0_BASE+0x0CC+0x1000)
#define IO_BANK0_GPIO25_CTRL_SET    (IO_BANK0_BASE+0x0CC+0x2000)
#define IO_BANK0_GPIO25_CTRL_CLR    (IO_BANK0_BASE+0x0CC+0x3000)

int notmain ( void )
{
    //release reset on IO_BANK0
    PUT32(RESETS_RESET_CLR,1<<5); //IO_BANK0
    //wait for reset to be done
    while(1)
    {
        if((GET32(RESETS_RESET_DONE_RW)&(1<<5))!=0) break;
    }

    //output disable
    PUT32(SIO_GPIO_OE_CLR,1<<25);
    //turn off pin 25
    PUT32(SIO_GPIO_OUT_CLR,1<<25);

    //set the function select to SIO (software controlled I/O)
    PUT32(IO_BANK0_GPIO25_CTRL_RW,5);

    //output enable
    PUT32(SIO_GPIO_OE_SET,1<<25);
    while(1)
    {
        //turn on the led
        PUT32(SIO_GPIO_OUT_SET,1<<25);
        DELAY(0x100000);
        //turn off the led
        PUT32(SIO_GPIO_OUT_CLR,1<<25);
        DELAY(0x100000);
    }
    return(0);
}

thumb位是什么意思?如果您查看ARM文档中的bx指令或其他相关信息(armv 6-m架构参考手册)。这回到了可以运行arm和thumb代码的全尺寸核心。由于两种模式中的指令是对齐的,因此它们选择使用lsbit用于按地址分支,以确定在分支目的地使用的模式(最初只有bx指令,但后来pop和其他指令)。如果lsbit被设置,则它分支到thumb指令,如果被重置,则分支到arm指令。
他们选择的cortex-ms采用向量表(根据产品的目标市场而定),而不是像之前的全尺寸内核(ARM 7、ARM9、ARM 10、ARM 11)那样采用硬编码地址。正如架构参考手册中所述,第一个字是一个值,放入堆栈指针中以保存 Boot 过程中的该步骤,第二个字是复位向量。
现在ARM选择这样做,你必须把一个thumb函数指针地址在那里,这意味着lsbit是ORRed与一。我强调ORRed与一,而不是加一,因为如果你使用你的工具正确(IMO),然后工具将设置lsbit和加一,你会打破它。
让工具完成工作

.cpu cortex-m0
.thumb

.thumb_func
.global _start
_start:
.word 0x20001000
.word reset
.word hang
.word hang

.word hang
.word hang
.word hang
.word hang

.word hang
.word hang
.word hang
.word hang

.word hang
.word hang
.word hang
.word hang

.thumb_func
reset:
    bl notmain
    b hang
.thumb_func
hang:   b .

(This不工作在一个皮科,这是一个什么是拇指它的意思)。
.thumb_func使它在代码中找到的下一个标签成为thumb函数地址,而不仅仅是普通的旧地址。
因此,这给出了

00200000 <_start>:
  200000:   20001000    andcs   r1, r0, r0
  200004:   00200041    eoreq   r0, r0, r1, asr #32
  200008:   00200047    eoreq   r0, r0, r7, asr #32
  20000c:   00200047    eoreq   r0, r0, r7, asr #32
  200010:   00200047    eoreq   r0, r0, r7, asr #32
  200014:   00200047    eoreq   r0, r0, r7, asr #32
  200018:   00200047    eoreq   r0, r0, r7, asr #32
  20001c:   00200047    eoreq   r0, r0, r7, asr #32
  200020:   00200047    eoreq   r0, r0, r7, asr #32
  200024:   00200047    eoreq   r0, r0, r7, asr #32
  200028:   00200047    eoreq   r0, r0, r7, asr #32
  20002c:   00200047    eoreq   r0, r0, r7, asr #32
  200030:   00200047    eoreq   r0, r0, r7, asr #32
  200034:   00200047    eoreq   r0, r0, r7, asr #32
  200038:   00200047    eoreq   r0, r0, r7, asr #32
  20003c:   00200047    eoreq   r0, r0, r7, asr #32

00200040 <reset>:
  200040:   f000 f81a   bl  200078 <notmain>
  200044:   e7ff        b.n 200046 <hang>

00200046 <hang>:
  200046:   e7fe        b.n 200046 <hang>

为不同的MCU构建和链接,而不是pci。重置在0x 00200040,挂起在0x 00200046。工具已经为我们完成了工作,因为我们使用了.thumb_func,并将地址orred与一个放在一起。
一切都很好,这个MCU将 Boot ,或者至少它不会挂后重置的权利。
更长的方法是,没有.arm_func,所以对于ARM和thumb,您可以改为

.type reset,%function
reset:

它不一定要紧接在标签之前,但您必须做额外的工作来键入标签名称。
如果我把你的代码改成这样:

ldr r1, =one_entry
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read

.thumb_func
one_entry:
    ldr r0, =0xd0000000
    ldr r1, [r0]
    cmp r1, #1
    beq led

然后我得到

2000005a:   4907        ldr r1, [pc, #28]   ; (20000078 <one_entry+0x14>)
2000005c:   467f        mov r7, pc
2000005e:   e011        b.n 20000084 <fifo_writ>
20000060:   467f        mov r7, pc
20000062:   e00e        b.n 20000082 <fifo_read>

20000064 <one_entry>:
20000064:   4805        ldr r0, [pc, #20]   ; (2000007c <one_entry+0x18>)
20000066:   6801        ldr r1, [r0, #0]
20000068:   2901        cmp r1, #1
2000006a:   d00c        beq.n   20000086 <led>
2000006c:   e7fe        b.n 2000006c <one_entry+0x8>
2000006e:   46c0        nop         ; (mov r8, r8)
20000070:   20001000    andcs   r1, r0, r0
20000074:   e000ed08    and lr, r0, r8, lsl #26
20000078:   20000065    andcs   r0, r0, r5, rrx
2000007c:   d0000000    andle   r0, r0, r0

该工具已创建了核心1的入口点地址,并设置了lsbit。20000065
接下来的问题是

mov r1, sp              @stack pointer

在核心0执行的这一点上,您正在获取核心0堆栈指针地址,并为核心1设置该地址。如果在启动核心1后在无限循环中结束核心0,那么这就可以了,但是如果你想继续用核心0做事情,你需要给予核心1它自己的堆栈指针。在我的示例中,您可以看到,我将内核0指定为0x 20002000,将内核1指定为0x 20003000。这将非常难以调试,因为内核1将启动,但每次更改代码时,都会出现随机混乱。
还有你的VTOR问题。我也试过只阅读VTOR,但它不起作用。最初我的代码有一个特殊的向量表:

.globl vector_table
vector_table:
    b reset
    .balign 4
    .word reset ;@ has to be offset 4
    .word loop
    .word loop
    .word loop

我设置了向量表,而不是读取它

ldr r1,=0xE000ED08 ;@ VTOR
ldr r0,=vector_table
str r0,[r1]

对于core zero,它可能是从我写的其他皮科代码中借用的,这些代码可能实际上使用了这个表。b重置是因为我们实际上没有使用core zero的重置向量,所以这是我的组装。可以做对齐的工作,并将向量表放在内存中的其他地方(是的,对于两个内核,最初我自己设置了堆栈指针,但对于上面的示例,假设内核1自己设置)。
并对核心1使用相同的地址vector_table。在这种情况下,我可以读取它,它会工作。您只提供了一个分数,因此我们不知道您在此代码之前对核心0的VTOR做了什么,但我假设您没有设置它,因为您的代码不工作。
在这些例子中,你/我们没有使用向量表,所以只需要让它高兴,所以我只是强制0x 20000000,然后它就工作了。
我相信你需要修正所有三个地址,向量表,入口点,和堆栈指针,以获得成功。
根据你的重写,我做了这些修改。

.cpu cortex-m0
    .thumb
ent:
    ldr r0, =0x20001000
    mov sp, r0              @init stack pointer

    ldr r0, =0xe000ed08
    ldr r1, =0x20000000
    str r1, [r0]            @init vtor

    ldr r0, =0xd0000000
    ldr r1, [r0]
    cmp r1, #1
    beq led

    b core

.thumb_func
core:
    mov r7, pc
    b fifo_drain
    mov r1, #0
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #0
    bne core

    mov r7, pc
    b fifo_drain
    mov r1, #0
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #0
    bne core

    mov r1, #1
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, #1
    bne core

    ldr r4, =0x20000000
    mov r1, r4              @vector table
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, r4
    bne core

    mov r4, sp              @stack pointer
    mov r1, r4
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, r4
    bne core

    ldr r4, =0x20000001
    mov r1, r4              @entry point
    mov r7, pc
    b fifo_writ
    mov r7, pc
    b fifo_read
    cmp r1, r4
    bne core

    b loop

.thumb_func
fifo_stat:
    ldr r0, =0xd0000050
    ldr r1, [r0]
    mov r2, #15
    and r1, r1, r2
    mov pc, r7

.thumb_func
fifo_writ:
    ldr r0, =0xd0000050
    ldr r3, [r0]
    mov r2, #2
    and r3, r3, r2
    beq fifo_writ

    ldr r0, =0xd0000054
    str r1, [r0]
    sev
    mov pc, r7

.thumb_func
fifo_read:
    ldr r0, =0xd0000050
    ldr r3, [r0]
    mov r2, #1
    and r3, r3, r2
    beq _wfe

    ldr r0, =0xd0000058
    ldr r1, [r0]
    mov pc, r7

.thumb_func
fifo_drain:
    ldr r0, =0xd0000058
    ldr r1, [r0]
    ldr r0, =0xd0000050
    ldr r1, [r0]
    mov r2, #1
    and r1, r1, r2
    bne fifo_drain
    sev
    mov pc, r7

.thumb_func
_wfe:
    wfe
    b fifo_read

;@ ----------------------------------
.balign 0x100

.thumb_func
led:
    movs r1, #32            @io_bank
    ldr r0, =0x4000f000
    str r1, [r0]            @release reset on io_bank

    movs r1, #5             @sio
    ldr r0, =0x400140cc
    str r1, [r0]            @assign sio to gpio25_ctrl

    movs r1, #1
    lsl r1, r1, #25

    ldr r0, =0xd0000024
    str r1, [r0]            @enable output

    ldr r0, =0xd0000014
    str r1, [r0]            @turn on the led

.thumb_func
loop:
    nop
    b loop

首先,在一些地方,你使用r3来保存你想在写和阅读回之后进行比较的值。但是r3在写和读中都被使用,所以它的内容丢失了。
第二,程序大于0x 100字节,有一些奇怪的东西,我必须了解我是如何弄清楚的,所以通过避免边界,然后它的工作。
正如上面使用的sp不需要去r4,但我这样做是为了猎枪的问题。

如果我删除不需要的项(写入VTOR,a B核心在前面。我使用bl和bx lr来调用和返回,这节省了足够的指令,使二进制小于0x 100字节。它可以在没有边界的情况下使用。

.cpu cortex-m0
    .thumb
ent:
    ldr r0, =0x20001000
    mov sp, r0              @init stack pointer

    ldr r0, =0xd0000000
    ldr r1, [r0]
    cmp r1, #1
    beq led

core:
    bl fifo_drain
    mov r1, #0
    bl fifo_writ
    bl fifo_read
    cmp r1, #0
    bne core

    b fifo_drain
    mov r1, #0
    bl fifo_writ
    bl fifo_read
    cmp r1, #0
    bne core

    mov r1, #1
    bl fifo_writ
    bl fifo_read
    cmp r1, #1
    bne core

    ldr r4, =0x20000000
    mov r1, r4              @vector table
    bl fifo_writ
    bl fifo_read
    cmp r1, r4
    bne core

    mov r1, sp              @stack pointer
    bl fifo_writ
    bl fifo_read
    cmp r1, sp
    bne core

    ldr r4, =0x20000001
    mov r1, r4              @entry point
    bl fifo_writ
    bl fifo_read
    cmp r1, r4
    bne core

    b loop

fifo_stat:
    ldr r0, =0xd0000050
    ldr r1, [r0]
    mov r2, #15
    and r1, r1, r2
    bx lr

fifo_writ:
    ldr r0, =0xd0000050
    ldr r3, [r0]
    mov r2, #2
    and r3, r3, r2
    beq fifo_writ

    ldr r0, =0xd0000054
    str r1, [r0]
    sev
    bx lr

fifo_read:
    ldr r0, =0xd0000050
    ldr r3, [r0]
    mov r2, #1
    and r3, r3, r2
    beq _wfe

    ldr r0, =0xd0000058
    ldr r1, [r0]
    bx lr

fifo_drain:
    ldr r0, =0xd0000058
    ldr r1, [r0]
    ldr r0, =0xd0000050
    ldr r1, [r0]
    mov r2, #1
    and r1, r1, r2
    bne fifo_drain
    sev
    bx lr

_wfe:
    wfe
    bl fifo_read

led:
    movs r1, #32            @io_bank
    ldr r0, =0x4000f000
    str r1, [r0]            @release reset on io_bank

    movs r1, #5             @sio
    ldr r0, =0x400140cc
    str r1, [r0]            @assign sio to gpio25_ctrl

    movs r1, #1
    lsl r1, r1, #25

    ldr r0, =0xd0000024
    str r1, [r0]            @enable output

    ldr r0, =0xd0000014
    str r1, [r0]            @turn on the led

loop:
    nop
    b loop

请注意,指令集允许执行以下操作:

fifo_drain:
    ldr r0, =0xd0000050
    ldr r1, [r0,#8] @0xd0000058
    ldr r1, [r0] @0xd0000050
    mov r2, #1
    and r1, r1, r2
    bne fifo_drain
    sev
    bx lr

不像蛮力和简单的阅读,但节省指令。
对于一个刚刚学习ARM汇编语言的人来说,我认为rp 2040在同一时间。我印象深刻,继续出色的工作。这个特别的MCU非常非常酷,但也很差的文件。ARM指令集是有文件的,但与ARM对比拇指,然后统一语法对比没有(幸运的是你没有击中差异)。而这个0x 100字节的东西,我不记得我是怎么弄明白的,我想我看了他们的代码,并从中弄明白了,但我得重新调查一下如果你想亲自确认取一个0x 100字节以下的版本,然后在正文中的某个地方添加一些nop,使其延伸到0x 100字节以上。请注意所描述的简单更改,并删除未使用的/我把你的密码弄到了

216 bytes read (0xD8)

216字节......
最低限度。
你对这三个参数的想法是正确的,但它们需要一些工作。然后是一个简单的哎呀,在一个函数调用之外使用一个寄存器,在一个函数调用之内使用。然后是疯狂的0x 100字节的事情。这是裸机的事情,很难调试,必须磨你的方式通过,不要给予。
mov r7,pc的事情,我其实印象深刻,而不是批评-很多人会挣扎与两个指令提前的事情。

相关问题