一、內存管理
- 靜態內存
概述
靜態內存管理模塊,提供了一套管理靜態內存塊的機制,支持用戶申請、釋放定長的內存塊。
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