FreeRTOS heap_5的realloc编写

在freertos中没有对realloc重分配内存函数进行支持,在此记录自己的实现方法。

void* pvPortRealloc(void* pv, size_t xWantedSize)
{
    void* pvReturn = NULL;
    if (xWantedSize == 0)
    {
        vPortFree(pv);
    }
    else if(xWantedSize > 0)
    {
        if (pv == NULL)
        {
            return pvPortMalloc(xWantedSize);
        }
        else
        {
            size_t xAdditionalRequiredSize;
            uint8_t* puc = (uint8_t*)pv;
            BlockLink_t* pxLink;

            size_t xExpansionSize; //需要扩充的大小
            size_t xRealSize; //真实大小

            puc -= xHeapStructSize;
            pxLink = (void*)puc;//获取当前块信息
            xAdditionalRequiredSize = xHeapStructSize + portBYTE_ALIGNMENT - (xWantedSize & portBYTE_ALIGNMENT_MASK);

            if (heapADD_WILL_OVERFLOW(xWantedSize, xAdditionalRequiredSize) == 0)
            {
                xWantedSize += xAdditionalRequiredSize;
            }
            else
            {
                xWantedSize = 0;
            }
            if (heapBLOCK_SIZE_IS_VALID(xWantedSize) != 0)
            {
                xRealSize = pxLink->xBlockSize & ~heapBLOCK_ALLOCATED_BITMASK;//获取到真实大小
                vTaskSuspendAll();
                if (xWantedSize == xRealSize)//在分配内存时会分配4字节对齐的空间,所以可能存在不用扩充的情况
                {
                    pvReturn = pv;
                }
                else if(xWantedSize > xRealSize)//扩充内存
                {
                    xExpansionSize = xWantedSize - xRealSize;//计算需要扩充大小
                   //如果堆剩余大小大于扩展大小那么检查前后连续的空闲堆
                    if (xExpansionSize <= xFreeBytesRemaining)
                    {
                        BlockLink_t* pxPreviousBlock, * pxIterator, * pxNewBlockLink = NULL;
                        BlockLink_t* pxBlock = NULL, * pxPreviousBlock1 = NULL;
                        for (pxPreviousBlock = pxIterator = &xStart; pxIterator->pxNextFreeBlock != NULL && pxIterator->pxNextFreeBlock < pxLink; pxIterator = pxIterator->pxNextFreeBlock)
                        {
                            pxPreviousBlock = pxIterator;
                            if (pxBlock == NULL && pxIterator->pxNextFreeBlock ->xBlockSize >= xWantedSize)
                            {
                            	pxPreviousBlock1 = pxIterator;
                                pxBlock = pxIterator->pxNextFreeBlock;
                            }
                        }
                        //检查后面一个空闲块是否满足扩展条件
                        if ((BlockLink_t*)(puc + xRealSize) == pxIterator->pxNextFreeBlock && pxIterator->pxNextFreeBlock->xBlockSize >= xExpansionSize)
                        {
                            pvReturn = pv;
                            //  如果后面一个块的空间在分配后小于管理块大小,直接从链表中删除
                            if (pxIterator->pxNextFreeBlock->xBlockSize - xExpansionSize < xHeapStructSize)
                            {
                                pxNewBlockLink = pxLink;
                                pxNewBlockLink->xBlockSize = xRealSize + pxIterator->pxNextFreeBlock->xBlockSize;
                                pxIterator->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
                            }
                            else//  如果后面一个块的空间在分配后大于管理块大小,创建新块
                            {
                                pxNewBlockLink = (BlockLink_t*)(puc + xWantedSize);
                                BlockLink_t* temp = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
                                pxNewBlockLink->xBlockSize = pxIterator->pxNextFreeBlock->xBlockSize - xExpansionSize;//设置新块大小
                                pxNewBlockLink->pxNextFreeBlock = temp;
                                pxIterator->pxNextFreeBlock = pxNewBlockLink;
                                pxNewBlockLink = pxLink;
                                pxNewBlockLink->xBlockSize = xWantedSize;
                            }
                            xFreeBytesRemaining -= pxNewBlockLink->xBlockSize - xRealSize;
                        }
                        else if ((BlockLink_t*)((uint8_t*)pxIterator + pxIterator->xBlockSize) == pxLink && pxIterator->xBlockSize >= xExpansionSize)//检查前面一个空闲块是否满足条件
                        {
                            puc -= xExpansionSize;
                            if ((BlockLink_t*)puc == pxIterator)//要扩展的大小等于前面的块大小,合并两个块
                            {
                                pxPreviousBlock->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
                                pxNewBlockLink = pxIterator;
                                pxNewBlockLink->xBlockSize = xWantedSize;
                            }
                            else if (pxIterator->xBlockSize - xExpansionSize >= xHeapStructSize)//扩充后前面的块的大小足够创建新块,创建块
                            {
                                pxIterator->xBlockSize -= xExpansionSize;
                                pxNewBlockLink = (BlockLink_t*)puc;
                                pxNewBlockLink->xBlockSize = xWantedSize;
                            }
                            else//扩展后前面的块剩余大小不足创建新块,合并块
                            {
                                pxPreviousBlock->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
                                pxNewBlockLink = pxIterator;
                                pxNewBlockLink->xBlockSize += xRealSize;
                            }
                            pvReturn = (uint8_t*)pxNewBlockLink + xHeapStructSize;
                            xFreeBytesRemaining -= pxNewBlockLink->xBlockSize - xRealSize;
                            memcpy(pvReturn, pv, xRealSize - xHeapStructSize);
                        }
                        if (pvReturn == NULL)
                        {
                            // 判断上一次遍历时是否找到符合的块,如果没有找到接着上一次中断的地方找
                            if (pxBlock == NULL && xWantedSize < xFreeBytesRemaining && pxPreviousBlock != NULL)
                            {
                                pxBlock = pxPreviousBlock->pxNextFreeBlock;
                                while ((pxBlock->xBlockSize < xWantedSize) && (pxBlock->pxNextFreeBlock != NULL))
                                {
                                    pxPreviousBlock = pxBlock;
                                    pxBlock = pxBlock->pxNextFreeBlock;
                                }
                            }
                            else
                            {
                            	pxPreviousBlock = pxPreviousBlock1;
							}
                            if (pxBlock != NULL)
                            {
                                pvReturn = (void*)((uint8_t*)pxBlock + xHeapStructSize);

                                //如果块剩余的内存大于等于管理结构体大小就创建新块
                                if (pxBlock->xBlockSize - xWantedSize >= xHeapStructSize)
                                {
                                    pxNewBlockLink = (BlockLink_t*)((uint8_t*)pxBlock + xWantedSize);
                                    pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
                                    pxNewBlockLink->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
                                    pxBlock->xBlockSize = xWantedSize;
                                }
                                else//如果本块剩余的空间小于管理结构体的大小
                                {
                                    pxNewBlockLink = pxBlock->pxNextFreeBlock;
                                }
                                pxPreviousBlock->pxNextFreeBlock = pxNewBlockLink;
                                xFreeBytesRemaining -= pxBlock->xBlockSize;
                                pxNewBlockLink = pxBlock;
                                memcpy(pvReturn, pv, xRealSize - xHeapStructSize);
                                vPortFree(pv);
                            }
                        }
                        if (pxNewBlockLink != NULL)
                        {
                            pxNewBlockLink->pxNextFreeBlock = NULL;
                            //memset((uint8_t*)pvReturn + xRealSize - xHeapStructSize, 0, pxNewBlockLink->xBlockSize - xRealSize);
                            heapALLOCATE_BLOCK(pxNewBlockLink);
                            xNumberOfSuccessfulAllocations++;
                            if (xFreeBytesRemaining < xMinimumEverFreeBytesRemaining)
                            {
                                xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
                            }
                        }
                    }
                   /* else
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }*/
                }
                else if (xWantedSize < xRealSize)//减小内存,一般来说一定会成功分配
                {
                    xExpansionSize = xRealSize - xWantedSize;//计算需要缩减大小
                    pvReturn = pv;
                    if (xExpansionSize > xHeapStructSize)//释放的内存可以创建管理块
                    {
                        BlockLink_t* pxIterator, * pxNewBlockLink = NULL;
                        for (pxIterator = &xStart; pxIterator->pxNextFreeBlock != NULL && pxIterator->pxNextFreeBlock < pxLink; pxIterator = pxIterator->pxNextFreeBlock)
                        {
                            //if (pxBlock == NULL && pxIterator->xBlockSize == xWantedSize)//有相等的也记录下来,防止内存碎片
                            //{
                            //    pxBlock = pxIterator;
                            //}
                        }
                        //如果前面的块空闲合并过去,防止内存碎片
                        // if()

                        //直接截断后面部分,最简单的方法,但可能会导致内存碎片过多
                        pxNewBlockLink = (BlockLink_t*)((uint8_t*)pxLink + xWantedSize);
                        if ((BlockLink_t*)((uint8_t*)pxNewBlockLink + xExpansionSize) == pxIterator->pxNextFreeBlock && pxIterator->pxNextFreeBlock != pxEnd)
                        {
                            pxNewBlockLink->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
                            pxNewBlockLink->xBlockSize = xExpansionSize + pxIterator->pxNextFreeBlock->xBlockSize;
                        }
                        else
                        {
                            pxNewBlockLink->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
                            pxNewBlockLink->xBlockSize = xExpansionSize;
                        }
                        pxIterator->pxNextFreeBlock = pxNewBlockLink;
                        pxLink->xBlockSize = xWantedSize;
                        heapALLOCATE_BLOCK(pxLink);
                        xFreeBytesRemaining += xExpansionSize;
                    }
                }
                xTaskResumeAll();
            }
           /* else
            {
                mtCOVERAGE_TEST_MARKER();
            }*/
        }
    }
    return pvReturn;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS是一个面向嵌入式系统的实时操作系统内核,而FreeRTOS10_xilinx是一个基于FreeRTOS的特定版本,专门为Xilinx FPGA(Field-Programmable Gate Array)平台开发而成。 FreeRTOS10_xilinx基于FreeRTOS的源代码进行了修改和扩展,使其能够更好地适配Xilinx FPGA平台的特性和需求。它提供了一组针对Xilinx FPGA设计的实时调度、内存管理和任务通信的API接口,以及一些针对FPGA平台的特定功能和优化。 FreeRTOS10_xilinx的主要特点包括: 1. 多任务调度:可以同时运行多个任务,并可根据优先级和调度策略进行合理的任务调度。 2. 内存管理:提供了一套内存管理机制,包括堆栈管理和动态内存分配,能够有效地管理FPGA平台上的有限资源。 3. 任务通信:提供了多种任务间通信的机制,如消息队列、信号量和事件等,实现不同任务之间的数据共享和同步。 4. 中断处理:支持中断处理机制,能够正确地处理硬件中断,并与任务调度进行协同工作。 5. 硬件支持:针对Xilinx FPGA平台的特性进行了优化,包括支持硬件加速和外设控制等功能。 通过使用FreeRTOS10_xilinx,开发人员可以在Xilinx FPGA平台上快速构建稳定、高效的嵌入式系统。它具有良好的可移植性和可扩展性,可以方便地在不同的Xilinx FPGA平台上进行移植和定制,满足不同应用场景的需求。它还提供了丰富的开发工具和示例代码,帮助开发人员快速入手和开发应用程序。 总之,FreeRTOS10_xilinx是一种专为Xilinx FPGA平台定制的实时操作系统内核,可以提供可靠的任务调度、内存管理、任务通信和硬件支持等功能,为开发人员提供便捷、高效的嵌入式系统开发平台。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值