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

11个帖子/ 0新
最后一篇
ablimen.
离线
最后一次露面:4年8月前
加入:2015-02-10 17:44
GTL消息和(动态)内存分配

亲爱的支持,

目前我正在在自定义嵌入式项目中实现GTL接口(OVER 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 \ proximity \ reporter \ folder)。

我面临的挑战是内存分配。直到现在我们已经避免使用Malloc /免费在我们的嵌入式代码中使用,只需防止引入灾难性的副作用,例如内存泄漏(也可能与我们的RTO结合引入新的挑战)。在上述项目的BLE_MSG中,我看到MALLOC和免费使用例如BLEMSGALLOC和BLEFREEMSG,同样用于UART.C中的Sendtomain。此外,UARTPROC(UART.C)中的接收缓冲区的大小为1000个字节,MAX_PACKET_LENGTH为350字节(UART.H)。在UARTSEND(UART.C)中分配了另外500个字节。

从我所理解的来源和通过综合进程应用程序的UM-B-017 GTL接口阅读.pdf和UM-B-010_DA14580_581_583 Proximity Application_v1.3.pdf,GTL接口不能被分类为停止 -等待协议。换句话说,DA14580可以在任何给定时刻将DA14580发送到外部处理器的多个事件分组/消息。另一方面,外部处理器可以在应用程序所需时发送命令包/消息。

我完全理解使用动态内存分配的原因,它具有可变的数据包和变量par_len字段值。但是,我想知道静态内存分配是否是可行的选项(并且可实现的内存要求)。在这种情况下,我想知道par_len的最大值是什么(消息可以包含的参数的最大字节数)以及DA14580可能会发送多少个数据包/消息。如果是可行的,我可以创建一个X个数据包的循环缓冲区,每个数据包都有max_par_len字节的参数(我们有32kb的总共可用,因此每个350个字节的350个字节的350个字节的数据包,其中350字节的单独读缓冲区为350字节和a写入350字节的缓冲区(对于异步读取/写入)不是很真实)。

我很想听到你的想法。如果可能,我宁愿不使用malloc /免费。

亲切的问候,
arjan.

编辑02-11-2015.
我添加了有关外部性和数据结构填充的信息,也许其他论坛用户也可能会发现这种有用。

设备:
ablimen.
离线
最后一次露面:4年8月前
加入:2015-02-10 17:44
很想听到别人

很乐意听到别人在嵌入式系统中如何在具有有限的嵌入式系统中实现这一点和/或Malloc /免费被认为是不良的做法。

亲切的问候,
arjan.

mt_dialog.
离线
最后一次露面:5个月2周前
职员
加入:2015-06-08 11:34
嗨,ablimen,

嗨,ablimen,

我们从来没有考虑做这样的事情,但可以做到这一点。可以在当前应用程序中完全依赖于当前应用程序的最大潜在数据包,我想您可以使用柜台的一些数据可以动态计算当前的实施方式,并将其发送,并将其发送能够判断应预先分配的内存大小。

谢谢mt_dialog.

SUMMER20100514.
离线
最后一次露面:4年8月前
格鲁鲁
加入:2014-12-30 05:01
您可以使用动态内存

您可以使用动态内存分配,并且您可以选择由静态缓冲区实现的,而不是原点。更重要的是,您可以添加一个调试功能,如PrintF到Project DA14580_SDK_3.0.4.0 \ host_Apps \ Windows \ Proximity \ Monitor,看看发送和接收多少数据包。就我而言,32KB的RAM完全充分,也许5KB就足够了。

ablimen.
离线
最后一次露面:4年8月前
加入:2015-02-10 17:44
@mt_dialog谢谢你的

@mt_dialog感谢您的回复,我最终使用动态内存分配以获得明显的原因。然而,它具有静态内存分配的有意义的实验。

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

也许你可以帮助我解决一个新问题;SDK中的所有数据结构都在正确的边界上明确对齐吗?或者它假设数据结构将包装在DA14580中以及主机代码(为了使用SDK)?我注意到尺寸频繁地用于确定不同消息参数的大小,我只是想知道是否考虑了潜在的隐式填充。

谢谢,
arjan.

