Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用指针函数-1台设备上的2个独立应用程序_C_Pointers_Embedded - Fatal编程技术网

C 使用指针函数-1台设备上的2个独立应用程序

C 使用指针函数-1台设备上的2个独立应用程序,c,pointers,embedded,C,Pointers,Embedded,不久前我问了这个问题,并开始实施建议的解决方案,但遇到了一些问题 在我的cortex M4上,我有两个独立的应用程序-引导加载程序和用户应用程序。现在我有一些(许多)功能,这两个应用程序都是一样的。所以我只为bootloader编译了它们,然后在指定的地址创建了一个函数指针数组,这对于用户应用程序来说是众所周知的。所以在应用程序中,我没有再次使用这些函数编译文件,但我在需要时使用这些指针 这是我试图使这两个应用程序通用的代码示例: static uint8_t m_var_1; /

不久前我问了这个问题,并开始实施建议的解决方案,但遇到了一些问题

在我的cortex M4上,我有两个独立的应用程序-引导加载程序和用户应用程序。现在我有一些(许多)功能,这两个应用程序都是一样的。所以我只为bootloader编译了它们,然后在指定的地址创建了一个函数指针数组,这对于用户应用程序来说是众所周知的。所以在应用程序中,我没有再次使用这些函数编译文件,但我在需要时使用这些指针

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

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结束,例如,当被零除或使用指向空值函数的指针时,就会发生这种情况。我还不知道为什么,但我开始怀疑这些变量会发生什么
var_2
肯定位于堆栈上,所以这没有问题。但是
m_var_1
呢?在映射文件中,它在RAM中有一个指定的位置。但我没有为应用程序和引导加载程序提供单独的RAM部分。我不确定,但我有一种感觉,这个变量可能使用与为引导加载程序创建时相同的RAM位置。这可能吗?可能还有其他问题?

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

在应用程序中,即使变量也存在,也可能位于不同的地址。 函数的调用恰好起作用,因为它们位于ROM中,应用程序和加载程序不能不同。通过存储在ROM中的常量指针调用它们可以绕过这个问题

解决方案是使用一个文件系统模拟器,如果你能为你的硬件找到一个

否则你会讨厌做以下事情

第1部分,设置:

  • 引入一个特殊的链接器部分,其中包含系统PAPRT(应用程序和加载程序)访问的所有变量
  • 让一个链接器填充它
  • 为另一个链接器设置为don-tocuh
  • 小心初始化
    • 最好不要假设任何初始化值
    • 如果需要初始化,例如“bss”(初始化为0)或“数据”(初始化为指定值),
      在系统部件的开始处显式执行此操作,该部件与您允许设置变量的链接器不关联
    • 为了安全起见,建议在两个系统部件中以相同的方式进行初始化
    • “data”init使用一个特殊的非易失性链接器部分,其中包含一个待初始化变量的副本,可以访问该部分
第2部分,访问:

  • 选项1)
    存储指向这些变量的常量指针,就像对函数所做的那样
  • 选项2)
    获取第二个链接器(另一个,它没有实际设置公共变量节),以创建与第一个链接器相同的结构和位置节;这里需要对链接器进行更多的研究
第3部分,恢复其他系统部件存储的值
(例如,您想从loader处留下一些信息,以便阅读我的申请)

  • 设计哪个系统部分初始化哪个变量,另一个只读取它们
  • 将常见变量分为四个部分,
    • 由两个系统部件书写和阅读,并由两个系统部件进行初始化
    • 由x写入和读取,仅由y读取,由x初始化
    • 由y书写和阅读,仅由x阅读,由y草签
    • 由两个系统部件编写,未初始化,使用校验和和合理性CEHCK,
      如果变量尚未初始化,则初始化为默认值
  • 仅在相应的writer系统部件中初始化每个部分
  • 在另一个链接器中设置为“no init”
  • 第四种情况下,在两个链接器中设置为“no init”
  • 对于第四种情况,使用具有校验和更新和合理性的getter和setter
要做到这一切,需要深入研究链接器的功能和语法。

因此,如果你能避开它,我建议你不要尝试。考虑使用现有的文件系统模拟器;因为这基本上就是上面的意思

如果您使用的是共享代码,无论采用何种方式,都应该避免使用静态/全局变量(特别是在有多个线程调用的情况下)。是的,您可以使用multex来保护数据,但是您需要添加“lock()”和“unlock()”调用,并且它开始变得混乱。最好完全避免这些数据。如果您这样做,您可能会想在应用程序和操作系统之间使用一个隔离层——陷阱或类似的函数指针和共享变量不是最好的主意。