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.
尊敬的 TI 支持:
我正在尝试使用 GNU GCC Linaro 9.2.1工具链、最大限度地减少应用中的每线程堆栈和堆使用量
当首次使用 errno 处理线程时、newlib 会为线程的_reent 结构分配动态缓冲区(我认为不使用任何其他可重入性功能)。
动态内存分配是一个小问题、我认为我可以忍受、因为希望每个线程只发生一次(我的线程都是静态的)。
问题的发生是因为内存分配过程需要大量堆栈使用、但之后线程不需要太多的内存。 如果我在线程开始时强制分配(例如通过将 errno 设置为0)、我可以最小化该线程的使用、从而避免稍后在嵌套 funcion 调用中进行分配、 但是、我仍然得到每线程700字节的堆栈使用、而在其余工作场景中、线程使用的是400图中的某些内容(如果从未使用过 errno、i.e:stdlib funcions 都很高兴使用外部环境无法控制的输入、如"strtoul")
我想知道是否有办法将 TI-RTOS 配置为静态为每个线程预先分配此结构、因此无需动态内存分配、堆和堆栈的使用都可以减少或删除。
谢谢你
您好、Pedro、
您是否使用了器件?
CC2640R2L 和 LAUNCHXL-CC26x2R1
您好、Pedro、
我正在将您的查询路由至正确的团队。
您好!
我已指派适当的专家回答您的问题。
请继续关注。
此致、
您好!
我不能完全确定我是否理解手头的问题。 我看到您提到"我的线程都是静态的"、但我并不完全确定您是如何创建线程的。
我产生怀疑的原因是、当任务是静态分配的(即直接在.cfg 文件上分配)、任务堆栈也可以定义为固定大小-请参阅 TI-RTOS 用户指南的第7.5.2节:
https://dev.ti.com/tirex/explore/node?node=ABkZJ9XPPWiX5v5YBrJbKg__pTTHBmu__LATEST
这似乎对您有所帮助吗?
此致、
拉斐尔
当首次使用 errno 处理线程时、newlib 会为线程的_reent 结构分配动态缓冲区(我认为不使用任何其他可重入性功能)。
[/报价]查看 simplelink_cc2640r2_sdk_5_10_00_02、它不是为__relent 结构分配动态缓冲区的 newlib、而是 SYS/BIOS Newlib RTS 库可重入性支持模块
[引用 userid="485546" URL"~/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/999116/ti-rtos-mcu-statically-preallocation-a-per-thread-struct-_reent-for-newlib-gcc-linaro ]我想知道是否有方法将 TI-RTOS 配置为静态为每个线程预先分配此结构、因此无需动态内存分配、堆和堆栈的使用量都可以减少或删除。查看 ti.sysbios.rts.gnu.ReentSupport 的文档或 simplelink_cc2640r2_sdk_5_10_00_02/kernel/tirtos/packages/ti/sysbios/rts/GNU/ReentSupport.c 的内容、我看不到任何现有的用于静态预分配每个线程结构的选项。 也许自定义任务创建挂钩可以实现这一点。
[引用 userid="485546" URL"~/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/999116/ti-rtos-mcu-statically-preallocation-a-per-thread-struct-_reent-for-newlib-gcc-linaro "]我不使用任何其他可重入性功能,我认为[/引用]在任务中首次使用 errno 时、避免动态内存分配的一个可能选项是在 SYS/BIOS cfg 文件中使用以下命令禁用可重入性支持:
var ReentSupport = xdc.useModule('ti.sysbios.rts.gnu.ReentSupport'); ReentSupport.enableReentSupport = false;
以上是指 __getreent()函数仅返回一个指向所有线程共享的全局__reent 结构的指针。 即删除每线程动态内存分配、但意味着运行时库函数不再可重入。 例如、看到 errno 的值随后在线程之间共享。
非常感谢您的回复、切斯特、
首先、您觉得自己有点像大师、您能不能让我来谈谈 TI 使用的构建标志以及 TI 提供的 newlib 的定制重建? 我看到有一个名为"origin.patch"的文件、但我认为我在这里缺少有关所使用的构建选项的内容。 我对 newlib 有点陌生。
以下只是在有人有类似场景/新想法/或 TI 考虑允许静态分配_reent 结构时的注意事项:
我现在看到缓冲区由 SYSBIOS RTS 分配、然后在 newlib 中发生神奇的事情(我不确定 TI 使用的构建标志、我认为它是使用_REENT_Small 编译的、但不确定_REENT_GLOBAL_STDIO_STREAMS)、因此调用了_SINIT 并执行一些操作。 无论如何、这里的路径看起来是修改 TI-RTOS/newlib 源代码、这对我来说现在可能太过于严格了。
关于自定义挂钩、如果我回答正确、_reent 结构的初始化应该在线程上下文中执行、这是堆栈已经设置后的结果、所以在堆栈使用方面没有太大差异、也许只是避免了堆分配、这对我来说不是什么问题。
不管怎样、将执行一些测试来查看堆栈的大量使用是来自 Memory_alloc 还是_REENT_INIT_PTR/_REENT_small_check_init
否则、我将尝试减少线程数量或完全避免在其中的某些线程上使用 stdlib、或者考虑禁用可重入性支持的选项、并在每次调用 stdlib 函数时使用全局互斥量。
感谢 您的设计、问题不是静态分配线程的堆栈、 但关于为每个创建的线程静态分配 newlib 的_reent 结构、以便在第一次使用 newlib 的可重入性功能时避免高堆栈使用量和堆内存使用量、这一点现在已在 SYSBIOS RTS 的可重入性支持模块中实现。
因此、我最初的问题的答案似乎是现在没有(简单)方法可以根据每个线程静态分配和初始化_reent 结构。