SUMMER20100514.
离线
最后一次露面:4年8月前
格鲁鲁
加入:2014-12-30 05:01
您可以打印出地址

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

ablimen.
离线
最后一次露面:4年8月前
加入:2015-02-10 17:44
@ summer20100514也许我

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

让我们拍摄struct proxr_enable_req:


// sdk \ ble_stack \ profiles \ prox \ proxr \ proxr_task.h

/// @ref proxr_enable_req消息的参数
struct proxr_enable_req.
{
///连接句柄
uint16_t conhdl;
/// 安全级别
uint8_t sec_l​​vl;

///保存LLS警报级别以在ATT DB中设置
uint8_t lls_alert_lvl;
/// TX功率电平
INT8_T TXP_LVL;
};

在创建Proxr_Enable_Req GTL数据包时,SizeOf(struct proxr_enable_req)用于确定参数长度。在这种情况下,结构的编译值,因此是分组参数长度的值为6;在成员TXP_LVL之后,添加了另外的填充字节。换句话说;最后一个成员用所需的字节数填充,使得结构的总大小是任何结构成员的最大对准的倍数。

当将传入的字节数组施放到消息的相应参数的相应参数时,我们需要确保发件人和接收器不考虑这种隐式填充。在Proxr_Enable_Req的情况下,我们不会有一个真正的问题解除了个别成员,因为填充仅在最后一个成员之后添加。但是,如果您采取以下示例,则各个成员可能不是您希望它们的位置(取决于发送方和接收方是否假设有关包装结构的不同规则)。

以下是具有各种类型的成员的结构,在编译之前总计8个字节:


结构混合数据
{
char data1;
短数据2;
int data3;
char data4;
};

编译后,数据结构将补充填充字节,以确保每个成员的适当对齐:


struct mixeddata / *编译32位x86机器* /
{
char data1;/ * 1字节* /
char padding1 [1];/ * 1字节用于以下“短”以在2字节边界上对齐
假设结构开始的地址是偶数* /
短数据2;/ * 2字节* /
int data3;/ * 4字节 - 最大的结构成员* /
char data4;/ * 1字节* /
Char Padding2 [3];/ * 3个字节,使结构的总大小为12字节* /
};

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

长话短说,我很想从对话本身学习哪些设计选择是用达SDK制作的。是否在字段之间发送或没有填充字节的数据包参数?

SUMMER20100514.
离线
最后一次露面:4年8月前
格鲁鲁
加入:2014-12-30 05:01
我没有注意到这件事

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

ablimen.
离线
最后一次露面:4年8月前
加入:2015-02-10 17:44
因为我还没有来

由于我尚未遇到任何明确地指定数据的文档,因为在结构成员之间包含数据结构以及数据结构是否存在,我的猜测是直到现在,SDK仅用于/打算(32位)平台,带有少量内存架构的没有结构(例如,我在SDK代码中找到了任何__Attribute __(packed))。

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

即使是艰难的我相信这是这种情况,迄今为止如何使用SDK,我真的很感谢对话本身的回应。

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

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

我在跨平台解决方案中使用了这些类型的面向字节的面向的基于包装的协议(具有不同的内存架构)。也许对于SDK的未来未来添加可以是添加额外的抽象级别,通过指定字段之间存在没有填充字节,并使用写/读取模块以以endianness独立方式写入/读取多字节数据类型。这样你就可以删除它的平台依赖性方面。

我是SDK的忠实粉丝(特别是5.0.3,爱它!),我只是喜欢尽可能地清理的东西:-)。

期待您的回复对话框。
亲切的问候,
arjan.

mt_dialog.
离线
最后一次露面:5个月2周前
职员
加入:2015-06-08 11:34
嗨,ablimen,

嗨,ablimen,

将对齐留给编译器来决定,原因是因为Windows和Arm具有相同的exidianess(小endian)和大小。在不同的体系结构的情况下,编译器将失败,您必须刚才声明结构。

谢谢mt_dialog.

ablimen.
离线
最后一次露面:4年8月前
加入:2015-02-10 17:44
嗨mt_dialog,

嗨mt_dialog,

谢谢你的确认。现在可以关闭此主题。

亲切的问候,
arjan.

主题锁定