zoukankan      html  css  js  c++  java
  • IAR EWAR 内联汇编 调用外部函数 Error[Og005], Error[Og006]

    How do I call a C function in another module from inline assembler in IAR EWARM?

    I have a bit of assembly in a hard fault handler.

    The assembly is basically meant to pass the current stack pointer as a parameter (in R0). It looks like so...

    __asm("    mov     r0, sp
    "
      "    bl      SavePC
    "
      "    bx      lr");

    This works fine when SavePC is in the same c file.

    However, when SavePC is placed in another c file I have no luck.

    I have tried to IMPORT the function like so...

    __asm("IMPORT SavePC
    "
    " mov r0, sp
    "
    " bl SavePC
    "
    " bx lr");

    ... but I must be doing something incorrect. The compiler reports the following...

    Error[Og005]: Unknown symbol in inline assembly: "IMPORT" 
    Error[Og005]: Unknown symbol in inline assembly: "SavePC" 
    Error[Og006]: Syntax error in inline assembly: "Error[54]: Expression can not be forward"
    Error[Og005]: Unknown symbol in inline assembly: "SavePC" 
    Error while running C/C++ Compiler 

    The c file with the assembly includes the header file with the SavePC prototype...

    extern void SavePC(unsigned long);

    Suggestions?

    Your code won't work even with a correct call.

    bl _SavePC             // LR be changed
    bx lr                  // while (1){} 

    What do you think will be the value in the LR register in the bx lr instruction?

    The address of the instruction itself!

    The bl instruction has put it there. This is effectively a while (1); 

    with a bx instruction.

    A nested function call looks more like this:

    push {lr}
    bl _SavePC
    pop {pc}

    To get the stack register one uses the corresponding CMSIS functions:

    • __get_MSP() for the Main Stack Pointer (MSP)
    • __get_PSP() for the Process Stack Pointer (PSP)

    Using extern is a bad habit since it is prone to errors. C-99 standard provides an safe alternative for extern. You should write the function prototype in the header file without extern keyword. Then include the header file in both C files. The linker is then responsible for linking the function in different files.

    Example:

    File : custom_header.h

    void SavePC(unsigned long);

    File : source_c_file.c

    #include "custom_header.h"
    
    void SavePC(unsigned long)
    {
          ....
          ....
    
          ....
    
    }

    File : user_c_file.c

    #include "custom_header.h"
    
    void someFunction(void)
    {
    .
    .
    .
    
    __asm("mov     r0, sp
    "
      "    push  {lr}
      "    bl      SavePC
    "
      "    pop    {pc}");
    
    .
    .
    .
    }
  • 相关阅读:
    Android关于版本更新下载安装之踩坑记录(针对7.0以上)
    使用UICollectionView遇到的各种坑
    WKWebView携带不上cookie的问题处理
    安卓圆角、背景遮罩。覆盖实现方式(适用于所有控件)
    Shell:命令用户、用户组管理useradd、usermod
    Cassandra 数据库安装部署
    Linux服务器的弱口令检测及端口扫描
    js 做的随机8位验证码
    JavaScript原型与继承的秘密
    html5语义化标签
  • 原文地址:https://www.cnblogs.com/shangdawei/p/4612680.html