ARM Cortex M4 SVC指令作用

2023-05-16

(1)SVC指令:

摘自 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0203ic/Cacdfeci.html

与更早版本的 ARM 处理器一样,有一条 SVC 指令可生成 SVC。 SVC 通常用于在操作系统上请求特权操作或访问系统资源。

SVC 指令中嵌入了一个数字,这个数字通常称为 SVC 编号。 在大多数 ARM 处理器上,此编号用于指示要请求的服务。在微控制器架构上,处理器在最初进入异常时,将参数寄存器保存到堆栈中。

在 SVC 处理程序执行第一个指令之前较晚处理的异常可能会损坏 R0 到 R3 中仍保存的参数副本。 这表示参数的堆栈副本必须由 SVC 处理程序使用。 还必须通过修改堆栈中的寄存器值将任何返回值传递回调用方。 为此,必须在 SVC 处理程序的开头实现一小段汇编代码。这样可以确定寄存器的保存位置,从指令中提取 SVC 编号,并将编号和参数指针传递到用 C 编写的处理程序主体中。

Example 6.21 是一个 SVC 处理程序示例。 这段代码测试处理器所设置的 EXC_RETURN 值,确定在调用 SVC 时,使用的是哪个堆栈指针。这对于重入 SVC 可能很有用,但在大多数系统上是不必要的,因为在典型系统设计中,只会从使用进程堆栈的用户代码中调用 SVC。在这种情况下,汇编代码可以包含单条 MSR 指令,后跟指向处理程序 C 程序体的尾调用跳转(B 指令)。

Example 6.21. SVC 处理程序示例

__asm void SVCHandler(void)
{
    IMPORT SVCHandler_main
    TST lr, #4
    ITE EQ
    MRSEQ R0, MSP
    MRSNE R0, PSP
    B SVCHandler_main
}
void SVCHandler_main(unsigned int * svc_args)
{
    unsigned int svc_number;
    /*
    * Stack contains:
    * R0, R1, R2, R3, R12, R14, the return address and xPSR
    * First argument (R0) is svc_args[0]
    */
    svc_number = ((char *)svc_args[6])[-2];
    switch(svc_number)
    {
        case SVC_00:
            /* Handle SVC 00 */
            break;
        case SVC_01:
            /* Handle SVC 01 */
            break;
        default:
            /* Unknown SVC */
            break;
    }
}


Example 6.22 演示如何为很多 SVC 进行不同声明。 __svc 是编译器关键字,该关键字将函数调用替换为包含指定编号的 SVC 指令。

Example 6.22. 在 C 代码中调用 SVC 的示例

