-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathheap.cpp
More file actions
105 lines (83 loc) · 2.46 KB
/
heap.cpp
File metadata and controls
105 lines (83 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2020 Embedded Artistry LLC
// SPDX-License-Identifier: MIT
#include "heap.hpp"
#include <FreeRTOS.h>
#include <cstdint>
#include <cstdlib>
#include <task.h>
/**
* NOTE: This FreeRTOS malloc implementation requires heap_5.c
*
* Please define the correct heap_region for your project.
*/
#pragma mark - Definitions
/**
* Your application can define this macro to increase the number of heap regions
*/
#ifndef FREERTOS_HEAP_REGION_CNT
#define FREERTOS_HEAP_REGION_CNT 2
#endif
#pragma mark - Private Functions -
static int cmp_heap(const void* a, const void* b) noexcept
{
const HeapRegion_t* ua = reinterpret_cast<const HeapRegion_t*>(a);
const HeapRegion_t* ub = reinterpret_cast<const HeapRegion_t*>(b);
return ((ua->pucStartAddress < ub->pucStartAddress)
? -1
: ((ua->pucStartAddress != ub->pucStartAddress)));
}
#pragma mark - Declarations -
/// Maximum number of heap regions that can be specified
static const uint8_t heap_region_max = FREERTOS_HEAP_REGION_CNT;
/// Current number of allocated heap regions
static volatile uint8_t heap_region_cnt = 0;
/**
* FreeRTOS internal memory pool stucture when using heap_5.c
*
* The block with the lowest starting address should appear first in the array
*
* An additional block is allocated to serve as a NULL terminator
*/
static HeapRegion_t heap_regions[FREERTOS_HEAP_REGION_CNT + 1];
#pragma mark - Class Implementations -
void os::freertos::Heap::addBlock(void* addr, size_t size) noexcept
{
assert((heap_region_cnt < heap_region_max) && "Too many heap regions!");
// Increment the count early to claim a spot in case of multi-threads
uint8_t cnt = heap_region_cnt++;
if(cnt < heap_region_max)
{
// We have space - add it to the table
heap_regions[cnt].pucStartAddress = static_cast<uint8_t*>(addr);
heap_regions[cnt].xSizeInBytes = size;
}
else
{
// Decrement the count if we don't have space
heap_region_cnt--;
}
}
void os::freertos::Heap::init() noexcept
{
assert((heap_region_cnt > 0));
if(heap_region_cnt > 0)
{
// Sort the heap regions so addresses are in the correct order
qsort(heap_regions, heap_region_cnt, sizeof(HeapRegion_t), cmp_heap);
// Pass the array into vPortDefineHeapRegions() to enable malloc()
vPortDefineHeapRegions(heap_regions);
}
}
void* os::freertos::Heap::alloc(size_t size) noexcept
{
void* ptr = nullptr;
if(size > 0)
{
ptr = pvPortMalloc(size);
}
return ptr;
}
void os::freertos::Heap::free(void* addr) noexcept
{
vPortFree(addr);
}