TCM SRAM等五块内存的使用和动态分配

TCM SRAM等五块内存的使用和动态分配

  • 配置sct文件
  • 内存使用
  • 动态内存分配
    • rtx_lib.h
    • rtx_memory.c
    • main.c

配置sct文件

LR_IROM1 0x08000000 0x00200000 { ; load region size_regionER_IROM1 0x08000000 0x00200000 { ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO)}; RW data - 128KB DTCMRW_IRAM1 0x20000000 0x00020000 { .ANY (+RW +ZI)}; RW data - 512KB AXI SRAMRW_IRAM2 0x24000000 0x00080000 { *(.RAM_D1) }; RW data - 128KB SRAM1(0x30000000) + 128KB SRAM2(0x3002 0000) + 32KB SRAM3(0x30040000)RW_IRAM3 0x30000000 0x00048000 { *(.RAM_D2)}; RW data - 64KB SRAM4(0x38000000)RW_IRAM4 0x38000000 0x00010000 { *(.RAM_D3)}
}

在这里插入图片描述

内存使用

/* 定义在 512KB AXI SRAM 里面的变量 */
__attribute__((section (".RAM_D1"))) uint32_t AXISRAMBuf[10];
__attribute__((section (".RAM_D1"))) uint16_t AXISRAMCount;
/* 定义在 128KB SRAM1(0x30000000) + 128KB SRAM2(0x30020000) + 32KB SRAM3(0x30040000)里面的变量 */
__attribute__((section (".RAM_D2"))) uint32_t D2SRAMBuf[10];
__attribute__((section (".RAM_D2"))) uint16_t D2SRAMount;
/* 定义在 64KB SRAM4(0x38000000)里面的变量 */
__attribute__((section (".RAM_D3"))) uint32_t D3SRAMBuf[10];
__attribute__((section (".RAM_D3"))) uint16_t D3SRAMCount;AXISRAMBuf[0] = AXISRAMCount++;
AXISRAMBuf[5] = AXISRAMCount++;
AXISRAMBuf[9] = AXISRAMCount++;D2SRAMBuf[0] = D2SRAMount++;
D2SRAMBuf[5] = D2SRAMount++;
D2SRAMBuf[9] = D2SRAMount++;D3SRAMBuf[0] = D3SRAMCount++;
D3SRAMBuf[5] = D3SRAMCount++;
D3SRAMBuf[9] = D3SRAMCount++;

动态内存分配

rtx_lib.h

#ifndef RTX_LIB_H_
#define RTX_LIB_H_#include <string.h>
#include <stdint.h>
#include "stm32h7xx.h"//  Memory Pool Header structure
typedef struct {uint32_t size;                // Memory Pool sizeuint32_t used;                // Used Memory
} mem_head_t;//  Memory Block Header structure
typedef struct mem_block_s {struct mem_block_s *next;     // Next Memory Block in listuint32_t            info;     // Block Info or max used Memory (in last block)
} mem_block_t;//  Memory Block Info: Length = <31:2>:'00', Type = <1:0>
#define MB_INFO_LEN_MASK        0xFFFFFFFCU     // Length mask
#define MB_INFO_TYPE_MASK       0x00000003U     // Type mask//  Memory Head Pointer
__STATIC_INLINE mem_head_t *MemHeadPtr (void *mem) {//lint -e{9079} -e{9087} "conversion from pointer to void to pointer to other type" [MISRA Note 6]return ((mem_head_t *)mem);
}//  Memory Block Pointer
__STATIC_INLINE mem_block_t *MemBlockPtr (void *mem, uint32_t offset) {uint32_t     addr;mem_block_t *ptr;//lint --e{923} --e{9078} "cast between pointer and unsigned int" [MISRA Note 8]addr = (uint32_t)mem + offset;ptr  = (mem_block_t *)addr;return ptr;
}//  ==== Library functions ====// Memory Heap Library functions
extern uint32_t osRtxMemoryInit (void *mem, uint32_t size);
extern void    *osRtxMemoryAlloc(void *mem, uint32_t size, uint32_t type);
extern uint32_t osRtxMemoryFree (void *mem, void *block);#endif  // RTX_LIB_H_

