女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于FreeRTOS的STM32F103系統(tǒng)—Heap_4內(nèi)存管理機(jī)制介紹

冬至子 ? 來源:月月望歸鳥 ? 作者:K.Fire ? 2023-11-10 11:08 ? 次閱讀

1

Heap_4內(nèi)存管理機(jī)制詳解

首先介紹一下用到的重要的結(jié)構(gòu)體-標(biāo)記內(nèi)存塊,在每個(gè)存放數(shù)據(jù)的內(nèi)存塊前都會(huì)有一個(gè)這樣的標(biāo)記結(jié)構(gòu)體。

typedef struct A_BLOCK_LINK
{
  struct A_BLOCK_LINK *pxNextFreeBlock;  /*< < The next free block in the list. */
  size_t xBlockSize;            /*< < The size of the free block. */
} BlockLink_t;

里面有兩個(gè)變量,pxNextFreeBlock指向下一個(gè)內(nèi)存塊,xBlockSize用來表示它所標(biāo)記的內(nèi)存塊大小。

還有一些全局變量,都寫了注釋很好理解,就不多解釋。

//內(nèi)存堆大小,并字節(jié)對齊
static const size_t xHeapStructSize  = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );

/* Create a couple of list links to mark the start and end of the list. */
static BlockLink_t xStart, *pxEnd = NULL;      //內(nèi)存堆頭尾

/* Keeps track of the number of free bytes remaining, but says nothing about
fragmentation. */
static size_t xFreeBytesRemaining = 0U;        //內(nèi)存堆剩余大小
static size_t xMinimumEverFreeBytesRemaining = 0U;  //歷史剩余大小的最小值

/* Gets set to the top bit of an size_t type.  When this bit in the xBlockSize
member of an BlockLink_t structure is set then the block belongs to the
application.  When the bit is free the block is still part of the free heap
space. */
static size_t xBlockAllocatedBit = 0;      //1這個(gè)塊被申請;0這個(gè)塊空閑

2

內(nèi)存堆初始化

首先定義一些臨時(shí)變量

BlockLink_t *pxFirstFreeBlock;                  //整個(gè)空閑內(nèi)存塊之前的標(biāo)記結(jié)構(gòu)體
uint8_t *pucAlignedHeap;                    //字節(jié)對齊后的起始地址
size_t uxAddress;                        //相當(dāng)于臨時(shí)變量
size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;          //拋棄不可用內(nèi)存塊后總的大小

經(jīng)過一系列的操作,使初始化后,空閑內(nèi)存表的起始地址為字節(jié)對齊,這里和heap_2不同的地方是,使用了臨時(shí)變量uxAddress存儲(chǔ)中間計(jì)算出來的一些地址,這里uxAddress存儲(chǔ)的是字節(jié)對齊后的初始地址,然后賦值給pucAlignedHeap變量中。

/* Ensure the heap starts on a correctly aligned boundary. */
  /*確保字節(jié)對齊后的起始地址正確*/
  uxAddress = ( size_t ) ucHeap;                //獲得內(nèi)存堆的大小放到uxAddress中

  if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )      //如果內(nèi)存堆大小不為0且不在掩模中
  {
    uxAddress += ( portBYTE_ALIGNMENT - 1 );        //portBYTE_ALIGNMENT = 7
    uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );  
    xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;    //拋棄不可用內(nèi)存塊后總的大小
  }

  pucAlignedHeap = ( uint8_t * ) uxAddress;          //字節(jié)對齊后的起始地址

這部分代碼用來初始化空閑內(nèi)存表的頭和尾,使頭的下一個(gè)內(nèi)存塊指向字節(jié)對齊后的首地址,大小初始化為0;這里的uxAddress變量經(jīng)過一系列操作以及變成了內(nèi)存塊的末地址,然后使尾的首地址指向末地址(pxEnd=(void *)uxAddress),大小初始化為0,尾的下一個(gè)內(nèi)存塊為NULL。

