Prusa MINI Firmware overview
portable.h File Reference
#include "deprecated_definitions.h"
#include "portmacro.h"
#include "mpu_wrappers.h"

Go to the source code of this file.

Classes

struct  HeapRegion
 

Macros

#define portNUM_CONFIGURABLE_REGIONS   1
 

Typedefs

typedef struct HeapRegion HeapRegion_t
 

Functions

PRIVILEGED_FUNCTION StackType_tpxPortInitialiseStack (StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters)
 
PRIVILEGED_FUNCTION void vPortDefineHeapRegions (const HeapRegion_t *const pxHeapRegions)
 
PRIVILEGED_FUNCTION voidpvPortMalloc (size_t xSize)
 
PRIVILEGED_FUNCTION void vPortFree (void *pv)
 
PRIVILEGED_FUNCTION void vPortInitialiseBlocks (void)
 
PRIVILEGED_FUNCTION size_t xPortGetFreeHeapSize (void)
 
PRIVILEGED_FUNCTION size_t xPortGetMinimumEverFreeHeapSize (void)
 
PRIVILEGED_FUNCTION BaseType_t xPortStartScheduler (void)
 
PRIVILEGED_FUNCTION void vPortEndScheduler (void)
 

Macro Definition Documentation

◆ portNUM_CONFIGURABLE_REGIONS

#define portNUM_CONFIGURABLE_REGIONS   1

Typedef Documentation

◆ HeapRegion_t

typedef struct HeapRegion HeapRegion_t

Function Documentation

◆ pxPortInitialiseStack()

PRIVILEGED_FUNCTION StackType_t* pxPortInitialiseStack ( StackType_t pxTopOfStack,
TaskFunction_t  pxCode,
void pvParameters 
)
Here is the caller graph for this function:

◆ vPortDefineHeapRegions()

PRIVILEGED_FUNCTION void vPortDefineHeapRegions ( const HeapRegion_t *const  pxHeapRegions)

◆ pvPortMalloc()

