硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4842|回复: 8
收起左侧

[ThreadX全家桶] 请教一下,ThreadX定时器回调里面不允许申请内存吗?

[复制链接]

1

主题

5

回帖

8

积分

新手上路

积分
8
发表于 2020-12-28 20:38:55 | 显示全部楼层 |阅读模式
ThreadX定时器回调里面不允许申请内存吗?
版本:ThreadX 6.1.2
文件:txe_byte_allocate.c
位置:Line 167
现象:使用函数 tx_byte_allocate() 申请字节内存时,该函数会判断当前正在运行的线程是否为定时器的线程,如果不是则继续向下执行,否则就返回 TX_CALLER_ERROR 的错误,导致内存申请失败。

  1. /**************************************************************************/
  2. /*                                                                        */
  3. /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
  4. /*                                                                        */
  5. /*       This software is licensed under the Microsoft Software License   */
  6. /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
  7. /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
  8. /*       and in the root directory of this software.                      */
  9. /*                                                                        */
  10. /**************************************************************************/


  11. /**************************************************************************/
  12. /**************************************************************************/
  13. /**                                                                       */
  14. /** ThreadX Component                                                     */
  15. /**                                                                       */
  16. /**   Byte Memory                                                         */
  17. /**                                                                       */
  18. /**************************************************************************/
  19. /**************************************************************************/

  20. #define TX_SOURCE_CODE


  21. /* Include necessary system files.  */

  22. #include "tx_api.h"
  23. #include "tx_initialize.h"
  24. #include "tx_thread.h"
  25. #include "tx_timer.h"
  26. #include "tx_byte_pool.h"


  27. /**************************************************************************/
  28. /*                                                                        */
  29. /*  FUNCTION                                               RELEASE        */
  30. /*                                                                        */
  31. /*    _txe_byte_allocate                                  PORTABLE C      */
  32. /*                                                           6.1          */
  33. /*  AUTHOR                                                                */
  34. /*                                                                        */
  35. /*    William E. Lamie, Microsoft Corporation                             */
  36. /*                                                                        */
  37. /*  DESCRIPTION                                                           */
  38. /*                                                                        */
  39. /*    This function checks for errors in allocate bytes function call.    */
  40. /*                                                                        */
  41. /*  INPUT                                                                 */
  42. /*                                                                        */
  43. /*    pool_ptr                          Pointer to pool control block     */
  44. /*    memory_ptr                        Pointer to place allocated bytes  */
  45. /*                                        pointer                         */
  46. /*    memory_size                       Number of bytes to allocate       */
  47. /*    wait_option                       Suspension option                 */
  48. /*                                                                        */
  49. /*  OUTPUT                                                                */
  50. /*                                                                        */
  51. /*    TX_POOL_ERROR                     Invalid memory pool pointer       */
  52. /*    TX_PTR_ERROR                      Invalid destination pointer       */
  53. /*    TX_WAIT_ERROR                     Invalid wait option               */
  54. /*    TX_CALLER_ERROR                   Invalid caller of this function   */
  55. /*    TX_SIZE_ERROR                     Invalid size of memory request    */
  56. /*    status                            Actual completion status          */
  57. /*                                                                        */
  58. /*  CALLS                                                                 */
  59. /*                                                                        */
  60. /*    _tx_byte_allocate                 Actual byte allocate function     */
  61. /*                                                                        */
  62. /*  CALLED BY                                                             */
  63. /*                                                                        */
  64. /*    Application Code                                                    */
  65. /*                                                                        */
  66. /*  RELEASE HISTORY                                                       */
  67. /*                                                                        */
  68. /*    DATE              NAME                      DESCRIPTION             */
  69. /*                                                                        */
  70. /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
  71. /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
  72. /*                                            resulting in version 6.1    */
  73. /*                                                                        */
  74. /**************************************************************************/
  75. UINT  _txe_byte_allocate(TX_BYTE_POOL *pool_ptr, VOID **memory_ptr,
  76.                                     ULONG memory_size,  ULONG wait_option)
  77. {

  78. UINT            status;
  79. #ifndef TX_TIMER_PROCESS_IN_ISR
  80. TX_THREAD       *thread_ptr;
  81. #endif


  82.     /* Default status to success.  */
  83.     status =  TX_SUCCESS;

  84.     /* Check for an invalid byte pool pointer.  */
  85.     if (pool_ptr == TX_NULL)
  86.     {
  87.         
  88.         /* Byte pool pointer is invalid, return appropriate error code.  */
  89.         status =  TX_POOL_ERROR;
  90.     }
  91.    
  92.     /* Now check for invalid pool ID.  */
  93.     else if  (pool_ptr -> tx_byte_pool_id != TX_BYTE_POOL_ID)
  94.     {
  95.         
  96.         /* Byte pool pointer is invalid, return appropriate error code.  */
  97.         status =  TX_POOL_ERROR;
  98.     }

  99.     /* Check for an invalid destination for return pointer.  */
  100.     else if (memory_ptr == TX_NULL)
  101.     {

  102.         /* Null destination pointer, return appropriate error.  */
  103.         status =  TX_PTR_ERROR;
  104.     }

  105.     /* Check for an invalid memory size.  */
  106.     else if (memory_size == ((ULONG) 0))
  107.     {

  108.         /* Error in size, return appropriate error.  */
  109.         status =  TX_SIZE_ERROR;
  110.     }
  111.    
  112.     /* Determine if the size is greater than the pool size.  */
  113.     else if (memory_size > pool_ptr -> tx_byte_pool_size)
  114.     {

  115.         /* Error in size, return appropriate error.  */
  116.         status =  TX_SIZE_ERROR;
  117.     }

  118.     else
  119.     {

  120.         /* Check for a wait option error.  Only threads are allowed any form of
  121.            suspension.  */
  122.         if (wait_option != TX_NO_WAIT)
  123.         {

  124.             /* Is call from ISR or Initialization?  */
  125.             if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0))
  126.             {
  127.         
  128.                 /* A non-thread is trying to suspend, return appropriate error code.  */
  129.                 status =  TX_WAIT_ERROR;
  130.             }
  131.         }
  132.     }
  133. #ifndef TX_TIMER_PROCESS_IN_ISR
  134.    
  135.     /* Check for timer execution.  */
  136.     if (status == TX_SUCCESS)
  137.     {

  138.         /* Pickup thread pointer.  */
  139.         TX_THREAD_GET_CURRENT(thread_ptr)

  140.         /* Check for invalid caller of this function.  First check for a calling thread.  */
  141.         if (thread_ptr == &_tx_timer_thread)
  142.         {

  143.             /* Invalid caller of this function, return appropriate error code.  */
  144.             status =  TX_CALLER_ERROR;
  145.         }
  146.     }
  147. #endif

  148.     /* Is everything still okay?  */
  149.     if (status == TX_SUCCESS)
  150.     {
  151.    
  152.         /* Check for interrupt call.  */
  153.         if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0))
  154.         {
  155.    
  156.             /* Now, make sure the call is from an interrupt and not initialization.  */
  157.             if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
  158.             {
  159.         
  160.                 /* Invalid caller of this function, return appropriate error code.  */
  161.                 status =  TX_CALLER_ERROR;
  162.             }
  163.         }
  164.     }

  165.     /* Determine if everything is okay.  */
  166.     if (status == TX_SUCCESS)
  167.     {

  168.         /* Call actual byte memory allocate function.  */
  169.         status =  _tx_byte_allocate(pool_ptr, memory_ptr, memory_size,  wait_option);
  170.     }

  171.     /* Return completion status.  */
  172.     return(status);
  173. }