/*初始化鏈表頭和尾*/
  xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;      //下一個(gè)頭指向字節(jié)對齊后的起始地址
  xStart.xBlockSize = ( size_t ) 0;              //大小初始化為0              

  /* pxEnd is used to mark the end of the list of free blocks and is inserted
  at the end of the heap space. */
  uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;  //這里的uxAddress已經(jīng)變成了末尾的地址
  uxAddress -= xHeapStructSize;                //減去一個(gè)標(biāo)志結(jié)構(gòu)體的大小
  uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );    //字節(jié)對齊
  pxEnd = ( void * ) uxAddress;                //這里的uxAddress已經(jīng)變成了內(nèi)存堆尾-一個(gè)標(biāo)志結(jié)構(gòu)體然后字節(jié)對齊后的地址
  pxEnd- >xBlockSize = 0;                    //末尾的內(nèi)存塊大小初始化為0
  pxEnd- >pxNextFreeBlock = NULL;                //下一個(gè)指向NULL

在申請內(nèi)存的最開始,把整個(gè)內(nèi)存堆都看成一個(gè)整體,作為一個(gè)大內(nèi)存塊,這個(gè)內(nèi)存塊之前也需要有一個(gè)標(biāo)記結(jié)構(gòu)體,也就是pxFirstFreeBlock結(jié)構(gòu)體,這里對這個(gè)結(jié)構(gòu)體進(jìn)行初始化,它的首地址就是字節(jié)對齊后的地址,大小是尾地址uxAddess-內(nèi)存塊字節(jié)對齊后的首地址,下一個(gè)內(nèi)存塊指向pxEnd。

/*開始的時(shí)候?qū)?nèi)存堆整個(gè)可用空間看成一個(gè)空閑內(nèi)存塊*/
  pxFirstFreeBlock = ( void * ) pucAlignedHeap;              //空閑內(nèi)存塊之前的標(biāo)記結(jié)構(gòu)體地址    
  pxFirstFreeBlock- >xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;  //標(biāo)記結(jié)構(gòu)體記錄內(nèi)存塊大小為末地址-初地址
  pxFirstFreeBlock- >pxNextFreeBlock = pxEnd;                //下一個(gè)空閑內(nèi)存塊為末尾內(nèi)存塊指針

最后這里就是更新一下全局變量,并標(biāo)記一下塊被占用。

/*只有一個(gè)內(nèi)存塊,而且這個(gè)內(nèi)存塊擁有內(nèi)存堆的整個(gè)可用空間*/
  xMinimumEverFreeBytesRemaining = pxFirstFreeBlock- >xBlockSize;      //記錄最小的空閑內(nèi)存塊大小
  xFreeBytesRemaining = pxFirstFreeBlock- >xBlockSize;            //記錄歷史最小的空閑內(nèi)存塊大小

  /* Work out the position of the top bit in a size_t variable. */
  xBlockAllocatedBit = ( ( size_t ) 1 ) < < ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );    //初始化靜態(tài)變量,初始化完成以后此變量值為 0X80000000
  //在 heap_4 中其最高位表示此內(nèi)存塊是否被使用,如果為 1 的話就表示被使用了,所以在 heap_4 中一個(gè)內(nèi)存塊最大只能為 0x7FFFFFFF

借用一下原子手冊的圖解:

圖片

3

插入空閑內(nèi)存表函數(shù)

先定義兩個(gè)用到的局部變量,pxIterator相當(dāng)于C++中容器的迭代器,puc就是個(gè)臨時(shí)變量。

BlockLink_t *pxIterator;    //相當(dāng)于查找合適位置的迭代器
uint8_t *puc;          //相當(dāng)于臨時(shí)變量

這里就是使用迭代器一次次循環(huán),知道找到空閑內(nèi)存表中滿足內(nèi)存要求(pxIterator->pxNextFreeBlock < pxBlockToInsert)的內(nèi)存塊地址。

//遍歷空閑內(nèi)存塊鏈表,找出內(nèi)存塊插入點(diǎn),內(nèi)存塊按照地址從低到高連接在一起(迭代器思想)
  for( pxIterator = &xStart; pxIterator- >pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator- >pxNextFreeBlock )
  {
    /* Nothing to do here, just iterate to the right position. */
  }

這里是判斷要插入的這塊內(nèi)存和前一塊內(nèi)存是否相鄰,如果相鄰就合并成一塊,判斷是否相鄰的條件是puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert,插入點(diǎn)地址+這塊內(nèi)存的大小==要插入塊首地址;即上一塊末地址==要插入塊起始地址

