亲爱的支持,
目前我正在在自定义嵌入式项目中实现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)。
The challenge I'm facing is with memory allocation. Up until now we have avoided using malloc/free in our embedded code, simply to prevent introducing disastrous side effects such as memory leaks (also it might introduce new challenges in combination with our RTOS). In ble_msg of the aforementioned project I see that malloc and free are used via for example BleMsgAlloc and BleFreeMsg, the same goes for SendToMain in uart.c. Furthermore the receive buffer in UARTProc (uart.c) is 1000 bytes in size, with MAX_PACKET_LENGTH being 350 bytes (uart.h). Another 500 bytes are allocated in UARTSend (uart.c).
From what I understand from going through the sources and reading through UM-B-017 GTL interface in Integrated Process Application.pdf and UM-B-010_DA14580_581_583 Proximity application_v1.3.pdf, the GTL interface cannot be classified as a stop-and-wait protocol. In other words, multiple event packets / messages can be sent by the DA14580 to the external processor at any given moment. On the other hand the external processor can send a command packet / message whenever required by the application.
我完全理解使用动态内存分配的原因,它具有可变的数据包和变量par_len字段值。但是,我想知道静态内存分配是否是可行的选项(并且可实现的内存要求)。在这种情况下,我想知道par_len的最大值是什么(消息可以包含的参数的最大字节数)以及DA14580可能会发送多少个数据包/消息。如果是可行的,我可以创建一个X个数据包的循环缓冲区,每个数据包都有max_par_len字节的参数(我们有32kb的总共可用,因此每个350个字节的350个字节的350个字节的数据包,其中350字节的单独读缓冲区为350字节和a写入350字节的缓冲区(对于异步读取/写入)不是很真实)。
I would love to hear your thoughts on this. If at all possible, I would rather not use malloc / free.
亲切的问候,
arjan.
编辑02-11-2015.
I have added information regarding endianness and data structure padding below, perhaps other forum users might find this useful as well.
Would love to hear how others implemented this in embedded systems with limited memory and/or where malloc/free was considered bad practice.
亲切的问候,
arjan.
嗨,ablimen,
我们从来没有考虑做这样的事情,但可以做到这一点。可以在当前应用程序中完全依赖于当前应用程序的最大潜在数据包,我想您可以使用柜台的一些数据可以动态计算当前的实施方式,并将其发送,并将其发送能够判断应预先分配的内存大小。
Thanks MT_dialog
You can use dynamic memory allocation, and you can choose one implemented by static buffers instead of the origin one. What's more, you can add one debug function such as printf to the project DA14580_SDK_3.0.4.0\host_apps\windows\proximity\monitor to see how many packets are send and received. As far as I am concerned, 32kB of RAM is fully sufficient, maybe 5kB is enough.
@mt_dialog感谢您的回复,我最终使用动态内存分配以获得明显的原因。然而,它具有静态内存分配的有意义的实验。
@ Summer20100514谢谢您的回复。请注意,我提到的32KB的RAM是整个系统,而不仅仅是它的BLE相关部分。所以5KB仍然是一个相当大的块;-)。
也许你可以帮助我解决一个新问题;SDK中的所有数据结构都在正确的边界上明确对齐吗?或者它假设数据结构将包装在DA14580中以及主机代码(为了使用SDK)?我注意到尺寸频繁地用于确定不同消息参数的大小,我只是想知道是否考虑了潜在的隐式填充。
谢谢,
arjan.
如果您不太确定对齐,则可以打印出地址。
@ Summer20100514也许我应该澄清我的问题。
让我们拍摄struct proxr_enable_req:
// sdk\ble_stack\profiles\prox\proxr\proxr_task.h
/// Parameters of the @ref PROXR_ENABLE_REQ message
struct proxr_enable_req.
{
/// Connection Handle
uint16_t conhdl;
/// 安全级别
uint8_t sec_lvl;
///保存LLS警报级别以在ATT DB中设置
uint8_t lls_alert_lvl;
/// TX功率电平
INT8_T TXP_LVL;
};
When creating a PROXR_ENABLE_REQ GTL packet, sizeof(struct proxr_enable_req) is used to determine the parameter length. In this case the compiled value of the struct, and thus the value for the packet parameter length, is 6; An additional byte of padding is added just after member txp_lvl. In other words; The last member is padded with the number of bytes required so that the total size of the structure is a multiple of the largest alignment of any structure member.
当将传入的字节数组施放到消息的相应参数的相应参数时,我们需要确保发件人和接收器不考虑这种隐式填充。在Proxr_Enable_Req的情况下,我们不会有一个真正的问题解除了个别成员,因为填充仅在最后一个成员之后添加。但是,如果您采取以下示例,则各个成员可能不是您希望它们的位置(取决于发送方和接收方是否假设有关包装结构的不同规则)。
Long story short, I'm curious to learn from Dialog itself which design choice was made with the DA SDK. Are packet parameters sent with or without pad bytes in between fields?
我之前没有注意到这件事,但它似乎发生了错误。也许填充字节总是在最后一个成员后添加?
由于我尚未遇到任何明确地指定数据的文档,因为在结构成员之间包含数据结构以及数据结构是否存在,我的猜测是直到现在,SDK仅用于/打算(32位)平台,带有少量内存架构的没有结构(例如,我在SDK代码中找到了任何__Attribute __(packed))。
只要两个系统都使用sizeof(struct)来设置GTL报文参数长度并将传入和传出参数字节数组传递给这些结构类型,一切都将正常工作(因为两个平台期望相同的结构构件填充/成员对齐)。
即使是艰难的我相信这是这种情况,迄今为止如何使用SDK,我真的很感谢对话本身的回应。
- 是否假设结构未打包(编译器添加的隐式填充)是正确的?
- There is no explicit padding added to make sure that members align properly and struct sizes are a multiple of the size of its largest member? (i.e. this is left to the compiler)
请注意,使用此方法(使用当前的主机平台)绝对没问题,因为我们的主机也使用32位ARM Cortex-M0 +处理器。DA14580和主处理器都配置了很少的字节字节顺序。换句话说,sizeof()将在两个平台上返回相同的结果,并且结构构件在两个平台上都会完全相同(编译器添加相同的隐式填充)。
I have worked quite a lot with these type of byte-oriented, packed based protocols in cross-platform solutions (with different memory architectures). Perhaps a good future addition for the SDK could be to add an extra level of abstraction, by specifying that no pad bytes exist in between fields and using a write/read module for writing/reading multi-byte data types in an endianness independent manner. This way you remove the platform-dependent aspect of it all.
I'm a big fan of the SDK (especially 5.0.3, love it!), I just like to get things cleared up as much as possible :-).
期待您的回复对话框。
亲切的问候,
arjan.
嗨,ablimen,
将对齐留给编译器来决定,原因是因为Windows和Arm具有相同的exidianess(小endian)和大小。在不同的体系结构的情况下,编译器将失败,您必须刚才声明结构。
Thanks MT_dialog
嗨mt_dialog,
Thanks for the confirmation. This topic may now be closed.
亲切的问候,
arjan.