复制代码
tx_byte_allocate.png
回复

使用道具 举报

212

主题

1051

回帖

1697

积分

至尊会员

More we do, more we can do.

积分
1697
发表于 2020-12-29 09:25:16 | 显示全部楼层
文档里写的允许在初始化和线程里使用,看代码也是。如果TIMER设的中断模式,就返回TX_CALLER_ERROR
回复

使用道具 举报

212

主题

1051

回帖

1697

积分

至尊会员

More we do, more we can do.

积分
1697
发表于 2020-12-29 09:29:58 | 显示全部楼层
中断里用tx_block_allocate()
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107439
QQ
发表于 2020-12-29 09:52:54 | 显示全部楼层
看代码是这个意思,不可以定时器组件回调调用,如果使能了#ifndef TX_TIMER_PROCESS_IN_ISR可以。
回复

使用道具 举报

1

主题

75

回帖

78

积分

初级会员

积分
78
发表于 2020-12-29 10:54:34 | 显示全部楼层
应该是不用于在定时器回调函数里面阻塞。把wait_option设置成TX_NO_WAIT就可以调用了。
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
 楼主| 发表于 2020-12-29 13:58:09 | 显示全部楼层
谢谢各位大佬的回复,由于我之前经常在 FreeRTOS 的定时器回调里面申请不定长的内存,所以才有了这样的需求。
1. ThreadX 里面确实可以使用 tx_block_allocate() 来申请固定长度的内存,但是这样做无法满足我现在的需求,其实这也是我不理解的地方,按道理来说 tx_byte_allocate() 与  tx_block_allocate() 的基本框架应该是一致的。
2. ThreadX 里面如果定义了宏 TX_TIMER_PROCESS_IN_ISR 的话 ThreadX 就不会启用软件定时器线程,超时的回调函数都会在定时器中断里面执行,但是 tx_byte_allocate() 函数会在 185 行退出,错误代码还是 TX_CALLER_ERROR。
3. tx_byte_allocate() 函数的 wait_option 我一直用的就是 TX_NO_WAIT,应该和这个选项没关系吧。
Note:The performance of this service is a function of the block size and the amount of fragmentation in the pool. Hence, this service should not be used during time-critical threads of execution.
文档中说:不应在时间关键线程执行期间使用 tx_byte_allocate() 函数。
可能是官方认为申请不定长的内存会影响系统的实时性吧。
我现在只好新建一个线程,然后人为延时一个固定的时间,来模拟软件定时器的执行,变相地实现这种功能。
  1. void app_thread_cb(ULONG thread_input)
  2. {
  3.         while (1) {
  4.                 tx_thread_sleep(10);
  5.                 app_timer_cb();
  6.         }
  7. }
复制代码
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107439
QQ
发表于 2020-12-30 09:14:13 | 显示全部楼层
gamerskyer 发表于 2020-12-29 13:58
谢谢各位大佬的回复,由于我之前经常在 FreeRTOS 的定时器回调里面申请不定长的内存,所以才有了这样的需求 ...

谢谢告知,回头我也测测。
回复

使用道具 举报

0

主题

57

回帖

57

积分

初级会员

积分
57
发表于 2020-12-30 09:38:23 | 显示全部楼层
首先中断中不允许处理费时间的操作,而内存分配的时候会有锁来保护资源,如此一来申请内存就会有阻塞
回复

使用道具 举报

19

主题

72

回帖

129

积分

初级会员

积分
129
发表于 2021-1-21 17:19:59 | 显示全部楼层
我也有这方面的需求,需要在回调函数中发布消息,而消息的内存是动态分配的,现象和你这边一样。还没想到一个好的办法解决。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-1 00:31 , Processed in 0.188048 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表