GTL消息和(动态)内存分配

11个员额/0个新员额
最后一篇文章
阿布雷曼
离线
最后一次见到:4年2个月前
加入:2015-02-10 17:44
GTL消息和(动态)内存分配

亲爱的支持:,

目前,我正在一个定制嵌入式项目中实现GTL接口(通过UART)。我的第一个目标是让prox_reporter_ext项目与我们的外部处理器(DA1458x_SDK\5.0.2.1\projects\target_apps\ble_examples文件夹)一起工作。我使用了host_proxr_SDK项目作为参考(DA1458x_SDK\5.0.2.1\projects\host_apps\windows\approxity\reporter\folder)。

我面临的挑战是内存分配。到目前为止,我们已经避免在嵌入式代码中使用malloc/free,只是为了防止引入灾难性的副作用,例如内存泄漏(与RTO结合可能会带来新的挑战)。在上述项目的ble_msg中,我看到malloc和free通过例如BleMsgAlloc和BleFreeMsg使用,在uart.c中SendToMain也是如此。此外,UARTProc(uart.c)中的接收缓冲区大小为1000字节,最大数据包长度为350字节(uart.h)。在UARTSend(uart.c)中分配了另外500个字节。

根据我通过查看来源和阅读Integrated Process Application.pdf和UM-B-010_DA14580_581_583 Proximition Application_v1.3.pdf中的UM-B-017 GTL接口所了解的情况,GTL接口不能归类为停止和等待协议。换句话说,DA14580可以在任何给定时刻将多个事件包/消息发送到外部处理器。另一方面,外部处理器可以在应用程序需要时发送命令包/消息。

我完全理解使用动态内存分配的原因,对于可变的数据包数量和可变的paru_LEN字段值,这是有意义的。然而,我想知道静态内存分配是否是一个可行的选择(从内存需求来看也是可以实现的)。在这种情况下,我想知道PAR_LEN的最大值是多少(消息可以包含的最大参数字节数)以及DA14580可能发送多少数据包/消息。如果可行,我可以创建一个X个数据包的循环缓冲区,每个数据包的参数最大为32kB(我们总共有32kB的RAM可用,因此,例如,每350字节有3个数据包,单独的读取缓冲区为350字节,写入缓冲区为350字节(用于异步读取/写入),这是不现实的。

我很想听听你对此的想法。如果可能的话,我宁愿不使用malloc/free。

亲切问候,,
阿扬

编辑日期:2015年11月2日
我在下面添加了有关endianness和数据结构填充的信息,也许其他论坛用户也会觉得这很有用。

设备:
阿布雷曼
离线
最后一次见到:4年2个月前
加入:2015-02-10 17:44
想听别人怎么说吗

我很想知道其他人是如何在内存有限的嵌入式系统中实现这一点的,或者malloc/free被认为是不好的做法。

亲切问候,,
阿扬

MT_对话框
离线
最后一次见到:6天6小时前
工作人员
加入:2015-06-08 11:34
嗨,艾伯曼,

嗨,艾伯曼,

我们从来没有考虑过这样做,但是可以做到。可以交换的潜在数据包的最大数量完全取决于当前的应用程序,我想您可以在当前的实现中使用某种计数器动态计算分配和发送的数据包数量,这样您就可以能够判断应该预先分配的内存大小。

谢谢你的对话

夏季20100514
离线
最后一次见到:4年2个月前
大师
加入:2014-12-30 05:01
您可以使用动态内存

您可以使用动态内存分配,并且可以选择由静态缓冲区实现的内存分配,而不是原始内存分配。此外,您还可以向项目DA14580_SDK_3.0.4.0\host_apps\windows\approxity\monitor添加一个调试函数,如printf,以查看发送和接收的数据包数量。就我而言,32kB的内存已经足够了,也许5kB就足够了。

阿布雷曼
离线
最后一次见到:4年2个月前
加入:2015-02-10 17:44
@MT_对话感谢您的支持

@感谢您的回复,我最终使用了动态内存分配,原因很明显。然而,尝试静态内存分配是有意义的。

@summer20100514感谢您的回复。请注意,我提到的32kB RAM是针对整个系统的,而不仅仅是与BLE相关的部分。所以5kB仍然是相当大的一块;-)。

也许您可以帮我解决一个新问题:SDK中的所有数据结构是否都明确地在正确的边界上对齐?或者是否假定数据结构将同时打包在DA14580和主机代码中(以便使用SDK)?我注意到sizeof经常用于确定不同消息参数的大小,我只是想知道是否考虑了潜在的隐式填充。

谢谢
阿扬

夏季20100514
离线
最后一次见到:4年2个月前
大师
加入:2014-12-30 05:01
你可以把地址打印出来

如果您对对齐方式不太确定,可以打印出地址。

阿布雷曼
离线
最后一次见到:4年2个月前
加入:2015-02-10 17:44
@summer20100514也许我

