• 2.4 内存管理
    • 2.4.1 动态内存
      • 概述
      • API讲解
      • 编程实例
      • 运行效果
    • 2.4.2 静态内存
      • 概述
      • API讲解
      • 编程实例
      • 运行效果

    2.4 内存管理

    2.4.1 动态内存

    概述

    动态内存管理模块,提供了一套动态管理系统内存的机制,支持用户动态的申请、释放不定长内存块。

    API讲解
    编程实例

    1、在tos_config.h中,配置动态内存组件开关TOS_CFG_MMHEAP_EN:

    #define TOS_CFG_MMHEAP_EN 1u

    2、在tos_config.h中,配置动态内存池大小:

    #define TOS_CFG_MMHEAP_POOL_SIZE 0x2000

    3、编写main.c示例代码:

    1. #include "tos.h"
    2. #include "mcu_init.h"
    3.  
    4. #define STK_SIZE_TASK_DEMO 512
    5.  
    6. k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO];
    7.  
    8. k_task_t task_demo;
    9.  
    10. extern void entry_task_demo(void *arg);
    11.  
    12. void entry_task_demo(void *arg)
    13. {
    14. void *p = K_NULL, *p_aligned = K_NULL;
    15. int i = 0;
    16.  
    17. while (K_TRUE) {
    18. if (i == 1) {
    19. p = tos_mmheap_alloc(0x30);
    20. if (p) {
    21. printf("alloc: %x\n", (cpu_addr_t)p);
    22. }
    23. } else if (i == 2) {
    24. if (p) {
    25. printf("free: %x\n", p);
    26. tos_mmheap_free(p);
    27. }
    28. } else if (i == 3) {
    29. p = tos_mmheap_alloc(0x30);
    30. if (p) {
    31. printf("alloc: %x\n", (cpu_addr_t)p);
    32. }
    33. } else if (i == 4) {
    34. p_aligned = tos_mmheap_aligned_alloc(0x50, 16);
    35. if (p_aligned) {
    36. printf("aligned alloc: %x\n", (cpu_addr_t)p_aligned);
    37. if ((cpu_addr_t)p_aligned % 16 == 0) {
    38. printf("%x is 16 aligned\n", (cpu_addr_t)p_aligned);
    39. } else {
    40. printf("should not happen\n");
    41. }
    42. }
    43. } else if (i == 5) {
    44. p = tos_mmheap_realloc(p, 0x40);
    45. if (p) {
    46. printf("realloc: %x\n", (cpu_addr_t)p);
    47. }
    48. } else if (i == 6) {
    49. if (p) {
    50. tos_mmheap_free(p);
    51. }
    52. if (p_aligned) {
    53. tos_mmheap_free(p_aligned);
    54. }
    55. }
    56.  
    57. tos_task_delay(1000);
    58. ++i;
    59. }
    60. }
    61.  
    62. int main(void)
    63. {
    64. board_init();
    65. tos_knl_init();
    66. (void)tos_task_create(&task_demo, "receiver_higher_prio", entry_task_demo, NULL,
    67. 4, stack_task_demo, STK_SIZE_TASK_DEMO, 0);
    68. tos_knl_start();
    69. }
    运行效果

    alloc: 20000c8cfree: 20000c8calloc: 20000c8caligned alloc: 20000cc020000cc0 is 16 alignedrealloc: 20000d14

    实例代码

    2.4.2 静态内存

    概述

    静态内存管理模块,提供了一套管理静态内存块的机制,支持用户申请、释放定长的内存块。

    API讲解

    创建静态内存池接口:

    1. k_err_t tos_mmblk_pool_create(k_mmblk_pool_t *mbp, void *pool_start, size_t blk_num, size_t blk_size);

    这里详细讲解此api参数意义:

    • mbp

    静态内存池句柄。

    • pool_start

    静态内存池起始地址。

    • blk_num

    内存池将要划分的内存块个数。

    • blk_size

    每个内存块的大小。

    编程实例

    1、在tos_config.h中,配置静态内存组件开关TOS_CFG_MMBLK_EN:

    #define TOS_CFG_MMBLK_EN 1u

    2、编写main.c示例代码:

    1. #include "tos.h"
    2. #include "mcu_init.h"
    3.  
    4. #define STK_SIZE_TASK_DEMO 512
    5.  
    6. k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO];
    7.  
    8. k_task_t task_demo;
    9.  
    10. #define MMBLK_BLK_NUM 5
    11. #define MMBLK_BLK_SIZE 0x20
    12.  
    13. k_mmblk_pool_t mmblk_pool;
    14.  
    15. // 需要管理的静态内存池
    16. uint8_t mmblk_pool_buffer[MMBLK_BLK_NUM * MMBLK_BLK_SIZE];
    17.  
    18. // 记录从内存池中分配到的地址
    19. void *p[MMBLK_BLK_NUM] = { K_NULL };
    20.  
    21. extern void entry_task_demo(void *arg);
    22.  
    23. void entry_task_demo(void *arg)
    24. {
    25. void *p_dummy = K_NULL;
    26. k_err_t err;
    27. int i = 0;
    28.  
    29. printf("mmblk_pool has %d blocks, size of each block is 0x%x\n", 5, 0x20);
    30. // 从内存池中获取所有的block
    31. for (; i < MMBLK_BLK_NUM; ++i) {
    32. err = tos_mmblk_alloc(&mmblk_pool, &p[i]);
    33. if (err == K_ERR_NONE) {
    34. printf("%d block alloced: 0x%x\n", i, p[i]);
    35. } else {
    36. printf("should not happen\n");
    37. }
    38. }
    39.  
    40. // 前文逻辑已经将所有可用block分配完毕,继续分配会返回K_ERR_MMBLK_POOL_EMPTY错误码
    41. err = tos_mmblk_alloc(&mmblk_pool, &p_dummy);
    42. if (err == K_ERR_MMBLK_POOL_EMPTY) {
    43. printf("blocks exhausted, all blocks is alloced\n");
    44. } else {
    45. printf("should not happen\n");
    46. }
    47.  
    48. // 将前文分配得到的所有block归还到池中
    49. for (i = 0; i < MMBLK_BLK_NUM; ++i) {
    50. err = tos_mmblk_free(&mmblk_pool, p[i]);
    51. if (err != K_ERR_NONE) {
    52. printf("should not happen\n");
    53. }
    54. }
    55. // 前文的归还动作中已经将所有的block归还到池中,继续规范会返回K_ERR_MMBLK_POOL_FULL错误码
    56. err = tos_mmblk_free(&mmblk_pool, p[0]);
    57. if (err == K_ERR_MMBLK_POOL_FULL) {
    58. printf("pool is full\n");
    59. } else {
    60. printf("should not happen\n");
    61. }
    62. }
    63.  
    64. int main(void)
    65. {
    66. board_init();
    67. tos_knl_init();
    68. // 创建静态内存池
    69. tos_mmblk_pool_create(&mmblk_pool, mmblk_pool_buffer, MMBLK_BLK_NUM, MMBLK_BLK_SIZE);
    70. (void)tos_task_create(&task_demo, "receiver_higher_prio", entry_task_demo, NULL,
    71. 4, stack_task_demo, STK_SIZE_TASK_DEMO, 0);
    72. tos_knl_start();
    73. }
    运行效果

    mmblk_pool has 5 blocks, size of each block is 0x200 block alloced: 0x200009741 block alloced: 0x200009942 block alloced: 0x200009b43 block alloced: 0x200009d44 block alloced: 0x200009f4blocks exhausted, all blocks is allocedpool is full

    实例代码