通过使用指向该函数的指针从ARM微控制器的ROM调用函数?

时间:2018-10-12 10:12:40

标签: c pointers arm rom

我正在使用cec1702(来自微芯片的cortex m4),该设备a具有cryptographic engine,但只能通过微芯片的API进行访问。我不想使用官方的API,因为我尝试仅对gcc使用最小化设置,而对于API,我将需要下载整个IDE,我只需要几个功能即可。

在关于设备ROM的文档中,我建立了API函数及其symdef表的列表,例如:

api_rng_mode                        = 0x00007425; 
api_rng_get_random_bytes            = 0x00007441; 

这两个函数的原型如下:

void api_rng_mode(uint8_t tmode_pseudo);
uint32_t api_rng_get_random_bytes ( uint8_t *pbuff8,uint32_t num_bytes);

MY PLAN 只能通过定义指向它们的指针来使用这些功能,但是我实际上是对的吗? 对于那些 2 示例,我正在使用以下定义:

#define api_rng_mode (void(*)(uint8_t))0x00007425
#define api_get_random_bytes (uint32_t(*(uint8_t,uint32_t))0x00007441

在代码中,我这样称呼他们:

(*api_rng_mode)(1);
(*api_get_random_bytes)(p, numberofbytes);

但是到目前为止,它看起来不起作用...有什么想法吗?

编辑:谢谢大家的帮助:)它现在可以使用,我学到了一些新东西:) 之前的代码跳到了ROM的某个地方并停留在那里,但在设置过程中通过重置RNG得以解决。

2 个答案:

答案 0 :(得分:4)

该代码很可能是正确的,但是由于不遵守范围的宏问题而难以理解。因此:

// alias the function types by just adding a `typedef`
typedef void api_rng_mode_function(uint8_t tmode_pseudo);
typedef uint32_t api_rng_get_random_bytes_function( uint8_t *pbuff8,uint32_t num_bytes);

这也使它更容易例如模拟单元测试的功能。然后,定义指向这些函数的指针:

// TODO: Add reference to documentation where these magic numbers came from!
api_rng_mode_function*const api_rng_mode = 0x00007425;
api_rng_get_random_bytes_function*const api_rng_get_random_bytes = 0x00007441;

然后您可以使用普通函数语法来调用相应的函数:

api_rng_mode(42);
uint8_t buffer[17];
uint32_t res = api_rng_get_random_bytes(buffer, sizeof buffer);

请注意,尽管可以进行显式取消引用(使用*),但可以这样做。

现在唯一仍可能引起问题的是“调用约定”,这是堆栈协议,即,如何在堆栈上传递参数的方式。如果调用函数以错误的顺序推送它们,或者被调用函数期望在寄存器中使用某些参数,则可能需要告诉编译器,甚至编写一些内联汇编。

答案 1 :(得分:1)

如果要使用定义,还需要同时设置参数

#define api_rng_mode(p) ((void(*)(uint8_t))0x00007425)(p)
#define api_get_random_bytes(p,s) ((uint32_t (*)(uint8_t *,uint32_t))0x00007441)(p,s)

但是实际上我会将它们包装到这样的内联函数中:

inline uint32_t api_get_random_bytes(uint8_t *buff, uint32_t size)
{
    return ((uint32_t (*)(uint8_t *,uint32_t))0x00007441)(buff,size);
}