使用指针功能-1个设备上2个独立的应用程序 [英] Using pointer functions - 2 separate applications on 1 device

查看:81
本文介绍了使用指针功能-1个设备上2个独立的应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我前段时间问过这个问题

I asked some time ago this question How can I use one function from main application and bootloader? (embedded) and started to implement proposed solution but ran into a few problems.

在我的cortex M4 I上,有2个独立的应用程序-引导程序和用户应用程序.现在,我有一些(很多)功能,这两个应用程序都相同.因此,我仅将它们编译为用于引导加载程序,然后在指定地址创建了一个函数指针数组,这对于用户应用程序而言是已知的.因此,在应用程序中,我不再使用那些函数来编译文件,而是在需要时使用这些指针.

On my cortex M4 I, have 2 separate applications - bootloader and user application. Now I had some (many) functions which were the same for both apps. So I compiled them only for bootloader, then created an array of function pointers at specified address, which is known for user application. So in application, I didn't compile the files with those functions again, but I use those pointers whenever needed.

这是我试图使这两个应用程序通用的代码示例:

This is example of code I tried to make common for both applications:

static uint8_t       m_var_1;

// Sends events to the application.
static void send_event(fs_op_t const * const p_op, fs_ret_t result)
{
    uint8_t var_2;
    [...]
}

我的应用程序以Hardfault结尾,例如除以零或使用指针使用NULL值时.我不确定为什么,但是我开始怀疑这些变量会发生什么. var_2最确定地将位于堆栈上,所以这没有问题.但是m_var_1呢?在地图文件中,它在RAM中具有指定的位置.但是我没有用于应用程序和引导程序的RAM部分.我不确定,但是我有一个感觉,该变量可能使用与为Bootloader创建时相同的RAM位置.这可能吗?也许还有其他问题?

My application ends in Hardfault, which happens e.g. when dividing by zero or using pointer to function with NULL value. I am not sure why yet, but I started wondering what happens with those variables. var_2 will most surely be located on stack so this is no problem. But what about m_var_1? In the map file, it has a specified place in RAM. But I don't have seperate RAM sections for app and bootloader. I am not sure, but I have a feeling that this variable may use the same RAM location as when created for bootloader. Is this possible? Maybe some other issues?

推荐答案

是的,代码将尝试在与加载程序链接的相同位置访问全局变量.这是因为链接涉及用编译后确定的地址替换所有出现的标识符(包括函数名和变量名).

Yes you are right, the code will attempt to access the global variable at the same location as it is linked for loader. This is because linking involves replacing all occurrences of identifiers (including function names and variable names) by the addresses determined after compiling.

在您的应用程序中,即使该变量确实存在,该变量也可能位于其他地址. 这些函数的调用恰好起作用,因为它们位于ROM中,并且对于应用程序和加载程序而言不能有所不同.通过也存储在ROM中的const指针调用它们可以避免此问题.

In your application, the variable, even if it does exist there too, is likely to be at a different address. The calling of the functions happens to work, because they are located in ROM and cannot be different for application and loader. Calling them via const pointers, which are also stored in ROM, bypasses the problem.

该解决方案使用的是文件系统模拟器,如果可以找到适合您硬件的模拟器.

The solution is using a file system simulator, if you can find one for your hardware.

否则,您将不必执行以下操作.

Otherwise you will hate having to do the following.

第1部分,设置:

  • 引入一个特殊的链接器部分,其中所有系统变量(应用程序和加载程序)都可以访问所有变量
  • 让一个链接器填充它
  • 将其设置为其他链接器,不要设置为
  • 在初始化时要小心
    • 最好不要假设任何初始化值
    • 如果您需要初始化,例如"bss"(初始化为0)或"data"(初始化为指定值),
      在与链接器无关的系统部分的开头明确地执行此操作,您可以设置变量
    • 为了安全起见,建议在两个系统部分中以相同的方式进行初始化
    • 数据"初始化使用特殊的非易失性链接器节以及要初始化的变量的副本,可以进行访问
    • introduce a special linker section with all the variables accessed by both system paprts (application and loader)
    • let one linker fill it
    • set it up for the other linker as don't-tocuh
    • be careful with the initialisation
      • preferrably do not assume any intialisation value
      • if you need initialisation, e.g. "bss" (init to 0) or "data" (init to specified value),
        do so explicitly at the start of the system part which is not associated to the linker you let setup the variables
      • for safety, it is recommended to do the init the same way in both system parts
      • "data" init uses a special non-volatile linker section with a copy of the to-be-initialised variables, accessing that is possible

      第2部分,访问权限:

      • 选项1)
        存储指向这些变量的const指针,就像您对函数所做的一样
      • 选项2)
        获取第二个链接器(另一个没有实际设置公共变量部分的链接器),以创建与第一个链接器中的链接相同的结构和位置相同的部分;这里需要对链接器进行更多研究
      • option 1)
        store const pointers to those variables, like you did for the functions
      • option 2)
        get the second linker (the other one, which did not do the actual setup of the common variable section) to create an identically structured and identically located section as the one from first linker; more studying of your linker needed here

      第3部分,恢复由其他系统部分存储的值
      (例如,您想从加载程序中留下某种消息,以便阅读我的应用程序)

      Part 3, resuing values stored by other system part
      (e.g. you want to leave some kind of message from loader, to be read my application)

      • 设计哪个系统部分感染哪个变量,另一个只读取它们
      • 将公用变量分成四个部分,
        • 由两个系统部分写入和读取,并由两个系统初始化
        • 由x写入和读取,仅由y读取,由x初始化
        • 由y编写和读取,仅由x读取,由y初始化
        • 由两个系统部分编写,但未初始化,它们使用校验和和合理性提示,
          如果尚未初始化变量,则将其初始化为默认值
        • design which system part initisalises which variable, the other one only reads them
        • separate the common variables in four sections,
          • written and read by both system parts, initialised by both
          • written and read by x, only read by y, initialised by x
          • written and read by y, only read by x, initialised by y
          • written by both system parts, not initialised, uses checksums and plausibility cehcks,
            if a variable has not been initialised, init to default

          要做所有这些,需要深入研究链接器的功能和语法.
          因此,如果可以解决,我建议不要尝试.考虑使用现有的文件系统模拟器;因为那基本上就是上面的意思.

          To do all that, intense study of your linker features and syntax is needed.
          So I recommend not to try, if you can get around it. Consider using an existing file system simulator; because that is basically what above means.

          这篇关于使用指针功能-1个设备上2个独立的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