【发布时间】:2021-10-22 21:09:05
【问题描述】:
首先,对不起我的英语。我是巴西人,仍在努力学习(英语和编程)。
我正在尝试创建一个固件应用程序(STM32 uc),它可以访问其他固件(我的地址分为 BL + FWA + FWB),但我有一个问题,找不到原因。 FWB 需要访问 FWA 上的一个函数,以使用更少的 flash 区域。 我可以访问函数本身,执行其中的任何操作,但是当达到返回时,它给了我一个 HardFault。 我正在使用分散文件来使用 FWA 和 B 上共享的内存。
LR_IROM1 0x08004000 0x00004000 { ; load region size_region
ER_IROM1 0x08004000 0x00004000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 UNINIT 0x00001000 { ; No init data
*(.noinit)
}
RW_IRAM2 0x20001000 0x00004000 {
.ANY (+RW +ZI) //RW data
}
}
我的功能被定义为
uint getInt(void) __attribute__((section(".ARM.__at_0x8006000")));//My fw was at 0x4000, total size is 0x4000,
//so space is not the problem.
uint getInt(void){
return 42;
}
在我的应用程序上(在 FWA 上运行以测试自身,但没有结果),我试图这样称呼它:
uint (*fun_ptr)(void) = (uint(*)(void))0x8006000;
uint _get_int= fun_ptr();
uint result = _get_int();
编辑: 使用时
IntFunc p = getInt;
uint ccccc = p();
uint aaaa = getInt();
所有选项都可以正常工作,问题出在使用地址时。
正如我所提到的,我可以进入函数“getInt()”,我可以执行其中的任何代码指令,但是当达到“return 42”时,我有一个 HardFault。
我找到了另一种方法来做到这一点,使用结构,工作,但我认为理解这个问题非常重要,了解错误在哪里,这有助于不再犯错误。
编辑 2: 我想了解问题,而不仅仅是简单地获得解决方案。 这种方法对我有用: main.h 文件
typedef struct bootloaderApi bootloaderApi;
typedef unsigned int (*do_something_t)(void);
struct bootloaderApi{
do_something_t do_something;
};
和 Main.c:
const struct bootloaderApi api __attribute__((section(".ARM.__at_0x8005000")))
= {.do_something = &getInt}; //address 0x5000 to test.
并将其用作
struct bootloaderApi *apit = (struct bootloaderApi *)0x8005000;
uint pa = api.do_something();
它工作正常,pa 将 uint 42 返回给我。
谢谢。
【问题讨论】:
-
但是当达到“return 42”时,我有一个 HardFault。 -- 我没有在 stm32 上工作过,但是根据我在 Windows 上的经验,每当
return崩溃,这通常表明调用者和被调用者之间的调用约定不匹配。请注意,您的功能非常简单,所以对我来说这就是我怀疑或类似的东西。 -
如果您不熟悉什么是调用约定,here is a link。当然,如果您知道它们是什么,那么您就会知道我在说什么。
-
另外,准备函数时的环境是否知道正在返回
uint(就大小而言)而不是不同字节大小的东西?如果不是,那么这可能是另一个原因(我看到你说它适用于结构,但不适用于非常简单的uint)。此外,我会坚持使用已知的 C++ 类型,例如uint32_t或类似类型,而不是uint,只是为了明确说明实际类型是什么。 -
@PaulMcKenzie,感谢您的链接,我会阅读的。抱歉,我认为我解释错了:“当我使用一个内部带有函数的结构时,将函数 getInt 映射到 struct 的成员,并将结构映射到地址,而不映射 getInt 函数本身,它可以工作。当我调用mystruct.getIntMethod(),它工作正常。我将编辑问题以提出工作方法,以澄清它。
-
@PaulMcKenzie 我编辑了我的问题,以解释什么更好。