rtx_memory.c

#include "rtx_lib.h"//  ==== Library functions ====/// Initialize Memory Pool with variable block size.
/// \param[in]  mem             pointer to memory pool.
/// \param[in]  size            size of a memory pool in bytes.
/// \return 1 - success, 0 - failure.
__WEAK uint32_t osRtxMemoryInit (void *mem, uint32_t size) {mem_head_t  *head;mem_block_t *ptr;// Check parameters//lint -e{923} "cast from pointer to unsigned int" [MISRA Note 7]if ((mem == NULL) || (((uint32_t)mem & 7U) != 0U) || ((size & 7U) != 0U) ||(size < (sizeof(mem_head_t) + (2U*sizeof(mem_block_t))))) {//EvrRtxMemoryInit(mem, size, 0U);//lint -e{904} "Return statement before end of function" [MISRA Note 1]return 0U;}// Initialize memory pool headerhead = MemHeadPtr(mem);head->size = size;head->used = sizeof(mem_head_t) + sizeof(mem_block_t);// Initialize first and last block headerptr = MemBlockPtr(mem, sizeof(mem_head_t));ptr->next = MemBlockPtr(mem, size - sizeof(mem_block_t));ptr->next->next = NULL;ptr->next->info = sizeof(mem_head_t) + sizeof(mem_block_t);ptr->info = 0U;//EvrRtxMemoryInit(mem, size, 1U);return 1U;
}/// Allocate a memory block from a Memory Pool.
/// \param[in]  mem             pointer to memory pool.
/// \param[in]  size            size of a memory block in bytes.
/// \param[in]  type            memory block type: 0 - generic, 1 - control block
/// \return allocated memory block or NULL in case of no memory is available.
__WEAK void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type) {mem_block_t *ptr;mem_block_t *p, *p_new;uint32_t     block_size;uint32_t     hole_size;// Check parametersif ((mem == NULL) || (size == 0U) || ((type & ~MB_INFO_TYPE_MASK) != 0U)) {//EvrRtxMemoryAlloc(mem, size, type, NULL);//lint -e{904} "Return statement before end of function" [MISRA Note 1]return NULL;}// Add block header to sizeblock_size = size + sizeof(mem_block_t);// Make sure that block is 8-byte alignedblock_size = (block_size + 7U) & ~((uint32_t)7U);// Search for hole big enoughp = MemBlockPtr(mem, sizeof(mem_head_t));for (;;) {//lint -e{923} -e{9078} "cast from pointer to unsigned int"hole_size  = (uint32_t)p->next - (uint32_t)p;hole_size -= p->info & MB_INFO_LEN_MASK;if (hole_size >= block_size) {// Hole foundbreak;}p = p->next;if (p->next == NULL) {// Failed (end of list)//EvrRtxMemoryAlloc(mem, size, type, NULL);//lint -e{904} "Return statement before end of function" [MISRA Note 1]return NULL;}}// Update used memory(MemHeadPtr(mem))->used += block_size;// Update max used memoryp_new = MemBlockPtr(mem, (MemHeadPtr(mem))->size - sizeof(mem_block_t));if (p_new->info < (MemHeadPtr(mem))->used) {p_new->info = (MemHeadPtr(mem))->used;}// Allocate blockif (p->info == 0U) {// No block allocated, set info of first elementp->info = block_size | type;ptr = MemBlockPtr(p, sizeof(mem_block_t));} else {// Insert new element into the listp_new = MemBlockPtr(p, p->info & MB_INFO_LEN_MASK);p_new->next = p->next;p_new->info = block_size | type;p->next = p_new;ptr = MemBlockPtr(p_new, sizeof(mem_block_t));}//EvrRtxMemoryAlloc(mem, size, type, ptr);return ptr;
}/// Return an allocated memory block back to a Memory Pool.
/// \param[in]  mem             pointer to memory pool.
/// \param[in]  block           memory block to be returned to the memory pool.
/// \return 1 - success, 0 - failure.
__WEAK uint32_t osRtxMemoryFree (void *mem, void *block) {const mem_block_t *ptr;mem_block_t *p, *p_prev;// Check parametersif ((mem == NULL) || (block == NULL)) {//EvrRtxMemoryFree(mem, block, 0U);//lint -e{904} "Return statement before end of function" [MISRA Note 1]return 0U;}// Memory block headerptr = MemBlockPtr(block, 0U);ptr--;// Search for block headerp_prev = NULL;p = MemBlockPtr(mem, sizeof(mem_head_t));while (p != ptr) {p_prev = p;p = p->next;if (p == NULL) {// Not found//EvrRtxMemoryFree(mem, block, 0U);//lint -e{904} "Return statement before end of function" [MISRA Note 1]return 0U;}}// Update used memory(MemHeadPtr(mem))->used -= p->info & MB_INFO_LEN_MASK;// Free blockif (p_prev == NULL) {// Release first block, only set info to 0p->info = 0U;} else {// Discard block from chained listp_prev->next = p->next;}//EvrRtxMemoryFree(mem, block, 1U);return 1U;
}

