如何在主应用程序和引导程序中使用一个功能? (嵌入)

时间:2017-08-02 11:35:07

标签: c bootloader dfu

首先,我需要说我开发了基于cortex m4的嵌入式设备应用程序。

我有一些常用于bootloader和主应用程序的函数。现在我为bootloader和app编译了两次源文件。但是我对于双银行dfu的空间不足,我想在ROM中只有这些功能一次。知道我怎么能实现这个目标?

修改

在某些情况下使用函数指针可能存在危险,请检查我的问题 - Using pointer functions - 2 seperate applications on 1 device

3 个答案:

答案 0 :(得分:2)

这只是部分答案,并假设您可以使用相同的地址空间从主代码跳转到引导加载程序。然后,一种常见的技术是将“bootloader API”作为函数指针表提供。

比如说你的bootloader中有以下功能:

static int do_something(void)
{
    return 42;
}

static int do_something_else(int arg)
{
    return arg+5;
}

然后你会在这样的标题中声明你的API:

struct bootloaderApi
{
    int (*do_something)(void);
    int (*do_something_else)(int arg);
};

在bootloader的实现中,您可以在自己的部分中定义此表:

// this is GCC syntax, use whatever your compiler provides to specify the section
struct bootloaderApi api __attribute__((section("API"))) = {
    do_something,
    do_something_else
};

然后在构建引导加载程序时,请确保将您的部分放在合适的固定地址。例如,使用GNU链接器,您可以在链接器脚本中使用类似的东西:

SECTIONS {
  // standard sections, e.g.:
  .text : { *(.text) }
  .data : { *(.data) } 
  .bss :  { *(.bss)  *(COMMON) }

  // your API table:
  .API 0x10000 : { *(.API) }
}

现在假设您的API表格将放在0x10000。然后,您可以执行以下操作从主代码访问API:

struct bootloaderApi *api = (struct bootloaderApi *)0x10000;

api->do_something();

所有这些只是一个草图,让您了解如何以合理的方式做到这一点。它将在很大程度上取决于您的目标平台和您正在使用的工具链。

答案 1 :(得分:1)

软件中断是访问引导代码中的功能的常用方法。然后主程序不需要知道函数的位置。通常,以固定方式推送函数编号,以便启动代码始终可以检索它并切换到所需的函数。

这样的机制不需要任何特殊定位的接口区域,这些接口区域是固定的,并且知道boot和main,或者主代码和引导代码之间的任何链接。

确切的机制取决于架构。

答案 2 :(得分:0)

两种可能的情况:

  1. 内置bootloader。在我所知道的所有Cortex内核中。以下是从应用程序调用引导加载程序的示例代码。

    redux
  2. 自定义引导加载程序 - 任何可能的方案