C 使用指针函数-1台设备上的2个独立应用程序
不久前我问了这个问题,并开始实施建议的解决方案,但遇到了一些问题 在我的cortex M4上,我有两个独立的应用程序-引导加载程序和用户应用程序。现在我有一些(许多)功能,这两个应用程序都是一样的。所以我只为bootloader编译了它们,然后在指定的地址创建了一个函数指针数组,这对于用户应用程序来说是众所周知的。所以在应用程序中,我没有再次使用这些函数编译文件,但我在需要时使用这些指针 这是我试图使这两个应用程序通用的代码示例:C 使用指针函数-1台设备上的2个独立应用程序,c,pointers,embedded,C,Pointers,Embedded,不久前我问了这个问题,并开始实施建议的解决方案,但遇到了一些问题 在我的cortex M4上,我有两个独立的应用程序-引导加载程序和用户应用程序。现在我有一些(许多)功能,这两个应用程序都是一样的。所以我只为bootloader编译了它们,然后在指定的地址创建了一个函数指针数组,这对于用户应用程序来说是众所周知的。所以在应用程序中,我没有再次使用这些函数编译文件,但我在需要时使用这些指针 这是我试图使这两个应用程序通用的代码示例: static uint8_t m_var_1; /
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使用一个特殊的非易失性链接器部分,其中包含一个待初始化变量的副本,可以访问该部分
- 选项1)
存储指向这些变量的常量指针,就像对函数所做的那样 - 选项2)
获取第二个链接器(另一个,它没有实际设置公共变量节),以创建与第一个链接器相同的结构和位置节;这里需要对链接器进行更多的研究
(例如,您想从loader处留下一些信息,以便阅读我的申请)
- 设计哪个系统部分初始化哪个变量,另一个只读取它们
- 将常见变量分为四个部分,
- 由两个系统部件书写和阅读,并由两个系统部件进行初始化
- 由x写入和读取,仅由y读取,由x初始化
- 由y书写和阅读,仅由x阅读,由y草签
- 由两个系统部件编写,未初始化,使用校验和和合理性CEHCK,
如果变量尚未初始化,则初始化为默认值
- 仅在相应的writer系统部件中初始化每个部分
- 在另一个链接器中设置为“no init”
- 第四种情况下,在两个链接器中设置为“no init”
- 对于第四种情况,使用具有校验和更新和合理性的getter和setter
因此,如果你能避开它,我建议你不要尝试。考虑使用现有的文件系统模拟器;因为这基本上就是上面的意思 如果您使用的是共享代码,无论采用何种方式,都应该避免使用静态/全局变量(特别是在有多个线程调用的情况下)。是的,您可以使用multex来保护数据,但是您需要添加“lock()”和“unlock()”调用,并且它开始变得混乱。最好完全避免这些数据。如果您这样做,您可能会想在应用程序和操作系统之间使用一个隔离层——陷阱或类似的函数指针和共享变量不是最好的主意。