main.c

/* D1, AXI SRAM, 512KB */
mem_head_t *AXISRAMUsed;
uint64_t AppMallocAXISRAM[512*1024/8]__attribute__((at(0x24000000)));/* D2, 128KB SRAM1(0x30000000) + 128KB SRAM2(0x30020000) + 32KB SRAM3(0x30040000)  */
mem_head_t *SRAM1Used; 
uint64_t AppMallocSRAM1[288*1024/8]__attribute__((at(0x30000000)));/* D3, SRAM4, 64KB */
mem_head_t *SRAM4Used;
uint64_t AppMallocSRAM4[64*1024/8]__attribute__((at(0x38000000)));
uint32_t *DTCM_Addres0, *AXISRAM_Addres0, *SRAM1_Addres0, *SRAM4_Addres0;
uint16_t *DTCM_Addres1, *AXISRAM_Addres1, *SRAM1_Addres1, *SRAM4_Addres1;
uint8_t  *DTCM_Addres2, *AXISRAM_Addres2, *SRAM1_Addres2, *SRAM4_Addres2;bsp_Init();osRtxMemoryInit(AppMallocDTCM,    sizeof(AppMallocDTCM));
osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
osRtxMemoryInit(AppMallocSRAM1,   sizeof(AppMallocSRAM1));
osRtxMemoryInit(AppMallocSRAM4,   sizeof(AppMallocSRAM4));/* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */
printf("=========================================================\r\n");
DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM 总大小 = %d 字节,申请大小 = 0280 字节,当前共使用大小 = %d 字节\r\n", DTCMUsed->size, DTCMUsed->used);
/* 从 DTCM 申请 64 字节空间,使用指针变量 DTCM_Addres1 操作这些空间时不要超过 64 字节大小 */
DTCM_Addres1 = osRtxMemoryAlloc(AppMallocDTCM, 64, 0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM 总大小 = %d 字节,申请大小 = 0064 字节,当前共使用大小 = %d 字节\r\n", DTCMUsed->size, DTCMUsed->used);/* 从 DTCM 申请 6111 字节空间,使用指针变量 DTCM_Addres2 操作这些空间时不要超过 6111 字节大小 */
DTCM_Addres2 = osRtxMemoryAlloc(AppMallocDTCM, 6111, 0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM 总大小 = %d 字节,申请大小 = 6111 字节,当前共使用大小 = %d 字节\r\n", DTCMUsed->size, DTCMUsed->used);
break;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/811684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 学习(4)——开发环境升级与项目 jdk 升级

各种版本都比较老&#xff0c;用起来也是常出各样的问题&#xff0c;终于找到一个看来不错的新教程&#xff0c;是原先那个教程的升级。遂决定升级一下开发环境&#xff0c;在升级遇到一些问题&#xff0c;摸索将其解决&#xff0c;得些体会记录备查。 最终确定开发环境约束如下…

蓝桥杯基础18——第13届省赛真题与代码详解

目录 0.心得体会 1.题目如下 2.代码实现的思路 键值扫描 数码管窗口切换 数码管的动态扫描 继电器工作时L3闪烁&#xff0c;整点时刻L1灯光亮5秒 3.变量列表 定义的常量和数组 功能控制和状态变量 定时器和计数变量 4.代码参考 4.1 头文件 onewire.h ds1302.h 4…

gpu服务器与cpu服务器的区别在哪?

GPU服务器与CPU服务器的区别主要体现在处理能力、应用场景、能源消耗和成本等方面。 处理能力&#xff1a;CPU&#xff08;中央处理器&#xff09;是计算机的“大脑”&#xff0c;负责执行指令和处理数据&#xff0c;它的设计注重于逻辑运算和串行处理能力。而GPU&#xff08;…

全球媒体发稿:海外发稿数字期刊Digital Journal

全球媒体发稿&#xff1a;海外发稿数字期刊Digital Journal ​官网&#xff1a; digitaljournal.com 数字期刊&#xff0c;加拿大知名门户&#xff0c;月访量超过30万。 是一个全球媒体平台和内容合作伙伴&#xff0c;通过捕捉和报道第一&#xff0c;提升新闻周期中的声…

文件上传【2】--靶场通关

1.前端禁用js绕过 上传文件&#xff0c;进行抓包&#xff0c;没有抓到&#xff0c;说明这里的验证是前端js验证跳出的弹窗 禁用js后&#xff0c;php文件上传成功。 2.文件上传.htaccess 上传png木马后连接不上 代码中存在.htaccess&#xff0c;判断此时应该就是需要用到.htac…

【通信原理笔记】【三】——3.7 频分复用

文章目录 前言一、时分复用&#xff08;TDM&#xff09;二、频分复用&#xff08;FDM&#xff09;总结 前言 现在我们学习了几种调制模拟基带信号的方法&#xff0c;这些调制方法可以将基带信号搬移到频带进行传输。那么如果采用不同的载波频率把多个基带信号搬移到不同的频带…

机器学习-09-图像处理02-PIL+numpy+OpenCV实践

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中图像处理技术。 参考 【人工智能】PythonOpenCV图像处理&#xff08;一篇全&#xff09; 一文讲解方向梯度直方图&#xff08;hog&#xff09; 【杂谈】计算机视觉在人脸图像领域的十几个大的应用方向&…

【LeetCode】1.两数之和

HashMap class Solution {public int[] twoSum(int[] nums, int target) {int a 0, b 0; // 返回两个索引HashMap<Integer, Integer> hm new HashMap<>(); // key是值&#xff0c;value是索引for (int i 0; i < nums.length; i) {if (!hm.containsKey(nums[…

基于SpringBoot的“汉服文化平台网站”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“汉服文化平台网站”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 系统功能界面图 用户登录、用…

论文阅读:Polyp-PVT: Polyp Segmentation with PyramidVision Transformers

这篇论文提出了一种名为Polyp-PVT的新型息肉分割框架&#xff0c;该框架采用金字塔视觉变换器&#xff08;Pyramid Vision Transformer, PVT&#xff09;作为编码器&#xff0c;以显式提取更强大的特征。本模型中使用到的关键技术有三个&#xff1a;渐进式特征融合、通道和空间…

定制个性化的 openEuler 系统镜像:打造独特的安装体验

前言 标准的操作系统镜像可能无法完全满足特定用户群体或特定应用场景的需求。通过定制化&#xff0c;可以根据具体需求预装特定软件、配置特定网络设置&#xff0c;甚至设置特定的用户权限&#xff0c;以确保系统能够满足用户的需求。定制化系统镜像可以优化安装流程&#xf…

mac配置Jmeter环境

mac配置Jmeter环境 一、安装jmeter二、Jmeter目录结构三、汉化Jmeter四、jmeter安装第三方插件 一、安装jmeter 第一步先自行配置好电脑的jdk环境 1、官网下载jar包 https://jmeter.apache.org/download_jmeter.cgi 2、解压到软件安装目录 3、启动Jmeter 启动方式1️⃣&#x…

洛谷-P1596 [USACO10OCT] Lake Counting S

P1596 [USACO10OCT] Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using namespace std; const int N110; int m,n; char g[N][N]; bool st[N][N]; //走/没走 int dx[] {-1,-1,-1,0,0,1,1,1}; //八联通 int dy[] {-1,0,1,1,-1,1…

docker:chown socket at step GROUP: No such process

docker:chown socket at step GROUP: No such process 原因&#xff1a;docker无法找到Group组信息&#xff0c;docker组有可能被误删除&#xff0c; 解决方式&#xff1a; groupadd docker Docker是一种相对使用较简单的容器&#xff0c;我们可以通过以下几种方式获取信息&am…

uniapp 开发小程序如何检测到更新点击重启小程序完成更新?

官方文档&#xff1a;uni.getUpdateManager() | uni-app官网 示例代码&#xff1a; const updateManager uni.getUpdateManager();updateManager.onCheckForUpdate(function (res) {// 请求完新版本信息的回调console.log(res.hasUpdate); });updateManager.onUpdateReady(fu…

【读点论文】Segment Anything,视觉界的GPT,可以通过Prompt完成图像实体理解的视觉基础大模型,处理零样本任务

Segment Anything Abstract 我们介绍了Segment Anything&#xff08;SA&#xff09;项目&#xff1a;一种用于图像分割的新任务、模型和数据集。在数据收集循环中使用我们的高效模型&#xff0c;我们构建了迄今为止&#xff08;迄今为止&#xff09;最大的分割数据集&#xf…

【opencv】示例-imgcodecs_jpeg.cpp使用OpenCV库来创建和处理图像,并保存为不同JPEG采样因子的版本...

上层-原始图像 下层&#xff1a;编码解码后的lossy_img #include <opencv2/core.hpp> // 包含OpenCV核心功能的头文件 #include <opencv2/imgproc.hpp> // 包含OpenCV图像处理功能的头文件 #include <opencv2/imgcodecs.hpp> // 包含OpenCV图像编码解码功能…

jenkins+gitlab配置

汉化 1、安装Localization: Chinese (Simplified)插件 &#xff08;此处我已安装&#xff09; &#xff08;安装完成后重启jenkins服务即可实现汉化&#xff09; 新增用户权限配置 1、安装插件 Role-based Authorization Strategy 2、全局安全配置 3、配置角色权限 4、新建…

微信小程序 超市网上购物商城采购管理系统

本课题研究的是基于HBuilder X系统平台的超市网上商城进货管理系统&#xff0c;开发这款超市网上商城进货管理系统主要是为了帮助用户可以不用约束时间与地点进行所需信息。本文详细讲述了超市网上商城进货管理系统的界面设计及使用&#xff0c;主要包括界面的实现、控件的使用…

ETL结合飞书快速实现业务信息同步

一、ETL工具介绍 ETLCloud数据集成平台是一款针对IT以及数据工程师推出的全域数据集成平台产品。它是集实时数据集成和离线数据集成以及API发布为一体的数据集成平台。与其他开源数据集成工具相比&#xff0c;系统采用轻量化架构、具有更快的部署速度、更快的数据传输速度、更…