#include <stdint.h>

#include "FreeRTOS.h"
#include "lab_freertos.h"
#include "lab_io.h"

/* Official heap_4.c uses this application-owned arena. */
__attribute__( ( aligned( 16 ) ) ) uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
volatile uint32_t g_failure_code;

int lab_address_in_heap( const volatile void * address )
{
    const uintptr_t value = ( uintptr_t ) address;
    const uintptr_t first = ( uintptr_t ) &ucHeap[ 0 ];
    const uintptr_t past_last = ( uintptr_t ) &ucHeap[ configTOTAL_HEAP_SIZE ];

    return ( value >= first ) && ( value < past_last );
}

void lab_heap_initialize( void )
{
    void * probe = pvPortMalloc( 1U );

    if( probe == NULL )
    {
        lab_fail( 0xA6000002UL );
    }
    vPortFree( probe );
}

void lab_fail( uint32_t code )
{
    g_failure_code = code;
    lab_puts( "FAIL\n" );
    lab_put_u32( code );
    lab_exit( code );
}

void lab_assert_fail( const char * file, int line )
{
    ( void ) file;
    lab_fail( 0xA5000000UL | ( ( uint32_t ) line & 0xFFFFUL ) );
}

void vApplicationMallocFailedHook( void )
{
    lab_fail( 0xA6000001UL );
}
