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\n"
" bl SavePC\n"
" 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\n"
" mov r0, sp\n"
" bl SavePC\n"
" 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\n"
" push {lr}
" bl SavePC\n"
" pop {pc}"); .
.
.
}

IAR EWAR 内联汇编 调用外部函数 Error[Og005], Error[Og006]的更多相关文章

  1. IAR EWAR 内联汇编 Error[Og010], Error [Og005], Error [Og006]

    Error [Og005] + [Og006] when using inline assembler EW targets: 430, ARM, AVR EW component: C/C++ co ...

  2. gcc 在c代码中内嵌汇编调用c函数: 只是证明曾经我来过

    我怕我不写下来,将来我都不记得我还在 c 中嵌套过汇编语言,用汇编代码调用一个c函数的过程. 折腾了一下午,在网上查看相关的资料,然后照葫芦画瓢地在c代码中嵌套汇编,希望解决我所遇到的问题,可最后发现 ...

  3. x64内联汇编调用API(需intel编译器,vc不支持x64内联汇编)

    #include "stdafx.h" #include <windows.h> STARTUPINFOW StartInfo  = {0}; PROCESS_INFO ...

  4. 在Visual C++中使用内联汇编

    一.内联汇编的优缺点 因为在Visual C++中使用内联汇编不需要额外的编译器和联接器,且可以处理Visual C++中不能处理的一些事情,而且可以使用在C/C++中的变量,所以非常方便.内联汇编主 ...

  5. GNU C内联汇编(AT&amp;T语法)

    转:http://www.linuxso.com/linuxbiancheng/40050.html 内联汇编提供了可以在C或C++代码中创建汇编语言代码,不必连接额外的库或程序.这种方法对最终程序在 ...

  6. C语言中递归什么时候能够省略return引发的思考:通过内联汇编解读C语言函数return的本质

    事情的经过是这种,博主在用C写一个简单的业务时使用递归,因为粗心而忘了写return.结果发现返回的结果依旧是正确的.经过半小时的反汇编调试.证明了我的猜想,如今在博客里分享.也是对C语言编译原理的一 ...

  7. 通过调用C语言的库函数与在C代码中使用内联汇编两种方式来使用同一个系统调用来分析系统调用的工作机制

    通过调用C语言的库函数与在C代码中使用内联汇编两种方式来使用同一个系统调用来分析系统调用的工作机制 前言说明 本篇为网易云课堂Linux内核分析课程的第四周作业,我将通过调用C语言的库函数与在C代码中 ...

  8. VC++线程函数内怎么调用外部函数

    VC++线程函数内怎么调用外部函数 1.把外部函数做成静态函数,就可以直接调用了.2.把外部函数所在的对象通过线程函数参数传到线程里面来,这样线程里可以使用此对象及其函数了.

  9. 最牛X的GCC 内联汇编

    导读 正如大家知道的,在C语言中插入汇编语言,其是Linux中使用的基本汇编程序语法.本文将讲解 GCC 提供的内联汇编特性的用途和用法.对于阅读这篇文章,这里只有两个前提要求,很明显,就是 x86 ...

随机推荐

  1. HTTP Methods

    简介 HTTP 定义了一组请求方法,以表明要对给定资源执行的操作.指示针对给定资源要执行的期望动作, 虽然他们也可以是名词,但这些请求方法有时被称为HTTP动词.每一个请求方法都实现了不同的语义,但一 ...

  2. Hibernate二级缓存(未完待续)

    1.Hibernate的cache介绍: Hibernate实现了良好的Cache机制,可以借助Hibernate内部的Cache迅速提高系统的数据读取性能.Hibernate中的Cache可分为两层 ...

  3. 解读Android LOG机制的实现【转】

    转自:http://www.cnblogs.com/hoys/archive/2011/09/30/2196199.html http://armboard.taobao.com/ Android提供 ...

  4. C#上传图片(含有图片大小格式过滤以及改变像素安全存储)

    示例一: public JsonResult Upload(string parameter) { ]; try { //LogHelper.Info("文件长度:" + file ...

  5. PHP+mysql系统报错:PHP message: PHP Warning: Unknown: Failed to write session data (files)

    PHP+mysql系统报错:PHP message: PHP Warning:  Unknown: Failed to write session data (files) 故障现象,后台页面点击没有 ...

  6. 使用eclipse为Servlet在Tomcat中的部署方法

    一:下载安装jdk,tomcat,eclipse: 使用eclipse建立动态web项目lcj,更改编译文件目录,方法如下: 右键点击→工程名称→属性(Properties)或(Building Pa ...

  7. jenkins 使用Git持续构建

    为jenkins添加git插件. 在Available tab页中找到Git Plugin 点击下方的Install without Restart安装插件. 插件安装完毕后,我们需要在jenkins ...

  8. python包管理之Pip安装及使用

    Python有两个著名的包管理工具easy_install.py和pip.在Python2.7的安装包中,easy_install.py是默认安装的,而pip需要我们手动安装. pip可以运行在Uni ...

  9. final修饰的地址不能被修改

    package final0; /* * 顾客 */public class Customer { // 属性 String name; int age; // 父类object的方法 public ...

  10. Servlet发送Http请求

    今日遇到一个需求,android注册,短信验证码功能. android请求我服务端,我请求tosms.cn发送验证码短信给android,于是需要在Servlet中发送Http请求 package o ...