理想的跨平台库

时间:2010-11-30 16:33:14

标签: c embedded operating-system cross-platform hardware

必须创建一个新的软件库。该库没有系统I / O例程,只包含Init(config),Run(some_data_inputs)和DeInit(config)函数以及一些typedef和define。 Run()函数只处理给定的输入数据并生成输出数据,没有中断,线程,锁等。但是,它需要一些RAM来满足其内部需求。接口在头文件中描述,静态库包含实现。

这个库必须尽可能多的plarform。将此库移植到任何新平台上的任何新OS + CPU都必须要花几分钟时间。有时甚至可以在没有操作系统的平台上使用此lib。

因此,在开始开发之前,必须决定:

  1. 这个lib必须用ANSI-C编写,还是用ANSI-C的子集编写,因为某些平台可能不完全支持ANSI-C?
  2. 是否写一个抽象 层,封装一个 底层OS + CPU?
  3. 应该是这个抽象层 包括自己的内存管理器 (malloc / free例程)或全部 今天的平台已经提供了吗?

3 个答案:

答案 0 :(得分:4)

  
      
  1. 此lib必须以ANSI-C或甚至ANSI-C的子集编写   因为某些平台可能不支持   ANSI-C完全?
  2.   

两者都没有,我建议ISO C.自1990年以来,ANSI一直不是C的标准体.ISO C90应该无处不在。根据目标平台功能,随附的标准库可能是一个子集,或者可能需要实现存根以将其移植到特定目标。例如,通常在使用GCC的嵌入式系统中使用的Newlib C库需要基本的I / O存根(在这种情况下不需要,因为您已指定不进行I / O操作)和要实现的sbrk()函数。 sbrk()为堆分配器提供内存;它不需要操作系统,也可以从操作系统请求内存。

  
      
  1. 是否要编写一个抽象层,它封装了一个   底层OS + CPU?
  2.   

给出对此库设计施加的限制,似乎没有操作系统问题。标准库提供了内存分配的要求。

  
      
  1. 此抽象层是否应包含自己的内存管理器   (malloc / free例程)或全部   今天的平台已经提供了吗?
  2.   

回答(1);将它们作为标准库的一部分提供,或者使用该平台的现有实现。

最后你需要的是编写你的库来使用C90和标准库,那么只需将标准库移植到目标就可以了。如果还没有完成的话。

答案 1 :(得分:2)

按相反的顺序:

(3)。您需要自己的内存管理例程,如果不是出于任何其他原因,那么只是因为您希望它可以移植到没有底层操作系统的裸平台。然后你还需要一个实现几乎所有其他的东西:字符串库,数学库等。你必须自己编写代码,或者尝试找到为每个平台提供它们的现成代码库。

(2)。 OS和CPU有些正交变量。您可能会有更好的时间创建两个抽象层(一个用于不同的操作系统,一个用于不同的硬件平台),然后根据每个新平台的需要包含/覆盖定义。但是,是的,抽象层是一个更易于管理的解决方案,而不是用整个#ifdefs来填充您的代码。

(1)。这不是一个容易回答的问题。例如,如果您希望您的库在嵌入式系统或甚至微控制器上运行,则很可能并非所有ANSI C功能都可用,具体取决于开发工具的成熟度。也可能存在与语言本身无关的限制。硬件浮点单元在嵌入式系统中相对较少。堆栈大小可能有限等。我建议您对您感兴趣的平台进行调查,并尝试选择一个公共子集。

(0)。您可以从经济(甚至是可行性)的角度很好地发现,对于您最常见的目标平台支持的相当丰富的子集进行开发并在遇到新平台时重构您的代码是首选。尝试将youserlf限制为 most 公共子集可能会在稍微更强大的系统中削弱您的开发工作量和库的有效性。

( - 1)。您应该从具有所需可移植性水平的库的稀缺性(甚至完全缺乏)中实现,您想要实现的目标并不容易。做好准备!

答案 2 :(得分:0)

有许多不同风格的系统架构,写一些非常简单的东西,很容易移植到所有这些系统架构中,这可能是不可能的。

但我建议您编写接口,以便它们接收指向包含所需系统功能的结构的指针。您可以在每次调用中执行此操作,也可以在init例程中执行此操作。

通过这种方式,您可以将不同体系结构的代码差异限制在生成函数指针结构的代码中。

这也使得你可以通过改变这个结构来轻松地测试库来处理一个或多个这些例程的失败,这样如果你想测试malloc失败的正确处理,那么你只需要替换malloc结构中的指针,其中一个指针失败。

您也可以将系统函数包装在特定系统上,其函数可以为您提供库所期望的接口以及至少部分处理错误(例如转换为errno)。