//插入內(nèi)存塊,如果要插入的內(nèi)存塊可以和前一個(gè)內(nèi)存塊合并的話就
  //合并兩個(gè)內(nèi)存塊
  puc = ( uint8_t * ) pxIterator;                //找到的合適的插入點(diǎn)的地址
  if( ( puc + pxIterator- >xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) //插入點(diǎn)地址+這塊內(nèi)存的大小==要插入塊首地址;即上一塊末地址==要插入塊起始地址
  {
    pxIterator- >xBlockSize += pxBlockToInsert- >xBlockSize;  //大小合并
    pxBlockToInsert = pxIterator;              //合并后內(nèi)存首地址不變
  }
  else
  {
    mtCOVERAGE_TEST_MARKER();
  }

再借用一下原子的圖:

圖片

這一部分代碼是檢查要插入的內(nèi)存塊是否和后一塊內(nèi)存相鄰,如果相鄰就合并起來,判斷條件是puc + pxBlockToInsert->xBlockSize == ( uint8_t * ) ( pxIterator->pxNextFreeBlock ),要插入塊首地址+這塊內(nèi)存的大小==下一塊首地址;即要插入塊末地址==下一塊起始地址

//檢查是否可以和后面的內(nèi)存塊合并,可以的話就合并
  puc = ( uint8_t * ) pxBlockToInsert;      //要插入的內(nèi)存塊的首地址
  if( ( puc + pxBlockToInsert- >xBlockSize ) == ( uint8_t * ) pxIterator- >pxNextFreeBlock )  要插入塊首地址+這塊內(nèi)存的大小==下一塊首地址;即要插入塊末地址==下一塊起始地址
  {
    if( pxIterator- >pxNextFreeBlock != pxEnd )    //下一塊不是表尾
    {
      /* Form one big block from the two blocks. */
      //將兩個(gè)內(nèi)存塊組合成一個(gè)大的內(nèi)存塊時(shí)
      pxBlockToInsert- >xBlockSize += pxIterator- >pxNextFreeBlock- >xBlockSize;      內(nèi)存塊大小合并
      pxBlockToInsert- >pxNextFreeBlock = pxIterator- >pxNextFreeBlock- >pxNextFreeBlock;//合并起來之后下下快變成了下一塊
    }
    else
    {
      pxBlockToInsert- >pxNextFreeBlock = pxEnd;  //要插入的變成表尾
    }
  }
  else
  {
    pxBlockToInsert- >pxNextFreeBlock = pxIterator- >pxNextFreeBlock;
  }

最后借用一下原子的圖:

圖片

如果和前后都不相鄰,則使用最簡單的插入方法:

//在內(nèi)存塊插入的過程中沒有進(jìn)行過一次內(nèi)存合并,使用最簡單的插入方法
  if( pxIterator != pxBlockToInsert )
  {
    pxIterator- >pxNextFreeBlock = pxBlockToInsert;
  }
  else
  {
    mtCOVERAGE_TEST_MARKER();
  }

4

內(nèi)存申請函數(shù)

先初始化一下內(nèi)存堆:

//第一次調(diào)用,初始化內(nèi)存堆
    if( pxEnd == NULL )
    {
      prvHeapInit();
    }
    else
    {
      mtCOVERAGE_TEST_MARKER();
    }

判斷一下想要插入數(shù)據(jù)的內(nèi)存塊是否被使用,就是和xBlockAllocateBit變量做一次與運(yùn)算,如果結(jié)果不是1,則說明沒被使用;在確保要插入的大小大于0之后,需要附加上標(biāo)記結(jié)構(gòu)體的大小(8字節(jié))后,再進(jìn)行字節(jié)對齊。

//需要申請的內(nèi)存塊大小的最高位不能為 1,因?yàn)樽罡呶挥脕肀硎緝?nèi)存塊有沒有被使用
    if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
    {
      /* The wanted size is increased so it can contain a BlockLink_t
      structure in addition to the requested amount of bytes. */
      if( xWantedSize > 0 )
      {
        xWantedSize += xHeapStructSize;    //要申請的大小加上標(biāo)記結(jié)構(gòu)體的大小
        /* Ensure that blocks are always aligned to the required number
        of bytes. */
        if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
        {
          /* Byte alignment required. */
          /*要插入的內(nèi)存塊字節(jié)對齊*/
          xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
          configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
        }
        else
        {
          mtCOVERAGE_TEST_MARKER();
        }
      }
      else
      {
        mtCOVERAGE_TEST_MARKER();
      }

當(dāng)我們想要插入的內(nèi)存塊小于剩余內(nèi)存大小時(shí),就開始查找滿足要求的內(nèi)存塊。

if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
      {
        /* Traverse the list from the start  (lowest address) block until
        one  of adequate size is found. */
        //從 xStart(內(nèi)存塊最小)開始,查找大小滿足所需要內(nèi)存的內(nèi)存塊
        pxPreviousBlock = &xStart;        //上一個(gè)內(nèi)存塊
        pxBlock = xStart.pxNextFreeBlock;    //滿足要求的內(nèi)存塊(下一塊)
        while( ( pxBlock- >xBlockSize < xWantedSize ) && ( pxBlock- >pxNextFreeBlock != NULL ) )
        {
          pxPreviousBlock = pxBlock;
          pxBlock = pxBlock- >pxNextFreeBlock;
        }

如果找到的是pxEnd表示沒有內(nèi)存可以分配,否則就將內(nèi)存首地址保存在 pvReturn 中,函數(shù)返回的時(shí)候返回此值,然后將這塊內(nèi)存從空閑內(nèi)存表中刪除

//如果找到的內(nèi)存塊是 pxEnd 的話就表示沒有內(nèi)存可以分配
        if( pxBlock != pxEnd )
        {
          /* Return the memory space pointed to - jumping over the
          BlockLink_t structure at its start. */
          //找到內(nèi)存塊以后就將內(nèi)存首地址保存在 pvReturn 中,函數(shù)返回的時(shí)候返回此值
          //找到的內(nèi)存塊讓出一個(gè)標(biāo)志結(jié)構(gòu)體的大小
          pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock- >pxNextFreeBlock ) + xHeapStructSize );

          /* This block is being returned for use so must be taken out
          of the list of free blocks. */
          //將申請到的內(nèi)存塊從空閑內(nèi)存鏈表中移除
          pxPreviousBlock- >pxNextFreeBlock = pxBlock- >pxNextFreeBlock;  //把滿足要求的pxBlock塊的下一塊拼接到上一塊

申請的內(nèi)存大小小于空閑的一大塊內(nèi)存的大小,則將其分割,剩下的留著,相當(dāng)于給空閑內(nèi)存塊的首地址做一個(gè)地址偏移:新的空閑內(nèi)存塊=滿足要求的內(nèi)存塊首地址+需要的內(nèi)存塊首地址,然后更新新的空閑內(nèi)存塊的大小,并將其插入到空閑內(nèi)存表。

//如果申請到的內(nèi)存塊大于所需的內(nèi)存,就將其分成兩塊
          if( ( pxBlock- >xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
          {
            /* This block is to be split into two.  Create a new
            block following the number of bytes requested. The void
            cast is used to prevent byte alignment warnings from the
            compiler. */
            pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );  //新的空閑內(nèi)存塊=滿足要求的內(nèi)存塊首地址+需要的內(nèi)存塊首地址 
            configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );

            /* Calculate the sizes of two blocks split from the
            single block. */
            pxNewBlockLink- >xBlockSize = pxBlock- >xBlockSize - xWantedSize;  //更新新的空閑內(nèi)存塊的大小
            pxBlock- >xBlockSize = xWantedSize;                //滿足要求的內(nèi)存塊的大小

            /* Insert the new block into the list of free blocks. */
            prvInsertBlockIntoFreeList( pxNewBlockLink );          //插入新的空閑內(nèi)存塊
          }
          else
          {
            mtCOVERAGE_TEST_MARKER();
          }

最后就是更新一下全局變量

xFreeBytesRemaining -= pxBlock- >xBlockSize;              //更新最小內(nèi)存塊大小

          if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )      //更新歷史最小內(nèi)存塊大小
          {
            xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
          }
          else
          {
            mtCOVERAGE_TEST_MARKER();
          }

          /* The block is being returned - it is allocated and owned
          by the application and has no "next" block. */
          //內(nèi)存塊申請成功,標(biāo)記此內(nèi)存塊已經(jīng)被使用
          pxBlock- >xBlockSize |= xBlockAllocatedBit;  //將pxBlock最高位置1
          pxBlock- >pxNextFreeBlock = NULL;      //滿足要求的內(nèi)存塊下一塊指向NULL

后面還可以配置內(nèi)存申請失敗時(shí)的鉤子函數(shù),需要把configUSE_MALLOC_FAILED_HOOK宏打開

#if( configUSE_MALLOC_FAILED_HOOK == 1 )
  {
    if( pvReturn == NULL )
    {
      extern void vApplicationMallocFailedHook( void );
      vApplicationMallocFailedHook();
    }
    else
    {
      mtCOVERAGE_TEST_MARKER();
    }
  }
  #endif

5

內(nèi)存釋放函數(shù)

先定義一些用到的局部變量:

uint8_t *puc = ( uint8_t * ) pv;  //傳入要釋放內(nèi)存的地址
BlockLink_t *pxLink;        //包含了標(biāo)志結(jié)構(gòu)體后的首地址

傳入的數(shù)據(jù)地址沒包含標(biāo)志結(jié)構(gòu)體,需要先做減法,進(jìn)行地址移位,然后將包含了標(biāo)志結(jié)構(gòu)體的首地址保存在pxLink中

puc -= xHeapStructSize;          //釋放的部分包括上標(biāo)志結(jié)構(gòu)體大小
/* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc;        //防止編譯器報(bào)錯(cuò)

如果要釋放的內(nèi)存真的被使用,就開始釋放操作,先把首位變0,表示變成空閑,然后更新空閑內(nèi)存大小,將這塊內(nèi)存插入回空閑內(nèi)存表中,要注意:釋放和申請內(nèi)存,并不是把這塊內(nèi)存從一個(gè)鏈表中拿出來了,只是做了一些標(biāo)記,讓程序知道這部分被占用,有數(shù)據(jù),在釋放內(nèi)存之前我們將數(shù)據(jù)刪除,然后把標(biāo)志位改為空閑狀態(tài)就行,這就是釋放的本質(zhì)。

if( ( pxLink- >xBlockSize & xBlockAllocatedBit ) != 0 )    //判斷是否真被使用
    {
      if( pxLink- >pxNextFreeBlock == NULL )
      {
        /* The block is being returned to the heap - it is no longer
        allocated. */
        pxLink- >xBlockSize &= ~xBlockAllocatedBit;      //首位變0,表示未被使用

        vTaskSuspendAll();
        {
          /* Add this block to the list of free blocks. */
          /*將內(nèi)存塊插到空閑內(nèi)存鏈表中*/
          xFreeBytesRemaining += pxLink- >xBlockSize;          //更新最小內(nèi)存塊大小
          traceFREE( pv, pxLink- >xBlockSize );            
          prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );  //將被釋放的內(nèi)存塊插入空閑內(nèi)存鏈表中
        }
        ( void ) xTaskResumeAll();
      }
      else
      {
        mtCOVERAGE_TEST_MARKER();
      }
    }
    else
    {
      mtCOVERAGE_TEST_MARKER();
    }