PRIVILEGED_FUNCTION void* pvPortMalloc ( size_t  xSize)
156 {
157 BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
158 void *pvReturn = NULL;
159 
160  vTaskSuspendAll();
161  {
162  /* If this is the first call to malloc then the heap will require
163  initialisation to setup the list of free blocks. */
164  if( pxEnd == NULL )
165  {
166  prvHeapInit();
167  }
168  else
169  {
171  }
172 
173  /* Check the requested block size is not so large that the top bit is
174  set. The top bit of the block size member of the BlockLink_t structure
175  is used to determine who owns the block - the application or the
176  kernel, so it must be free. */
177  if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
178  {
179  /* The wanted size is increased so it can contain a BlockLink_t
180  structure in addition to the requested amount of bytes. */
181  if( xWantedSize > 0 )
182  {
183  xWantedSize += xHeapStructSize;
184 
185  /* Ensure that blocks are always aligned to the required number
186  of bytes. */
187  if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
188  {
189  /* Byte alignment required. */
190  xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
191  configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
192  }
193  else
194  {
196  }
197  }
198  else
199  {
201  }
202 
203  if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
204  {
205  /* Traverse the list from the start (lowest address) block until
206  one of adequate size is found. */
207  pxPreviousBlock = &xStart;
208  pxBlock = xStart.pxNextFreeBlock;
209  while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
210  {
211  pxPreviousBlock = pxBlock;
212  pxBlock = pxBlock->pxNextFreeBlock;
213  }
214 
215  /* If the end marker was reached then a block of adequate size
216  was not found. */
217  if( pxBlock != pxEnd )
218  {
219  /* Return the memory space pointed to - jumping over the
220  BlockLink_t structure at its start. */
221  pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
222 
223  /* This block is being returned for use so must be taken out
224  of the list of free blocks. */
225  pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
226 
227  /* If the block is larger than required it can be split into
228  two. */
229  if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
230  {
231  /* This block is to be split into two. Create a new
232  block following the number of bytes requested. The void
233  cast is used to prevent byte alignment warnings from the
234  compiler. */
235  pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
236  configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
237 
238  /* Calculate the sizes of two blocks split from the
239  single block. */
240  pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
241  pxBlock->xBlockSize = xWantedSize;
242 
243  /* Insert the new block into the list of free blocks. */
244  prvInsertBlockIntoFreeList( pxNewBlockLink );
245  }
246  else
247  {
249  }
250 
251  xFreeBytesRemaining -= pxBlock->xBlockSize;
252 
254  {
256  }
257  else
258  {
260  }
261 
262  /* The block is being returned - it is allocated and owned
263  by the application and has no "next" block. */
264  pxBlock->xBlockSize |= xBlockAllocatedBit;
265  pxBlock->pxNextFreeBlock = NULL;
266  }
267  else
268  {
270  }
271  }
272  else
273  {
275  }
276  }
277  else
278  {
280  }
281 
282  traceMALLOC( pvReturn, xWantedSize );
283  }
284  ( void ) xTaskResumeAll();
285 
286  #if( configUSE_MALLOC_FAILED_HOOK == 1 )
287  {
288  if( pvReturn == NULL )
289  {
290  extern void vApplicationMallocFailedHook( void );
291  vApplicationMallocFailedHook();
292  }
293  else
294  {
296  }
297  }
298  #endif
299 
300  configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
301  return pvReturn;
302 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ vPortFree()

PRIVILEGED_FUNCTION void vPortFree ( void pv)
306 {
307 uint8_t *puc = ( uint8_t * ) pv;
308 BlockLink_t *pxLink;
309 
310  if( pv != NULL )
311  {
312  /* The memory being freed will have an BlockLink_t structure immediately
313  before it. */
314  puc -= xHeapStructSize;
315 
316  /* This casting is to keep the compiler from issuing warnings. */
317  pxLink = ( void * ) puc;
318 
319  /* Check the block is actually allocated. */
320  configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
321  configASSERT( pxLink->pxNextFreeBlock == NULL );
322 
323  if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
324  {
325  if( pxLink->pxNextFreeBlock == NULL )
326  {
327  /* The block is being returned to the heap - it is no longer
328  allocated. */
329  pxLink->xBlockSize &= ~xBlockAllocatedBit;
330 
331  vTaskSuspendAll();
332  {
333  /* Add this block to the list of free blocks. */
334  xFreeBytesRemaining += pxLink->xBlockSize;
335  traceFREE( pv, pxLink->xBlockSize );
336  prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
337  }
338  ( void ) xTaskResumeAll();
339  }
340  else
341  {
343  }
344  }
345  else
346  {
348  }
349  }
350 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ vPortInitialiseBlocks()

PRIVILEGED_FUNCTION void vPortInitialiseBlocks ( void  )
366 {
367  /* This just exists to keep the linker quiet. */
368 }

◆ xPortGetFreeHeapSize()

PRIVILEGED_FUNCTION size_t xPortGetFreeHeapSize ( void  )
354 {
355  return xFreeBytesRemaining;
356 }

◆ xPortGetMinimumEverFreeHeapSize()

PRIVILEGED_FUNCTION size_t xPortGetMinimumEverFreeHeapSize ( void  )
360 {
362 }

◆ xPortStartScheduler()

PRIVILEGED_FUNCTION BaseType_t xPortStartScheduler ( void  )
313 {
314  /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
315  See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
317 
318  /* This port can be used on all revisions of the Cortex-M7 core other than
319  the r0p1 parts. r0p1 parts should use the port from the
320  /source/portable/GCC/ARM_CM7/r0p1 directory. */
323 
324  #if( configASSERT_DEFINED == 1 )
325  {
326  volatile uint32_t ulOriginalPriority;
327  volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
328  volatile uint8_t ucMaxPriorityValue;
329 
330  /* Determine the maximum priority from which ISR safe FreeRTOS API
331  functions can be called. ISR safe functions are those that end in
332  "FromISR". FreeRTOS maintains separate thread and ISR API functions to
333  ensure interrupt entry is as fast and simple as possible.
334 
335  Save the interrupt priority value that is about to be clobbered. */
336  ulOriginalPriority = *pucFirstUserPriorityRegister;
337 
338  /* Determine the number of priority bits available. First write to all
339  possible bits. */
340  *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
341 
342  /* Read the value back to see how many bits stuck. */
343  ucMaxPriorityValue = *pucFirstUserPriorityRegister;
344 
345  /* Use the same mask on the maximum system call priority. */
346  ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
347 
348  /* Calculate the maximum acceptable priority group value for the number
349  of bits read back. */
350  ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
351  while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
352  {
353  ulMaxPRIGROUPValue--;
354  ucMaxPriorityValue <<= ( uint8_t ) 0x01;
355  }
356 
357  /* Shift the priority group value back to its position within the AIRCR
358  register. */
359  ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
360  ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
361 
362  /* Restore the clobbered interrupt priority register to its original
363  value. */
364  *pucFirstUserPriorityRegister = ulOriginalPriority;
365  }
366  #endif /* conifgASSERT_DEFINED */
367 
368  /* Make PendSV and SysTick the lowest priority interrupts. */
371 
372  /* Start the timer that generates the tick ISR. Interrupts are disabled
373  here already. */
375 
376  /* Initialise the critical nesting count ready for the first task. */
377  uxCriticalNesting = 0;
378 
379  /* Ensure the VFP is enabled - it should be anyway. */
380  vPortEnableVFP();
381 
382  /* Lazy save always. */
384 
385  /* Start the first task. */
387 
388  /* Should never get here as the tasks will now be executing! Call the task
389  exit error function to prevent compiler warnings about a static function
390  not being called in the case that the application writer overrides this
391  functionality by defining configTASK_RETURN_ADDRESS. */
393 
394  /* Should not get here! */
395  return 0;
396 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ vPortEndScheduler()

PRIVILEGED_FUNCTION void vPortEndScheduler ( void  )
400 {
401  /* Not implemented in ports where there is nothing to return to.
402  Artificially force an assert. */
403  configASSERT( uxCriticalNesting == 1000UL );
404 }
Here is the caller graph for this function:
A_BLOCK_LINK::xBlockSize
size_t xBlockSize
Definition: heap_4.c:114
pxEnd
static BlockLink_t * pxEnd
Definition: heap_4.c:140
configASSERT
#define configASSERT(x)
Definition: FreeRTOSConfig.h:162
portCORTEX_M7_r0p0_ID
#define portCORTEX_M7_r0p0_ID
Definition: port.c:108
A_BLOCK_LINK
Definition: heap_4.c:111
heapMINIMUM_BLOCK_SIZE
#define heapMINIMUM_BLOCK_SIZE
Definition: heap_4.c:95
portPRIGROUP_SHIFT
#define portPRIGROUP_SHIFT
Definition: port.c:121
portCORTEX_M7_r0p1_ID
#define portCORTEX_M7_r0p1_ID
Definition: port.c:107
traceMALLOC
#define traceMALLOC(pvAddress, uiSize)
Definition: FreeRTOS.h:570
portNVIC_PENDSV_PRI
#define portNVIC_PENDSV_PRI
Definition: port.c:110
prvTaskExitError
static void prvTaskExitError(void)
Definition: port.c:259
NULL
#define NULL
Definition: usbd_def.h:53
portNVIC_SYSTICK_PRI
#define portNVIC_SYSTICK_PRI
Definition: port.c:111
portFPCCR
#define portFPCCR
Definition: port.c:127
xMinimumEverFreeBytesRemaining
static size_t xMinimumEverFreeBytesRemaining
Definition: heap_4.c:145
portBYTE_ALIGNMENT
#define portBYTE_ALIGNMENT
Definition: portmacro.h:117
xFreeBytesRemaining
static size_t xFreeBytesRemaining
Definition: heap_4.c:144
portCPUID
#define portCPUID
Definition: port.c:106
xBlockAllocatedBit
static size_t xBlockAllocatedBit
Definition: heap_4.c:151
A_BLOCK_LINK::pxNextFreeBlock
struct A_BLOCK_LINK * pxNextFreeBlock
Definition: heap_4.c:113
void
void
Definition: png.h:1083
portMAX_8_BIT_VALUE
#define portMAX_8_BIT_VALUE
Definition: port.c:117
prvInsertBlockIntoFreeList
static void prvInsertBlockIntoFreeList(BlockLink_t *pxBlockToInsert)
Definition: heap_4.c:419
configMAX_SYSCALL_INTERRUPT_PRIORITY
#define configMAX_SYSCALL_INTERRUPT_PRIORITY
Definition: FreeRTOSConfig.h:157
uxCriticalNesting
static UBaseType_t uxCriticalNesting
Definition: port.c:157
traceFREE
#define traceFREE(pvAddress, uiSize)
Definition: FreeRTOS.h:574
uint8_t
const uint8_t[]
Definition: 404_html.c:3
prvHeapInit
static void prvHeapInit(void)
Definition: heap_4.c:371
portNVIC_SYSPRI2_REG
#define portNVIC_SYSPRI2_REG
Definition: port.c:96
xHeapStructSize
static const size_t xHeapStructSize
Definition: heap_4.c:137
xStart
static BlockLink_t xStart
Definition: heap_4.c:140
portTOP_BIT_OF_BYTE
#define portTOP_BIT_OF_BYTE
Definition: port.c:118
vPortSetupTimerInterrupt
void vPortSetupTimerInterrupt(void)
xTaskResumeAll
PRIVILEGED_FUNCTION BaseType_t xTaskResumeAll(void)
Definition: tasks.c:2017
portFIRST_USER_INTERRUPT_NUMBER
#define portFIRST_USER_INTERRUPT_NUMBER
Definition: port.c:114
prvPortStartFirstTask
static void prvPortStartFirstTask(void)
Definition: port.c:292
portMAX_PRIGROUP_BITS
#define portMAX_PRIGROUP_BITS
Definition: port.c:119
portNVIC_IP_REGISTERS_OFFSET_16
#define portNVIC_IP_REGISTERS_OFFSET_16
Definition: port.c:115
portASPEN_AND_LSPEN_BITS
#define portASPEN_AND_LSPEN_BITS
Definition: port.c:128
vTaskSuspendAll
PRIVILEGED_FUNCTION void vTaskSuspendAll(void)
Definition: tasks.c:1944
vPortEnableVFP
static void vPortEnableVFP(void)
Definition: port.c:689
portPRIORITY_GROUP_MASK
#define portPRIORITY_GROUP_MASK
Definition: port.c:120
const
#define const
Definition: zconf.h:230
mtCOVERAGE_TEST_MARKER
#define mtCOVERAGE_TEST_MARKER()
Definition: FreeRTOS.h:748