2022-05-17 03:56:25 +00:00
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
|
|
|
#include "itoa.h"
|
|
|
|
#include "lock.h"
|
|
|
|
#include "timer.h"
|
|
|
|
#include "uart.h"
|
|
|
|
|
2022-06-19 07:48:28 +00:00
|
|
|
#ifndef SBRK_STATS
|
|
|
|
#define SBRK_STATS 0
|
|
|
|
#endif
|
|
|
|
|
2022-05-17 03:56:25 +00:00
|
|
|
extern unsigned char _heap_begin, _heap_end;
|
|
|
|
|
|
|
|
namespace {
|
2022-06-19 07:48:28 +00:00
|
|
|
[[maybe_unused]]
|
2022-05-17 03:56:25 +00:00
|
|
|
void LogStats(unsigned char* heap) {
|
|
|
|
char number[] = "00000000\r\n";
|
2022-06-19 07:48:28 +00:00
|
|
|
UartWriteCrash("Program break now at 0x");
|
2022-05-17 03:56:25 +00:00
|
|
|
itoa(reinterpret_cast<int>(heap), number);
|
2022-06-19 07:48:28 +00:00
|
|
|
UartWriteCrash(number);
|
2022-05-17 03:56:25 +00:00
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
extern "C" void* _sbrk(int increment) {
|
|
|
|
static unsigned char* heap = &_heap_begin;
|
|
|
|
unsigned char* prev_heap = heap;
|
|
|
|
if (heap + increment >= &_heap_end) {
|
2022-06-19 07:48:28 +00:00
|
|
|
UartWriteCrash("Heap overflow!\r\n");
|
2022-05-17 03:56:25 +00:00
|
|
|
return reinterpret_cast<void*>(-1);
|
|
|
|
}
|
|
|
|
heap += increment;
|
2022-06-19 07:48:28 +00:00
|
|
|
#if SBRK_STATS
|
2022-05-17 03:56:25 +00:00
|
|
|
LogStats(heap);
|
2022-06-19 07:48:28 +00:00
|
|
|
#endif
|
2022-05-17 03:56:25 +00:00
|
|
|
return prev_heap;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" int _gettimeofday(struct timeval* tv, void* tzvp) {
|
|
|
|
uint32_t ticks = timer0->GetT1Ticks();
|
|
|
|
tv->tv_sec = ticks / 100000000;
|
|
|
|
tv->tv_usec = (ticks % 100000000) / 100;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" uint8_t __atomic_exchange_1(volatile void* ptr, uint8_t val,
|
|
|
|
int memorder) {
|
|
|
|
auto* dest = reinterpret_cast<volatile uint8_t*>(ptr);
|
|
|
|
bool ret;
|
|
|
|
|
|
|
|
{
|
|
|
|
InterruptLock lock;
|
|
|
|
ret = *dest;
|
|
|
|
*dest = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|