#define SVC_00 0x00
#define SVC_01 0x01
void __svc(SVC_00) svc_zero(const char *string);
void __svc(SVC_01) svc_one(const char *string);
int call_system_func(void)
{
    svc_zero("String to pass to SVC handler zero");
    svc_one("String to pass to a different OS function");

 SVC 处理程序
发生异常时,异常处理程序可能需要确定处理器是在 ARM 状态还是在 Thumb 状态。

特别是 SVC 处理程序,更需要读取处理器状态。 通过检查 SPSR 的 T 位可确定处理器状态。 该位在 Thumb 状态时为 1,在 ARM 状态时为 0。

ARM 和 Thumb 指令集均有 SVC 指令。 在 Thumb 状态下调用 SVC 时,必须考虑以下情况:

指令的地址在 lr–2,而不在 lr–4。

该指令本身为 16 位,因而需要半字加载,请参阅Figure 6.3。

在 ARM 状态下,SVC 编号以 8 位存储,而不是 24 位。

Figure 6.3. Thumb SVC 指令
Example 6.8 演示处理 SVC 异常的 ARM 代码。 通过动态调用 SVC,可以增大 Thumb 状态下可访问的 SVC 编号的范围。
Example 6.8. SVC 处理程序
    PRESERVE8
    AREA SVC_Area, CODE, READONLY
    EXPORT SVC_Handler    IMPORT C_SVC_Handler
T_bit   EQU    0x20                    ; Thumb bit (5) of CPSR/SPSR.
SVC_Handler
    STMFD   sp!, {r0-r3, r12, lr}  ; Store registers
    MOV     r1, sp                 ; Set pointer to parameters
    MRS     r0, spsr               ; Get spsr
    STMFD   sp!, {r0, r3}          ; Store spsr onto stack and another
                                   ; register to maintain 8-byte-aligned stack
    TST     r0, #T_bit             ; Occurred in Thumb state?
    LDRNEH  r0, [lr,#-2]           ; Yes: Load halfword and...
    BICNE   r0, r0, #0xFF00        ; ...extract comment field
    LDREQ   r0, [lr,#-4]           ; No: Load word and...
    BICEQ   r0, r0, #0xFF000000    ; ...extract comment field

    ; r0 now contains SVC number
    ; r1 now contains pointer to stacked registers

    BL      C_SVC_Handler          ; Call main part of handler
    LDMFD   sp!, {r0, r3}          ; Get spsr from stack
    MSR     SPSR_cxsf, r0               ; Restore spsr
    LDMFD   sp!, {r0-r3, r12, pc}^ ; Restore registers and return
    END


确定要调用的 SVC
进入 SVC 处理程序后,必须确定要调用哪个 SVC。 此信息可存储在指令本身的 0-23 位,如Figure 6.4 所示,或将其传递给某个整数寄存器,通常为 R0-R3 中的一个。

Figure 6.4. ARM SVC 指令

顶层 SVC 处理程序可以相对于 LR 加载 SVC 指令 请用汇编语言、C/C++ 内联或嵌入式汇编器编写。
处理程序必须首先将导致异常的 SVC 指令加载到寄存器中。 此时,SVC LR 保存 SVC 指令的下一个指令的地址,这样 SVC 加载到了寄存器(本例中为 R0)中,代码如下:
    LDR R0, [lr,#-4]
然后,处理程序可检查注释字段位,以决定所需的操作。 通过清除操作码的前八位来提取 SVC 编号:

    BIC R0, R0, #0xFF000000
Example 6.9 演示如何用这些指令编写顶层 SVC 处理程序。 有关在 ARM 状态和 Thumb 状态下处理 SVC 指令的处理程序示例,请参阅Example 6.8。

Example 6.9. 顶层 SVC 处理程序

    PRESERVE8
    AREA TopLevelSVC, CODE, READONLY   ; Name this block of code.
    EXPORT     SVC_Handler
SVC_Handler
    PUSH       {R0-R12,lr}             ; Store registers.
    LDR        R0,[lr,#-4]             ; Calculate address of SVC instruction
                                       ; and load it into R0.
    BIC        R0,R0,#0xFF000000       ; Mask off top 8 bits of instruction
                                       ; to give SVC number.
    ;
    ; Use value in R0 to determine which SVC routine to execute.
    ;
    LDM         sp!, {R0-R12,pc}^      ; Restore registers and return.
    END

汇编语言编写的 SVC 处理程序
要调用请求的 SVC 编号的处理程序,最简单的方法是使用跳转表。 如果 R0 包含 SVC 编号,则Example 6.10 中的代码可以插入到Example 6.9 提供的顶层处理程序中,插入位置在 BIC 指令之后。

Example 6.10. SVC 跳转表

    AREA SVC_Area, CODE, READONLY
    PRESERVE8
    IMPORT SVCOutOfRange
    IMPORT MaxSVC
    CMP    R0,#MaxSVC          ; Range check
    LDRLS  pc, [pc,R0,LSL #2]
    B      SVCOutOfRange
SVCJumpTable
    DCD    SVCnum0
    DCD    SVCnum1
                               ; DCD for each of other SVC routines
SVCnum0                        ; SVC number 0 code
    B    EndofSVC
SVCnum1                        ; SVC number 1 code
    B    EndofSVC
                               ; Rest of SVC handling code
EndofSVC
                               ; Return execution to top level
                               ; SVC handler so as to restore
                               ; registers and return to program.
    END

C 语言和汇编语言编写的 SVC 处理程序
尽管顶层处理程序始终必须用 ARM 汇编语言编写,处理每个 SVC 的例程既可用汇编语言编写,也可用 C 语言编写。有关限制的说明,请参阅在超级用户模式下使用 SVC。

顶层处理程序使用 BL 指令可跳转到相应的 C 函数。 因为 SVC 编号是由汇编例程加载到 R0 中的,所以作为第一个参数传递给 C 函数。 举例来说,函数可以将此参数值用在 switch() 语句中,请参阅Example 6.11。

若要调用此 C 函数,可以向Example 6.9 中 SVC_Handler 例程添加下面的代码行:

    BL    C_SVC_Handler     ; Call C routine to handle the SVC
Example 6.11. C 函数中的 SVC 处理程序

void C_SVC_handler (unsigned number)
{
    switch (number)
    {
        case 0 :                 /* SVC number 0 code */
            ...
            break;
        case 1 :                 /* SVC number 1 code */
            ...
            break;
        ...
        default :                /* Unknown SVC - report error */
    }
}


超级用户模式堆栈空间可能是有限的,因此要避免使用需要大量堆栈空间的函数。

    MOV     R1, sp        ; Second parameter to C routine...
                          ; ...is pointer to register values.
    BL    C_SVC_Handler   ; Call C routine to handle the SVC.
用 C 语言编写的 SVC 处理程序可以传入和传出值,前提是顶层处理程序将堆栈指针值作为第二个参数(在 R1 中)传递给 C 函数,并且更新 C 函数以访问该值:

void C_SVC_handler(unsigned number, unsigned *reg)
现在,C 函数在主应用程序代码中遇到 SVC 指令时就可访问存储在寄存器中的值了,请参阅 Figure 6.5。 它可从其中读取:

    value_in_reg_0 = reg [0];
    value_in_reg_1 = reg [1];
    value_in_reg_2 = reg [2];
    value_in_reg_3 = reg [3];
也可向其中回写:

    reg [0] = updated_value_0;
    reg [1] = updated_value_1;
    reg [2] = updated_value_2;
    reg [3] = updated_value_3;
这使已更新的值写入到堆栈的相应位置,然后通过顶层处理程序恢复到寄存器中。

Figure 6.5. 访问超级用户模式堆栈
在超级用户模式下使用 SVC
执行 SVC 指令时:

处理器进入超级用户模式。

CPSR 存储到 SVC SPSR 中。

返回地址存储在 SVC LR 中,请参阅处理器对异常的响应。

如果处理器已经处在超级用户模式下,则会损坏 SVC LR 和 SPSR。

如果在超级用户模式下调用 SVC,则必须存储 SVC LR 和 SPSR,以确保 LR 和 SPSR 的原始值不会丢失。例如,如果某个特定 SVC 编号的处理程序例程调用另一个 SVC,则必须确保该处理程序例程将 SVC LR 和 SPSR 都存储在堆栈中。 这可确保处理程序的每一次调用都保存返回到调用它的 SVC 后面的指令所需要的信息。Example 6.12 演示如何实现这一点。

Example 6.12. SVC 处理程序

    AREA SVC_Area, CODE, READONLY
    PRESERVE8
    EXPORT SVC_Handler
    IMPORT C_SVC_Handler
T_bit EQU 0x20
SVC_Handler
    PUSH     {R0-R3,R12,lr}       ; Store registers.
    MOV      R1, sp               ; Set pointer to parameters.
    MRS      R0, SPSR             ; Get SPSR.
    PUSH     {R0,R3}              ; Store SPSR onto stack and another register to maintain
                                  ; 8-byte-aligned stack. Only required for nested SVCs.
    TST      R0,#0x20             ; Occurred in Thumb state?
    LDRHNE   R0,[lr,#-2]          ; Yes: load halfword and...
    BICNE    R0,R0,#0xFF00        ; ...extract comment field.
    LDREQ    R0,[lr,#-4]          ; No: load word and...
    BICEQ    R0,R0,#0xFF000000    ; ...extract comment field.
                                  ; R0 now contains SVC number
                                  ; R1 now contains pointer to stacked registers
    BL       C_SVC_Handler        ; Call C routine to handle the SVC.
    POP      {R0,R3}              ; Get SPSR from stack.
    MSR      SPSR_cf, R0          ; Restore SPSR.
    LDM      sp!, {R0-R3,R12,pc}^ ; Restore registers and return.
    END


用 C 和 C++ 编写的嵌套 SVC
可用 C 或 C++ 语言编写嵌套的 SVC。 由 ARM 编译器生成的代码根据需要存储和重新加载 lr_SVC。

从应用程序调用 SVC
可用汇编语言或 C/C++ 调用 SVC。

用汇编语言设置所有必需的寄存器值并发出相关的 SVC。 例如:

    MOV    R0, #65    ; load R0 with the value 65
    SVC    0x0        ; Call SVC 0x0 with parameter value in R0
几乎像所有的 ARM 指令那样,SVC 指令可被有条件地执行。

在 C/C++ 中,将 SVC 声明为一个 __SVC 函数并调用它。 例如:

    __svc(0) void my_svc(int);
    .
    .
    .
    my_svc(65);
这确保了 SVC 以内联方式进行编译,无需额外的调用开销,其前提是:

所有参数都只传入 R0-R3

所有结果都只返回到 R0-R3 中。

参数被传递给 SVC,如同 SVC 是一个真正的函数调用。 但是,如果有二到四个返回值,则必须告诉编译器返回值在一个结构中,并使用 __value_in_regs 命令。这是因为基于 struct 值的函数通常被视为一个 void 函数,它的第一个参数必须是存放结果结构的地址。

Example 6.13 和 Example 6.14 演示一个 SVC 处理程序,该处理程序提供 SVC 编号 0x0、0x1、0x2 和 0x3。 SVC 0x0 和 SVC 0x1 都采用两个整数参数并返回一个结果。SVC 0x2 采用四个参数并返回一个结果。SVC 0x3 采用四个参数并返回四个结果。 此示例位于示例目录(...\svc\main.c 和 ...\svc\svc.h)中。

Example 6.13. main.c

#include <stdio.h>
#include "svc.h"
unsigned *svc_vec = (unsigned *)0x08;
extern void SVC_Handler(void);
int main( void )
{
    int result1, result2;
    struct four_results res_3;
    Install_Handler( (unsigned) SVC_Handler, svc_vec );
    printf("result1 = multiply_two(2,4) = %d\n", result1 = multiply_two(2,4));
    printf("result2 = multiply_two(3,6) = %d\n", result2 = multiply_two(3,6));
    printf("add_two( result1, result2 ) = %d\n", add_two( result1, result2 ));
    printf("add_multiply_two(2,4,3,6) = %d\n", add_multiply_two(2,4,3,6));
    res_3 = many_operations( 12, 4, 3, 1 );
    printf("res_3.a = %d\n", res_3.a );
    printf("res_3.b = %d\n", res_3.b );
    printf("res_3.c = %d\n", res_3.c );
    printf("res_3.d = %d\n", res_3.d );
    return 0;
}


Example 6.14. svc.h

__svc(0) int multiply_two(int, int);
__svc(1) int add_two(int, int);
__svc(2) int add_multiply_two(int, int, int, int);
struct four_results
{
    int a;
    int b;
    int c;
    int d;
};
__svc(3) __value_in_regs struct four_results
    many_operations(int, int, int, int);


从应用程序动态调用 SVC
在某些情况下,需要调用直到运行时才会知道其编号的 SVC。 例如,当有很多相关操作可对同一目标执行,并且每个操作都有自己的 SVC 时,就会发生这种情况。 在这种情况下,前几节中介绍的方法不适用。

对此,有几种解决方法,例如:

通过 SVC 编号构建 SVC 指令,将它存储在某处,然后再执行该指令。

使用通用的 SVC(作为一个额外的参数)将一个代码作为对其参数执行的实际操作。 通用 SVC 对该操作进行解码并予以执行。

第二种机制可使用汇编语言将所需的操作数传递到寄存器(通常为 R0 或 R12)中来实现。然后可重新编写 SVC 处理程序,对相应寄存器中的值进行处理。

因为有些值必须用注释字段传递给 SVC,所以有可能将这两种方法结合起来使用。

例如,操作系统可能会只用一条 SVC 指令和一个寄存器来传递所需的操作数。 这使得其他 SVC 空间可用于应用程序特定的 SVC。 在一个特定的应用程序中,如果从指令提取操作数的开销太大,则可使用这个方法。 ARM 和 Thumb 半主机指令就是这样实现的。

Example 6.15 演示如何使用 __svc 将 C 函数调用映射到半主机调用。 该示例是根据示例目录中的 retarget.c 编写的,该文件路径为 ...\emb_sw_dev\source\retarget.c。

Example 6.15. 将 C 函数映射到半主机调用

#ifdef __thumb
/* Thumb Semihosting */
#define SemiSVC 0xAB
#else
/* ARM Semihosting */
#define SemiSVC 0x123456
#endif
/* Semihosting call to write a character */
__svc(SemiSVC) void Semihosting(unsigned op, char *c);
#define WriteC(c) Semihosting (0x3,c)
void write_a_character(int ch)
{
    char tempch = ch;
    WriteC( &tempch );
}


编译器含有一个机制,支持使用 R12 来传递所需运算的值。 在 AAPCS 下,R12 为 ip 寄存器,并且专用于函数调用。其他时间内可将其用作暂存寄存器。 通用 SVC 的参数被传递到 R0-R3 寄存器中,如前面所述,还可以选择在 R0-R3 中返回值,请参阅 从应用程序调用 SVC。 在 R12 中传递的操作数可以是通用 SVC 调用的 SVC 的编号。 但这不是必需的。

Example 6.16 演示使用通用或间接 SVC 的 C 程序段。

Example 6.16. 使用间接 SVC

__svc_indirect(0x80)
    unsigned SVC_ManipulateObject(unsigned operationNumber,
                                  unsigned object,unsigned parameter);
unsigned DoSelectedManipulation(unsigned object,
                                unsigned parameter, unsigned operation)
{ return SVC_ManipulateObject(operation, object, parameter);
}


它生成以下代码:

DoSelectedManipulation
        PUSH     {R4,lr}
        MOV      R12,R2
        SVC      #0x80
        POP      {R4,pc}
        END
还可使用 __svc 机制从 C 中传递 R0 中的 SVC 编号。 例如,如果将 SVC 0x0 用作通用 SVC,操作 0 为字符读,操作 1 为字符写,则可以进行如下设置:

__svc (0) char __ReadCharacter (unsigned op);
__svc (0) void __WriteCharacter (unsigned op, char c);
可通过如下定义使其具有更好的可读性风格:

#define ReadCharacter () __ReadCharacter (0);
#define WriteCharacter (c) __WriteCharacter (1, c);
但是,如果以这种方式使用 R0,则仅有三个寄存器可用于向 SVC 传递参数。通常,在不得不将除 R0-R3 之外的更多参数传递给子例程时,可通过使用堆栈来完成但是,SVC 处理程序不容易访问堆栈参数,因为这些参数通常在用户模式堆栈中,而不是在 SVC 处理程序使用的超级用户模式堆栈中。

作为另一种选择,其中一个寄存器(通常是 R1)可用来指向存储其他参数的内存块。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ARM Cortex M4 SVC指令作用 的相关文章

  • 中断的尾链

    什么是 ARM Cortex M3 中 NVIC 支持的中断尾链 尾链是异常的背对背处理 无需 中断之间的状态保存和恢复的开销 这 处理器跳过八个寄存器的弹出操作和八个寄存器的压入操作 当退出一个 ISR 并进入另一个 ISR 时 因为这没
  • 如何创建具有自定义外设和内存映射的 QEMU ARM 机器?

    我正在为 Cortex M3 cpu 编写代码 并且正在使用以下命令执行单元测试qemu arm二进制 现在一切都很好 但我想知道我是否能够使用测试整个系统qemu system arm 我的意思是 我想为 qemu 编写自定义 机器 我将
  • 多核ARM cpu上的中断如何工作

    这个问题已经针对 x86 得到了解答 但是 我找不到太多关于 ARM MP cpu 如 Cortex A9 Cortex A15 等 的信息 更重要的是我想知道是否可以在非主CPU上引发中断而无需任何配置等 我正在开发一款仅处理主 cpu
  • arm gcc工具链为arm-elf或arm-none-eabi,有什么区别?

    当您构建 gcc 工具链时 可以将其构建为arm elf 或arm none eabi 但是有什么区别呢 我今天使用 eabi 但这只是因为其他人似乎都这样做 但由于这是一个非常糟糕的论点 因此理解其中的差异真的很高兴 注意 此工具链将为基
  • 理解这部分手臂的汇编代码

    syntax unified thumb cpu cortex m4 arch armv7e m fpu fpv4 sp d16 Changes from unprivileged to privileged mode thumb func
  • 使用 GCC 编译器为代码的特定部分保留寄存器

    是否可以为 C 代码的特定部分保留寄存器 ffixed reg 选项或声明全局寄存器变量不是我正在寻找的答案 我想保留特定范围 比如说特定函数 的寄存器值 使用局部寄存器变量是不可能的 因为它不能保证在整个范围内保留寄存器的值 我正在寻找类
  • 如何在 ARM 架构上从 RAM 运行代码

    我正在对 ARM Cortex R4 进行编程 并且有一些二进制文件 我想从 TCRAM 执行它们 只是为了看看性能的提升是否足够好 我知道我必须编写一个函数来将二进制文件复制到 RAM 这可以通过链接器脚本来完成 并且知道二进制文件的大小
  • ARM 的启动过程是怎样的?

    我们知道 对于X86架构 按下电源按钮后 机器开始执行0xFFFFFFF0处的代码 然后开始执行BIOS中的代码以进行硬件初始化 BIOS 执行后 它使用引导加载程序将操作系统映像加载到内存中 最后 操作系统代码开始运行 对于ARM架构 使
  • 如何修改内核DTB文件

    Summary 我目前正在为定制板编译 Linux 内核 内核 模块和 DTB 以及一些定制驱动程序 有时 我会编译内核并意识到 DTB 文件中的兼容性字符串不是自定义驱动程序正在寻找的内容 现在 我可以解决此问题的唯一方法是修改 DTS
  • ARM 汇编分支到寄存器或内存内部的地址

    我想知道在 ARM 汇编中我可以使用哪条指令分支到存储在某个内存地址中的地址或标签 例如 我们可以使用B LABEL来跳转到LABEL 但现在目的地只能在运行时知道 并且它存储在某个已知的内存位置 是否有类似 B 地址 的东西 Thanks
  • 如何使用 gcc 编译代码和 ARM Cortex A8 目标进行调用图分析?

    我对这个已经咬牙切齿了 我需要在 ARM 板上进行分析并需要查看调用图 我尝试使用 OProfile Kernel perf 和 Google 性能工具 一切正常 但不输出任何调用图信息 这使我得出结论 我没有正确编译代码 我在编译 C 代
  • 读取和打印手臂组件中的字符串

    我正在使用 ARMSim 刚刚开始学习汇编 所以如果我看起来一无所知 请原谅我 但我正在尝试从输入文件中读取字符串 然后将其打印到输出屏幕 到目前为止我有 equ SWI Open 0x66 open a file equ SWI Clos
  • 可以使用Visual Studio 2012构建ARM桌面程序吗?

    我正在使用 Visual Studio 2012 beta 我的桌面 win32 程序在 ARM 架构中编译得很好 升级到 Visual Studio 2012 RC 后 编译器无法工作并出现以下错误 不支持为 ARM 平台编译桌面应用程序
  • ARM + gcc:不要使用一大块 .rodata 部分

    我想使用 gcc 编译一个程序 并针对 ARM 处理器进行链接时间优化 当我在没有 LTO 的情况下编译时 系统会被编译 当我启用 LTO 时 使用 flto 我收到以下汇编错误 错误 无效的文字常量 池需要更近 环顾网络 我发现这与我系统
  • ARM 调用约定是否允许函数不将 LR 存储到堆栈中?

    正如标题所示 我在理解 ARM 架构的调用约定时遇到问题 特别是 我仍然很难知道当你调用子程序时 LR 寄存器会发生什么 我认为 当您进入子程序时 处理 LR 寄存器的最明显 最安全的方法是将其存储到堆栈中 但该行为没有出现在文档中 因此我
  • 产生并处理软件中断

    有人可以告诉我如何在Linux下生成软件中断然后用request irq处理它吗 或者也许这是不可能的 您可以使用软中断来代替 您可以通过编辑 include linux interrupt h 来定义您的 sofirq 然后使用函数 ra
  • 使用 Android NDK 使用 -fsigned-char 进行构建安全吗?

    为了与其他平台保持一致 我需要使用signed char在我正在处理的一些本机代码中 但默认情况下在Android NDK上char类型是unsigned 我尝试明确使用signed char类型 但它生成太多警告differ in sig
  • 如何设置 CMake 与 clang 交叉编译 Windows 上的 ARM 嵌入式系统?

    我正在尝试生成 Ninja makefile 以使用 Clang 为 ARM Cortex A5 CPU 交叉编译 C 项目 我为 CMake 创建了一个工具链文件 但似乎存在错误或缺少一些我无法找到的东西 当使用下面的工具链文件调用 CM
  • 了解 U-Boot 内存占用

    我不明白加载 U Boot 时 RAM 中发生了什么 我正在开发 Xilinx Zynq ZC702 评估套件 并尝试使用 U Boot 在其上加载 Linux 内核 于是我使用Xilinx工具Vivado和SDK生成了一个BOOT bin
  • gdb 不会从外部架构读取核心文件

    我正在尝试在 Linux 桌面上读取 ARM 核心文件 但似乎无法找出我的核心文件 有什么方法可以指示 gdb 我的核心文件是什么类型吗 file daemon daemon ELF 32 bit LSB executable ARM ve

随机推荐

  • Git Flow 用法

    git flow 工作流程 如下图所示 master 分支 master 分支主要方稳定 随时可上线的版本 这个分支只能从别的分支上合并过来 xff0c 一般来讲 xff0c 从develop 上合并 xff0c 或者从hotfix分支上合
  • Qt父窗口与子窗口间的焦点传递问题的完美解决

    使用activateWindow 或者raise 参考文章 xff1a https blog csdn net Hoarce article details 107215868 http www manongjc com detail 19
  • Git 工作中的一些命令操作

    本篇为工作中 git 使用过程中的一些操作记载 xff0c 不定期更新 目录 1 git 推本地代码到远程 2 git 放弃修改 commit 撤销远程提交记录 3 git pull push fetch 4 git关联本地与远程分支 5
  • php如何使用S3

    本篇是新手使用PHP调aws的s3服务的一些心得 一 关于AWS S3 s3是一个文件存储服务 xff0c 当需要做成服务来进行微服务调用 xff0c 或者终端服务端文件交流使用s3是一个非常不错的选择 aws各种常见的语言例如 xff1a
  • MySQL相关面试题

    1 MySQL text长度 mysql的text是65535的字节限制 xff0c 而pg是不限制的 2 覆盖索引 聚簇索引 xff08 https blog csdn net alexdamiao article details 519
  • Redis相关面试题

    1 缓存是什么 xff1f 缓存分为本地缓存和分布式缓存 以Java为例 xff0c guava实现的就是本地缓存 xff0c 生命周期随JVM销毁而结束 起多个服务实例 xff0c 就有多份缓存 xff0c 不具有一致性 redis和me
  • 如何断网安装docker

    docker rpm安装 不能联网情况 生产环境可能是不能联网的 xff0c 当我们需要用到docker 或其他组件 的时候 xff0c 就需要借助能联网的环境下载好rpm包 xff0c 然后去操作系统服务器装下载好的docker RPM包
  • docker相关

    优势 xff1a 1 启动快 传统的虚拟机技术启动应用服务往往需要数分钟 xff0c 而 Docker 容器应用 xff0c 由于直接运行于宿主内核 xff0c 无需启动完整的操作系统 xff0c 因此可以做到秒级 甚至毫秒级的启动时间 大
  • Liunx下源代码安装&&make&&makefile

    Linux下安装软件的方式分为源代码安装和二进制安装 源代码安装 xff0c 即使用应用程序源代码进行编译安装二进制安装 xff0c 例如red hat发行的 rpm包 debian发行的 deb包 源代码安装 用c语言为例 include
  • Linux下rpm&yum&apt-get

    RPM简介 RPM命名 RedHat Package Manager xff0c 简称则为RPM 属于Red Hat阵营的 xff0c 与其并列的则是debian centos中大部分我们安装都是使用yum install xff0c 而d
  • Java面试题复习整理(多线程)

    文章目录 1 aio nio bio epoll select2 reactor模式介绍Reactor软件工程java代码总结 3 Java中的cas乐观锁4 自旋锁是什么 xff1f 自旋锁 amp amp 自适应自旋锁 amp amp
  • Grpc&&protocol buffer结合提供grpc服务

    Grpc amp amp protocol buffer 关于下载 xff1a 首先下载一个protobuf 对于mac系统就brew install protobuf 就可以了 然后可以 protoc version 看下安装的版本号 x
  • 指针p,*p,&p之间的区别

    假设我们定义一个指针p 那么会经常使用到三个符号 xff1a 1 xff0c p xff1b p是一个指针变量的名字 xff0c 表示此指针变量指向的内存地址 xff0c 如果使用 p来输出的话 xff0c 它将是一个16进制数 2 xff
  • 自己经历的Java面试题(附答案)

    本篇记录一下自己面试的一些中大厂的 1 3年Java开发的面试题以及自己对题目理解的答案 xff08 结合网上查的资料 xff09 部分可能更新的不及时 xff0c 有问题可以评论区讨论 面试题不分先后 1 hashmap rehash 过
  • Redisson相关使用&&分布式锁浅析

    注 xff1a 本篇的redisson版本基于3 13 3 xff1b 本篇的demo将我写的源代码贴了出来 xff0c 每个方法都有清晰的注释 xff0c 分布式锁相关的代码以及验证是我手动验证Redis中key状态来判断的 文章目录 简
  • SpringBoot实战elasticSearchAPI微服务开发

    文章目录 前言启动一个ElasticSearchSpringBoot引入ElasticSearch索引创建 amp amp 更新插入删除 写 操作ElasticSearch的API查询操作源码参考 前言 本文准备记录一下ElasticSea
  • Leetcode链表刷题思路汇总

    链表 链表相关的题 xff0c 最快的入门方法就是做题的时候画图 标注A的next节点是哪里 xff0c 单链表的遍历只能是单向的 xff0c 从头结点到尾结点 例如 xff1a 给你一个链表的head头 xff0c 让你返回最后元素的值
  • Java基础之字符串&equals、==、包装类、常量池

    在java中有三中对字符串的操作方式 注 xff1a 文章只注明思路原理 不注明方法 xff0c 看API就行了 文章就涉及到啥写啥了 xff0c 哈哈 xff0c 瞅着可能乱一点 但是这么写就很舒服 1 String 常量 效率较低 指的
  • 基于激光雷达的人型识别(无人车)

    原文在这 finalobject cn 这个项目是无人车里的一部分 xff0c 完成激光雷达的驱动 xff0c 数据采集然后后期的处理以及人型识别 xff0c 并不涉及车辆硬件的控制 主要分三个大块讲吧 xff0c 硬件驱动 数据聚类 xf
  • ARM Cortex M4 SVC指令作用

    xff08 1 xff09 SVC指令 xff1a 摘自 http infocenter arm com help index jsp topic 61 com arm doc dui0203ic Cacdfeci html 与更早版本的