一、内存管理
- 静态内存
概述
静态内存管理模块,提供了一套管理静态内存块的机制,支持用户申请、释放定长的内存块。
API讲解
创建静态内存池接口:
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示例代码:
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "cmsis_os.h"
#include "stdio.h"
#include "tos_k.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define STK_SIZE_TASK_DEMO 512
k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO];
k_task_t task_demo;
#define MMBLK_BLK_NUM 5
#define MMBLK_BLK_SIZE 0x20
k_mmblk_pool_t mmblk_pool;
// 需要管理的静态内存池
uint8_t mmblk_pool_buffer[MMBLK_BLK_NUM * MMBLK_BLK_SIZE];
// 记录从内存池中分配到的地址
void *p[MMBLK_BLK_NUM] = { K_NULL };
extern void entry_task_demo(void *arg);
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
void entry_task_demo(void *arg)
{
void *p_dummy = K_NULL;
k_err_t err;
int i = 0;
printf("mmblk_pool has %d blocks, size of each block is 0x%x\n", 5, 0x20);
// 从内存池中获取所有的block
for (; i < MMBLK_BLK_NUM; ++i) {
err = tos_mmblk_alloc(&mmblk_pool, &p[i]);
if (err == K_ERR_NONE) {
printf("%d block alloced: 0x%x\n", i, p[i]);
} else {
printf("should not happen\n");
}
}
// 前文逻辑已经将所有可用block分配完毕,继续分配会返回K_ERR_MMBLK_POOL_EMPTY错误码
err = tos_mmblk_alloc(&mmblk_pool, &p_dummy);
if (err == K_ERR_MMBLK_POOL_EMPTY) {
printf("blocks exhausted, all blocks is alloced\n");
} else {
printf("should not happen\n");
}
// 将前文分配得到的所有block归还到池中
for (i = 0; i < MMBLK_BLK_NUM; ++i) {
err = tos_mmblk_free(&mmblk_pool, p[i]);
if (err != K_ERR_NONE) {
printf("should not happen\n");
}
}
// 前文的归还动作中已经将所有的block归还到池中,继续规范会返回K_ERR_MMBLK_POOL_FULL错误码
err = tos_mmblk_free(&mmblk_pool, p[0]);
if (err == K_ERR_MMBLK_POOL_FULL) {
printf("pool is full\n");
} else {
printf("should not happen\n");
}
}
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
tos_knl_init();
// 创建静态内存池
tos_mmblk_pool_create(&mmblk_pool, mmblk_pool_buffer, MMBLK_BLK_NUM, MMBLK_BLK_SIZE);
(void)tos_task_create(&task_demo, "receiver_higher_prio", entry_task_demo, NULL,
4, stack_task_demo, STK_SIZE_TASK_DEMO, 0);
tos_knl_start();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
(注:如果程序没有跑起来,去看看是不是等级优化设置导致的,把它改为Level 0 即可)
3、运行效果:
源码链接:Git