6

總結(jié)

其他的函數(shù)主要就是直接返回我們之前更新的全局變量,終于把基礎(chǔ)知識(shí)都鋪墊完了,下面結(jié)合具體項(xiàng)目程序談?wù)勗趺磧?yōu)化了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    488

    瀏覽量

    63723
  • STM32F103
    +關(guān)注

    關(guān)注

    33

    文章

    481

    瀏覽量

    65028
  • 內(nèi)存管理
    +關(guān)注

    關(guān)注

    0

    文章

    168

    瀏覽量

    14472
  • 迭代器
    +關(guān)注

    關(guān)注

    0

    文章

    45

    瀏覽量

    4436
收藏 人收藏

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    第28章 FreeRTOS動(dòng)態(tài)內(nèi)存管理

    教程配套的例子含Cortex-M3內(nèi)核的STM32F103和Cortex-M4內(nèi)核的STM32F407以及F429。28.1 動(dòng)態(tài)內(nèi)存
    發(fā)表于 09-11 07:15

    FreeRTOS vPortFree 內(nèi)存釋放異常怎么辦

    函數(shù)因?yàn)樾枰褂玫揭粋€(gè) 4k 的buf做數(shù)據(jù)暫存;為了使用方便引用了FreeRTOSheap_4 內(nèi)存管理方式;pvPortMallo
    發(fā)表于 07-13 10:36

    基于FreeRTOS內(nèi)存管理Heap_4.c的實(shí)現(xiàn)方法

    一下,哈哈。 既然是在FreeRTOS內(nèi)存管理Heap_4.c的基礎(chǔ)上稍稍修改的,那還是先介紹一下它的實(shí)現(xiàn)方法吧:以下為轉(zhuǎn)載內(nèi)容,原文鏈接:
    發(fā)表于 07-15 21:46

    linux內(nèi)存管理機(jī)制淺析

    本內(nèi)容介紹了arm linux內(nèi)存管理機(jī)制,詳細(xì)說明了linux內(nèi)核內(nèi)存管理,linux虛擬內(nèi)存
    發(fā)表于 12-19 14:09 ?73次下載
    linux<b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理機(jī)制</b>淺析

    基于STM32F103的振動(dòng)監(jiān)測系統(tǒng)設(shè)計(jì)

    基于STM32F103的振動(dòng)監(jiān)測系統(tǒng)設(shè)計(jì)。
    發(fā)表于 11-09 17:49 ?46次下載

    FreeRTOS代碼剖析之4內(nèi)存管理Heap

    FreeRTOS8.0.1內(nèi)存管理的最后一個(gè)堆模型Heap_4,貌似是在這一個(gè)版本才有的。所以找到的說明幾乎沒有。代碼的開頭注釋也只是簡單地說了一下實(shí)現(xiàn)了pvPortMalloc
    發(fā)表于 02-09 02:52 ?457次閱讀

    FreeRTOS代碼剖析之1:內(nèi)存管理Heap

    內(nèi)存管理是一個(gè)操作系統(tǒng)的重要組成部分之一,所有應(yīng)用程序都離不開操作系統(tǒng)內(nèi)存管理。因此,在剖析
    發(fā)表于 02-09 05:25 ?1103次閱讀
    <b class='flag-5'>FreeRTOS</b>代碼剖析之1:<b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理</b><b class='flag-5'>Heap</b>

    FreeRTOS代碼剖析之3:內(nèi)存管理Heap

    STM32F103中,FreeRTOS管理的堆就定義在啟動(dòng)文件startup_stm32f10x_xd.s中。 不過,就算是直接引用了標(biāo)準(zhǔn)
    發(fā)表于 02-09 05:30 ?520次閱讀

    STM32F103的振動(dòng)監(jiān)測系統(tǒng)設(shè)計(jì)

    STM32F103的振動(dòng)監(jiān)測系統(tǒng)設(shè)計(jì)
    發(fā)表于 09-28 14:45 ?49次下載
    <b class='flag-5'>STM32F103</b>的振動(dòng)監(jiān)測<b class='flag-5'>系統(tǒng)</b>設(shè)計(jì)

    STM32F103教程之STM32F103單片機(jī)的使用心得資料免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STM32F103教程之STM32F103單片機(jī)的使用心得資料免費(fèi)下載目前很火的設(shè)計(jì)STM32教程。
    發(fā)表于 09-26 08:00 ?256次下載

    嵌入式系統(tǒng)內(nèi)存管理機(jī)制詳解

    操作系統(tǒng)內(nèi)存管理功能用于向操作系統(tǒng)提供一致的地址映射功能和內(nèi)存頁面的申請、釋放操作。在嵌入式實(shí)時(shí)系統(tǒng)
    發(fā)表于 11-18 09:41 ?4694次閱讀

    STM32F103芯片資料介紹

    只是STM32F103芯片資料的簡單介紹,文章由(逆向開發(fā)技術(shù)網(wǎng))編輯整理。下次我們將具體介紹一下”STM32F103芯片解密方法”
    發(fā)表于 01-08 08:00 ?189次下載
    <b class='flag-5'>STM32F103</b>芯片資料<b class='flag-5'>介紹</b>

    淺析物理內(nèi)存與虛擬內(nèi)存的關(guān)系及其管理機(jī)制

    本文主要介紹內(nèi)存管理機(jī)制:物理內(nèi)存與虛擬內(nèi)存的關(guān)系,Linux內(nèi)存
    的頭像 發(fā)表于 04-12 09:55 ?5878次閱讀
    淺析物理<b class='flag-5'>內(nèi)存</b>與虛擬<b class='flag-5'>內(nèi)存</b>的關(guān)系及其<b class='flag-5'>管理機(jī)制</b>

    heap_4內(nèi)存分配方法介紹

    heap_4 內(nèi)存分配方法 heap_4 提供了一個(gè)最優(yōu)的匹配算法,不像 heap_2,heap_4 會(huì)將
    的頭像 發(fā)表于 07-30 10:42 ?1258次閱讀

    FreeRTOS heap_5內(nèi)存分配方法介紹

    heap_5 內(nèi)存分配方法 heap_5 使用了和 heap_4 相同的合并算法,內(nèi)存管理實(shí)現(xiàn)起
    的頭像 發(fā)表于 07-30 10:47 ?1324次閱讀