stm32 单片机的__attribute__ ((at())绝对定位及首次适应算法的动态内存管理

本段代码可单独作为一个模块放心使用。

单片机中 __attribute__( at(绝对地址) )的作用分两个,一个是绝对定位到Flash,另个一是绝对定位到RAM/SDRAM。

1、定位到flash中,一般用于固化的信息,如ID卡的ID号,flash标记等等

2、定位到RAM/SDRAM,一般用于数据量比较大的缓存,如动态内存分配的缓存,串口的接收缓存.

 

由于单片机的内存空间不够大,硬件设计会外加一个SDRAM等用来扩展存储空间。

这里为了方便动态内存管理所需要的较大缓存空间,就采用__attribute__( at(绝对地址) )定位到SDRAM

#define MEM_BASE                     0xD0700000

mem_TypeDef memory_pool __attribute__((at(MEM_BASE)));

//动态内存分配使用首次适应算法
/* Exported types ------------------------------------------------------------*/

#define SIZE_OF_PAGE     1024  
#define MAX_PAGE_NUMBER  1024
#define MSHIFT_BIT        10

//内存表的结构体
typedef struct
{
  uint32_t mallocBase;                    /* Memory pool base address */
  uint16_t size[MAX_PAGE_NUMBER];         /* Sizes Table to allow safe deallocation */
  uint8_t PageTable[MAX_PAGE_NUMBER];     /* Memory page state table '1'-> Allocated '0' -> Free */
}
mem_TypeDef;

//初始化内存表

void k_MemInit(void)
{
  memset(&memory_pool, 0, sizeof(mem_TypeDef));
  memory_pool.mallocBase = MEM_BASE + sizeof(mem_TypeDef);
}

void * k_malloc(size_t size)
{
  __IO uint16_t index = 0, counter = 0, start = 0;
  uint16_t PageCount = 0, NewStart = 0;
  
  if (size > 0)
  {
    /* look for the first contiguous memory that meet requested size. */
    while ( index < (MAX_PAGE_NUMBER))
    {
      if (memory_pool.PageTable[index++] == 0)
      {
        counter++;
        if (size <= (counter * SIZE_OF_PAGE))
        {
          PageCount = counter - 1;
          NewStart = start;
          /* Set memory region state to allocated */
          for (index = 0; index <= PageCount;index++)
          {
            memory_pool.PageTable[NewStart + index] = 1;
          }
          /* Save size */
          memory_pool.size[NewStart] = counter;
          /* return pointer to allocated region. */
          return (void *)((memory_pool.mallocBase + (start  << MSHIFT_BIT)) +  sizeof(uint32_t));

// 特别注意红色部分,分配地址的时候偏移4个字节的含义:函数参数传递进来的实际是指针变量,指针变量本身占用4个字节的大小。
        }
      }
      else
      {
        start = index;
        counter = 0;
      }
    }
  }
return NULL;

}

 
void k_free(void * p)
{
  __IO uint16_t index = 0;
  uint16_t counter = 0, start = 0;
  /* Handle NULL pointers */
  if (p == NULL)
    return;

  /* Find start Index */
  start = ((((uint32_t)p - sizeof(uint32_t)) - memory_pool.mallocBase) >> MSHIFT_BIT);
  /* Retrieve segment size */
  counter = memory_pool.size[start];
  /* Set size to zero */
  memory_pool.size[start] = 0;
  /* Deallocate memory region */
  for (index = 0; index < counter; index++)
  {
    memory_pool.PageTable[start + index] = 0;
  }

  return;
}
 

 

 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值