@summer20100514也许我应该澄清我的问题。

让我们以struct proxr_enable_req为例:


//sdk\ble\u stack\profiles\prox\proxr\proxr\u task.h

///@ref PROXR_ENABLE_REQ消息的参数
结构程序\u启用\u请求
{
///连接手柄
uint16_t conhdl;
///安全级别
uint8第二层;

///已保存LLS警报级别,以在ATT DB中设置
uint8警报层;
///发射功率电平
int8_t txp_lvl;
};

创建PROXR_ENABLE_REQ GTL数据包时,sizeof(struct PROXR_ENABLE_REQ)用于确定参数长度。在这种情况下,结构的编译值以及数据包参数长度的值为6;在成员txp_lvl之后添加一个额外的填充字节。换言之;最后一个成员填充所需的字节数,以便结构的总大小是任何结构成员最大对齐的倍数。

当将传入字节数组强制转换为消息的相应参数struct type时,我们需要确保发送方和接收方都考虑或不考虑此隐式填充。在proxr_enable_req的情况下,取消引用单个成员不会有真正的问题,因为填充仅添加在最后一个成员之后。Howe如果您举下面的例子,单个成员可能不是您期望的位置(取决于发送方和接收方是否对打包结构采用不同的规则)。

这是一个包含各种类型成员的结构,在编译之前总共有8个字节:


结构混合数据
{
字符数据1;
短数据2;
int数据3;
字符数据4;
};

编译后,将使用填充字节对数据结构进行补充,以确保其每个成员正确对齐:


在32位x86机器中编译后的struct MixedData/*结构*/
{
字符数据1;/*1字节*/
字符填充1[1];/*1字节,用于在2字节边界上对齐以下“短路”
假设结构开始的地址是偶数*/
短数据2;/*2字节*/
int Data3;/*4字节-最大结构成员*/
字符数据4;/*1字节*/
字符填充2[3];/*3字节,使结构的总大小为12字节*/
};

https://en.wikipedia.org/wiki/Data_structure_alignment

长话短说,我很想从Dialog本身了解使用DA SDK进行的设计选择。在字段之间发送数据包参数时是否有pad字节?

夏季20100514
离线
最后一次见到:4年2个月前
大师
加入:2014-12-30 05:01
我没有注意到这件事

我以前没有注意到这件事,但似乎没发生什么事。也许填充字节总是添加在最后一个成员之后?

阿布雷曼
离线
最后一次见到:4年2个月前
加入:2015-02-10 17:44
因为我还没来

由于我还没有遇到任何文档明确指定数据的结尾,以及数据结构是否打包,或者结构成员之间是否存在填充字节,因此我猜测,到目前为止,SDK只用于/打算用于(32位)具有少量endian内存体系结构的平台,没有打包结构(例如,我确实在SDK代码中找到了任何_属性_(打包))。

只要两个系统都使用sizeof(struct)来设置GTL数据包参数长度,并将传入和传出参数字节数组强制转换为这些结构类型,一切都会正常工作(因为两个平台都期望相同的结构成员填充/成员对齐)。

尽管我认为SDK的使用到目前为止都是如此,但我非常感谢Dialog本身对此事的回应。

-假设结构未打包(编译器添加的隐式填充)是否正确?
-没有添加明确的填充,以确保成员正确对齐,并且结构大小是其最大成员大小的倍数?(即,这将留给编译器处理)

请注意,我完全同意这种方法(使用我们当前的主机平台),因为我们的主机也使用32位ARM Cortex-M0+处理器。DA14580和主机处理器都配置了小端字节顺序。换句话说,sizeof()将在两个平台上返回相同的结果,并且结构成员在两个平台上的对齐方式将完全相同(编译器添加了相同的隐式填充)。

我在跨平台解决方案(具有不同的内存体系结构)中使用了大量面向字节、基于打包的协议。对于SDK来说,一个很好的未来补充可能是增加一个额外的抽象级别,通过指定字段之间不存在pad字节,并使用写/读模块以与endianness无关的方式写入/读取多字节数据类型。通过这种方式,您可以完全消除与平台相关的方面。

我是SDK的忠实粉丝(特别是5.0.3,我喜欢它!),我只是希望尽可能地把事情弄清楚:-)。

期待您的回复对话框。
亲切问候,,
阿扬

MT_对话框
离线
最后一次见到:6天6小时前
工作人员
加入:2015-06-08 11:34
嗨,艾伯曼,

嗨,艾伯曼,

对齐方式由编译器决定,原因是windows和ARM具有相同的endian(小endian)和大小。如果使用不同的体系结构,编译器将失败,您必须明确声明结构。

谢谢你的对话

阿布雷曼
离线
最后一次见到:4年2个月前
加入:2015-02-10 17:44
嗨,MT_dialog,

嗨,MT_dialog,

谢谢你的确认。此主题现在可能已结束。

亲切问候,,
阿扬

主题锁定