c - 嵌入式 C 文件结构建议

标签 c architecture embedded project-management

关闭。这个问题是opinion-based .它目前不接受答案。












想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它.

2年前关闭。




Improve this question




我在 C 中的典型嵌入式软件中找不到关于文件结构的好建议。SO 上有很多这样的问题和答案,但没有一个涵盖我提出的问题,或者似乎适用于 C 中的嵌入式系统。

我明白没有 Elixir 。如果这有助于缩小建议范围,我的典型应用程序必须适合具有 8 到 32 kB 闪存和几 kB RAM 的目标。时钟在 4 到 20 MHz 范围内。

1.图层

我已经看到源代码分层组织,每一层都有自己的目录:

  • 申请
  • 传输层
  • 硬件抽象层

  • 问题是模块通常在所有这些层中都有文件,因此在目录中分离层意味着单个模块的文件分散在各处。封装不良。

    2.目录中的模块,$ROOT/includes/中的h文件

    每个模块一个目录。好处是真正的封装。我不确定如何做好是如何发布模块的API。开源 PC 应用程序 SW 似乎:
  • 将所有源代码放在模块目录中(所有 C 文件和所有头文件都打算在模块中使用)
  • 将 API 头文件发布到模块目录之外,到 $PROJ_ROOT/includes .

  • 这样我就可以拥有 -I$PROJ_ROOT/includes (或等效)在我的编译器命令中,并且在我的 #include 中没有搜索路径陈述。

    一个问题是 API 在模块目录之外,从而破坏了封装。例如,在 VCS 中将模块作为独立的模块进行维护是比较困难的。

    3. 目录中有API的模块

    与上面相同,但 API 头文件位于模块目录中。适当的封装和更易于版本控制模块,但 API 头文件与其他模块头文件处于同一级别,这些头文件是私有(private)的。在模块之外包含这样一个“私有(private)”头文件的诱惑对于 future 的开发人员来说可能太大了,并且不可见哪个 h 文件是公开的,哪些不是。

    4. 目录中有API的模块,子目录中有私有(private)结构

    仅将 API 头文件直接放在模块目录中,其他所有文件放在一个或多个子目录中。这可能行得通,但我觉得结构越来越复杂,我不太喜欢。

    我觉得我应该选择 2 或 4,但会非常感谢洞察力。如何解决我描述的相关缺点?其他选择?

    这种大小的成功开源软件的链接也可能很好。也欢迎文学建议。

    最佳答案

    在如此有限的内存量下,应用程序 + 操作系统将相当小。我从事的项目有数 GB 的源代码、数千个模块的数量,以及构建“千兆字节”范围内的可安装二进制文件。当您达到该大小时,您肯定需要将头文件等放在正确的位置。

    但是,我认为以下是一个相当不错的概念:

  • 每个模块的源文件。模块可以通过“使用”(例如“基本/操作系统”、“图形”、“音频”、“网络”、“用户界面”、“应用程序”等)分成更大的组。
  • 每个模块都有一个“导出的包含”列表(从零到相当大),在构建模块时将其复制到一般的“${ROOT}/includes”类型目录。这提供了 EXTERNAL 接口(interface),但作为模块本身生成的目标文件也可以使用“${module}/includes”,其中有私有(private)声明和定义,而不是对 API 用户“公开”的。

  • 这大致是大多数大型项目的工作方式。如果它适用于大型项目,那么它也适用于小型项目。但是,如果源文件的数量是十几个或两个,我真的认为将其拆分没有太大意义 - 可能是“src”和“includes”,如果你愿意,也可能是“include/private”以确保 API 是干净的。保持简单有很大的好处!

    请注意,“导出”部分需要在编译实际模块之前构建,否则您必须确保模块之间绝对没有交叉通信 [或至少确保没有“早期”模块需要任何“后来的”模块头文件 - 如果系统变得越来越大,这将变得非常困难]。

    您还应该有一套关于您公开的方式和内容的规则,并在代码审查期间检查是否遵循这些规则。

    关于c - 嵌入式 C 文件结构建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17143835/

    相关文章:

    database - 交易最佳实践

    c - 以促进供应商库更新的方式修改供应商嵌入式库?

    c - 将任意/自定义标签添加到 (ex)ctags 文件

    c++ - 计算 trampoline hook 的 JMP 指令地址

    ios - 哪种 iOS 架构模式更好地优化代码 谁能解释一下?

    MySQL_Trigger_Problem_Uknown_Col

    无法编译和运行 minisat+ sat 求解器

    c - 如何解决合并排序C程序中的段错误?

    c - 从函数中为外部变量赋值

    embedded - 在 Modelica 中对简单的嵌入式系统进行建模