简体   繁体   English

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

[英]Calling function from ARM microcontroller's ROM by using pointer to this function?

I am working with cec1702 ( cortex m4 from microchip), this device a has cryptographic engine , but it is accessible only through microchip's API.我正在使用cec1702 (来自 microchip 的cortex m4 ),该设备具有cryptographic engine ,但只能通过 microchip 的 API 访问。 I don't want to use official API , because I am trying to use minimal setup only with gcc and for API I would need to download the whole IDE , also I need just a couple of functions..我不想使用官方API ,因为我试图只使用gcc最小设置,对于API我需要下载整个IDE ,而且我只需要几个功能..

In document about device's ROM I've founded this list of API functions and their symdef table, for example:在有关设备ROM文档中,我创建了这个API函数列表及其 symdef 表,例如:

api_rng_mode                        = 0x00007425; 
api_rng_get_random_bytes            = 0x00007441; 

Prototypes of this two functions look like this:这两个函数的原型如下所示:

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

MY PLAN is to use those functions only by defining pointers to them, but am Am I actually doing it right?我的计划是仅通过定义指向它们的指针来使用这些函数,但我实际上做对了吗? For those 2 examples I am using this definitions:对于这两个示例,我使用了以下定义:

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

And in code I call them like this:在代码中,我这样称呼它们:

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

But so far it doesn't look working... Any ideas?但到目前为止它看起来不起作用......有什么想法吗?

EDIT: Thank you all for your help:) It works now and I learned something new:) The code before jumped somewhere into ROM and stucked there, but it was solved by resetting RNG during the process of setting it up.编辑:谢谢大家的帮助:) 它现在可以工作了,我学到了一些新东西:) 之前的代码跳到 ROM 的某个地方并卡在那里,但是在设置过程中通过重置 RNG 解决了这个问题。

The code may well be correct, but it is borderline unreadable with the added problem of macros that don't respect scopes.代码可能是正确的,但由于不考虑作用域的宏的附加问题,它是不可读的。 Therefore:所以:

// 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);

That also makes it easier to eg mock the functions for unit tests.这也使得模拟单元测试的函数变得更容易。 Then, define pointers to these functions:然后,定义指向这些函数的指针:

// 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;

You can then call the according functions using plain function syntax:然后,您可以使用普通函数语法调用相应的函数:

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

Note that the explicit dereferencing (with * ) isn't necessary, although it can be done.请注意,虽然可以完成,但不需要显式取消引用(使用* )。

The only thing that might still cause problems now is "calling conventions", which is the stack protocol, ie the way how arguments are passed on the stack.现在唯一可能仍然导致问题的是“调用约定”,这是堆栈协议,即参数在堆栈上传递的方式。 If the calling function pushes them in the wrong order or if the called function expects some arguments in registers instead, you may need to tell the compiler or even write some inline assembly.如果调用函数以错误的顺序推送它们,或者如果被调用函数需要寄存器中的一些参数,则可能需要告诉编译器甚至编写一些内联汇编。

If you want yo use defines you need to pas the parameters as well如果你想使用定义,你还需要传递参数

#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)

But actually I would wrap them into the inline functions like this:但实际上我会将它们包装成这样的内联函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM