This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 可变数组数-此"动态内存"?

Guru**** 2330840 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/594553/variable-number-of-arrays---is-this-dynamic-memory

同事、

我意识到这不仅仅是 C 语言问题、而是 TM4C 问题... 或者至少是一个"嵌入式 c"。 但我将假定这里会出现一些很好的帮助。

假设我创建了一个库来处理测量特定传感器。 该传感器具有可在 sensorStruct_t 结构内组织在一起的参数、例如:

typedef 结构
{
uint32_t sensor.outbase;
uint32_t sensor.outpin;
uint32_t sensor.inbase;
uint32_t sensor.inpin;
uint32_t sensor.readrate;
浮动传感器温度;
float sensor.湿度;
}
sensorStruct_t;

我发现、大多数用于任何类似用途的库往往具有"初始化"调用。 如果我可以使用能够访问上述传感器所有元件的应用、初始化可能类似于:

sensorStruct_t sensorData1;
sensorInitialize (&sensorData1); 

这是干净的、有组织的。 但我不确定如何管理各种传感器...

我已经使用的一种解决方案是预先确定库中的最大结构数、而不是从应用程序传递指针、传递实际参数并让库端管理某种"结构数组":

localSensor = sensorInitialize (outbase、outpin、inbase、inpin、readrate); 

其中 localSensor 将只是函数返回的地址的指针。 初始化函数将传感器添加到"下一个可用插槽"中。

再说一次、可能是 C 编程类12 (我跳过了它)、但老实说、我不知道初始化"尽可能多的传感器..."的最佳方法。 现在、我实际上已经在库端创建了最大数量、并浪费了未使用的存储器位置。

我希望这个问题能得到正确的解释、因为用一个简洁的示例来说明清楚的一点有点困难... 对具体文献的任何评论或指导都是最受欢迎的。

此致

布鲁诺

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Bruno Saraiva"]

    我已经使用的一种解决方案是预先确定库中的最大结构数、而不是从应用程序传递指针、传递实际参数并让库端管理某种"结构数组":

    localSensor = sensorInitialize (outbase、outpin、inbase、inpin、readrate); 

    其中 localSensor 将只是函数返回的地址的指针。 初始化函数将传感器添加到"下一个可用插槽"中。

    [/报价]

    这已经是动态内存。 您刚刚编写了一个专用(池)分配器。

    这是使用分配的最安全的形式之一、因为内存是在编译时分配的。 缺点是传感器数量超出了最大容量、您无法从应用的另一部分窃取内存。 对于许多嵌入式系统、这不是什么大问题、因为您必须同时处理任何情况下的所有最大值。

    或者、如果在启动时分配了所有内容、则可以使用 malloc。 这可以很好地适应不同的配置、而不需要发明多个内存池。 只要您只分配并且永远不释放、您就没有分段问题、只要您在启动时执行此操作一次、您就只能在通常具有最佳报告和安全可能性的一个位置失败分配。

    由于您分配了最大值、因此您可能只需通过声明进行分配。 如果您只 能将传感器结构声明为使用它的功能的一部分、则动态分配没有太多优势。

    规则

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我没有问 Bruno 一个问题。 这是运行时可配置数量的传感器、还是在编译时已知(或知道)?

    如果是后者、那么代码生成也是一个很好的解决方案。 在第一种情况下、这甚至是合理的、但这取决于具体细节。

    Robert
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Robert、

    感谢这两篇文章。

    在编译时、传感器的数量未知。 目标是为产品提供一个固定的固件、代码初始化将能够以某种方式检查传感器的存在(可能通过硬件轮询、可能通过一些外部消息传递...) 无论如何、只有在确定传感器数量后、才会发生单独的传感器初始化。

    我想、在我的例子中、在库中分配最大数量的传感器不会成为问题。 即使实际结构占用大约40个字节、嗯... 现在、我们可以在每次编译中"浪费"大约8x40字节、最多允许初始化8个传感器...

    一个"未来"关注的问题是、我们正在考虑为沟通渠道制定同样的战略。 我们成功地为串行通信创建了合适的库、而公共库为8个端口预先分配了结构。 在这种情况下、情况甚至更糟、因为通信需要 Tx 和 Rx 缓冲器(是的、目前我们分配8个 Tx/Rx 缓冲器、即使只有1对 UART 电缆!)。 如果我们要使用公共库进行"任何类型的通信"、并将以太网、USB 等添加到游戏中、那么在前面创建/提交大量缓冲区肯定是不明智的!

    但不用担心、我只是想大声一点。 这种特殊情况最好通过在应用端声明的缓冲区来实现、并且可能只有放置在库端"通信结构"内部的公共参数。 此外、当事情变得如此复杂时、可能是时候改用基于 RTOS 的解决方案了!

    谢谢、

    布鲁诺

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Bruno Saraiva"]目标是为产品提供一个固定的固件

    过去的公司和我都曾考虑过这一点-但我们的领域并不是特别的"动态"-新的/改进的设备会经常"起泡?"    

    "一个固定固件"如何适应未来的"确保到达"器件?   (存在该问题-很可能会"推动更高价值的销售!)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CB1、我需要对它进行重新表述-作者头脑中清楚的情况不一定会在几英里之外向读者解释、因为您已经在三板连接线程上做了很好的表述。

    假设我有三种基于同一电路板的类似产品。 我们更希望所有三种产品只保留一个固件、而 MCU 会以某种方式检测产品的"版本"、并相应地运行。 这里对"一个固定固件"的描述与管理三个程序/项目不同、每个"相似产品"一个。

    这并不意味着它不会发展或不断变化、但我们仍会尽可能升级一个适用于不同产品的固件。

    除其他外、此类产品之间的一个区别是给定类型的传感器数量。 因此、在编译时、程序必须能够用于简单的单传感器以及更昂贵的八传感器烧烤。

    希望现在更有意义! 谢谢!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引述 user="Bruno Saraiva">我想说一下、我有三种基于同一电路板的类似产品。 我们更希望所有三种产品只保留一个固件、而 MCU 会以某种方式检测产品的"版本"、并相应地运行。 [/报价]

    我自己一直在使用类似的器件(目前一个电路板、一个图像、六个用途)。 单个图像和板意味着要跟踪和库存的项目更少。 差异主要由静态配置驱动、有些是手动编写的、有些是生成的代码。 考虑到这些处理器上可用的大量内存以及大多数应用所需的合理最小处理能力、工作正常。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Bruno Saraiva]'一个"未来"关注的问题是,我们正在考虑为通信渠道制定同样的战略。 我们成功地为串行通信创建了合适的库、而公共库为8个端口预先分配了结构。 在这种情况下、情况甚至更糟、因为通信需要 Tx 和 Rx 缓冲器(是的、目前我们分配8个 Tx/Rx 缓冲器、即使只有1对 UART 电缆!)。 如果我们要使用公共库进行"任何类型的通信"、将以太网、USB 等添加到游戏中、那么创建/提交大量缓冲区肯定不明智!

    除了将缓冲区分配进一步向上移动应用程序外、这可能会调用缓冲区的内存池或通过 malloc 进行启动分配。

    [引用用户="Bruno Saraiva"]。 此外、当事情变得如此复杂时、可能是时候改用基于 RTOS 的解决方案了![/引述]

    在这一点之前、我想。

    BTW 当您进行该切换时(可能是以前、现在我怀疑您可以使用它)、请查看 RMA (费率单调分析)。 它比听起来简单得多、而且知道您有坚实的基础是很好的。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的案例与我们的案例完全匹配、符合每一个单词!
    这里的一个板和一个固件可以执行几乎相同的操作、比如测量火车的速度或烘烤面团的糖级!
    当然、这只是夸大其词、产品高度相关、但我们通过这种方式更好地管理它。 只要我们足够小心、不能通过更改另一个产品的某些功能来破坏一个产品(通过认真隔离库来保证)。
    布鲁诺
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Robert - assistez-Moi、s'il vous plaît -您的"单板、一个图像、六个用途"... "正确"(即快速、轻松)欢迎并适应新添加的设备-被认为"对混合物有用?"

    我们是否可以将此"新添加的器件"限制为"特殊条件"-这样(一些)非标准(即不可预测)新接口时序(甚至是级别)必须由该"一个映像"适应?

    感谢您的观点、尤其是"如果"您"面对并克服了这一挑战。"   感谢您的论坛努力...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [报价用户="Robert Adsett"]查看 RMA (费率单调分析)[/quot]

    谢谢!

    退回材料授权?  )

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    布鲁诺-您即将"百般"地接近"CCB1领地!"    (通过包括第二个定义(更标准的定义(对于"rma") 、我们必须注意...)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    只需分享我的"案例研究"...
    新的#4具有适用于3个非常相似产品的固件、基于同一硬件、但该硬件具有非常不同的屏幕交互、测量的参数甚至使用"动态"(模式 d'emploi)。
    将第4个功能添加到现有代码中实际上比可能的替代练习容易/快得多:
    -将现有项目复制到新项目中
    -查找并删除与新产品无关的内容
    -实施新产品的功能
    此致
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Bruno Saraiva">退货授权?  :)[/报价]

    我这样说是有原因的;)

    不过、您会发现首字母缩略词引用了它。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    “克裂”工作人员(也)迅速进入,“手臂”-搜索“单调”(那里),得到了“有趣”的结果。   (尽管他们是"单音"的大师!)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Bruno Saraiva"]将第4个功能添加到现有代码中实际上要容易得多/快得多[/引用]

    这可能是事实--但我怀疑真相可以证明,"普遍"。

    大多数情况下(任何)添加新代码将需要更改的"测试/验证"协议-而"更广泛的代码"可能会"违反"您(过去)的测试/验证(尤其是机构批准)。

    一种尺寸可能(有时)适合所有尺寸-但我不会"依赖它"-它不太可能快/容易...    正如您所知-这在很大程度上取决于应用程序-合理的"简单"新应用程序将解决您的"更快/更轻松"索赔!    

    "银子弹"可能是"销售"-但它们可能不是"始终"工作...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="CB1_mobile "] Robert - assistez-Moi, s'il vous plaît -您的“单板,一个映像,六个用途”... "正确"(即快速、容易)欢迎并适应新添加的设备-被认为"对混合物有用?"

    当然。 其中很大一部分是有限的问题域。 它基本上是一种具有一些额外逻辑的传感器传动器类型的接口。 因此、模拟输入、数字输入、继电器驱动器、模拟电流环路输出和通过 CAN 进行通信的 RS-422 (Bruno、我们还使用 RMA 调度来定义 CAN 协议)。 产品中的多个电路板。

    模拟输入可通过跳线配置为+/-10V 或+/-20mA、覆盖绝大多数模拟发送器、最近的迭代添加了几个 RTD 输入、从而为我们节省了 RTD 发送器的成本。

    一组查找决定输入滤波、缩放、输入到 CAN 消息的转换 以及 CAN 消息到输出的转换。 以及一些电路板具有额外的处理能力。 要使用的配置和流程由分流器或开关决定。

    因此、通常添加(或删除、也会发生这种情况)传感器是更新表的问题。 更新 RS-422/485需要更多的工作。 如果您提前准备充分、则更改新传感器的比例可能只涉及更新非易失性存储器、而无需更新应用。

    这不适合所有应用、但对我们来说很好。 即使我们可以使用特定的板进行成本优化、这些通用板中的一个或两个也能更快地实现目标。

    OTOH 如果我 需要添加正交编码器之类的操作、我将无法在此设置中执行此操作。 我能使用的转速发生器。 我怀疑我也需要。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Robert -非常感谢-非常有启发性-非常详细。

    特别值得注意的是、您的告诫是、"不适合所有应用"、但"证明(或不)概念"和"在承诺日期之前交付"的能力确实证明了您的做法是合理的。 (大部分时间)

    至于您的"正交编码器"-商号/我(经常)注意到很难出现-尤其是当编码器的位置与(中央) MCU 存在"敌意或距离"时。   在这种情况下-我们(现在)采用(小型) Cortex M0 (宽温度范围、稳定版本)-管理编码器并(通过 RS422)传回"主控" MCU。   (在我们的情况下-通常是 Cortex M7)   也许这种方法"适合您"-并扩展您的"一个电路板"(外部器件住宿!)

    再次感谢...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="CB1_MOBILE "]特别注意的是您的注意事项:"不适合所有应用程序"

    完全正确、但它实际上描述了大部分 PLC 和数据采集域。 说到 Bruno、如果您想获得有关如何设置各种未知传感器的灵感、请查看 PLC 的作用。

    不过、我不会使用这种方法来控制车罩上的风扇。

    [引用 USER="CB1_MOBILE "]也许这种方法会"适合您"-并扩展您的"一个电路板"(外部器件调整!)

    这就是我们拥有422/485接口的情况。 不过可能是通过 Modbus RTU。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们认为-小引脚数 M0 (漫游于(TX)平原之外)-可以很好地应对"将传感器和/或意外或"困难"器件聚合到422/485合规性中的挑战-传递到您的"一个(主)板"。

    这些(过去/即将死亡)通信媒介的简单性和范围/稳健性肯定会挑战此类(过去/将来死亡)标签。   而且-在我们的领域-(消息通常是短消息)、由更复杂/更快的方法产生的"增益"可能(实际上)不会被注意到...   (在提取长期且要求苛刻的"学习曲线"时-通常从未真正"掌握"。)

    再次感谢。