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

实例代码