void *task_alloc() { char *result; if (!initialized) { /* Allocate MEMORY_BLOCK_SIZE of memory */ memory_block_start = _sbrk(MEMORY_BLOCK_SIZE); memory_block_end = memory_block_start + MEMORY_BLOCK_SIZE; if (memory_block_start == (char *)-1) { return NULL; } /* Return a pointer to the beginning of this block */ result = memory_block_start; initialized = 1; } else { /* Check if the linked list is non-empty */ if (free_slots.first) { int next = *(int *)free_slots.first; result = free_slots.first; /* Update first if this slot contains a pointer to the next free slot, otherwise make this linked list empty */ if (next) { free_slots.first = (char *)next; } else { free_slots.first = NULL; } } else { /* In case the linked list is empty, just allocate the slot after the last allocated slot */ result = last_allocated_slot + sizeof(task_t); /* Increase the size of this memory block if necessary */ if (result + sizeof(task_t) >= memory_block_end) { if (_sbrk(MEMORY_BLOCK_SIZE) == (char *)-1) { return NULL; } memory_block_end += MEMORY_BLOCK_SIZE; } /* The last freed slot doesn't exist anymore (?) */ free_slots.last = NULL; } } /* Update the last allocated slot */ if (result > last_allocated_slot) last_allocated_slot = result; return result; }
void cli_cmd_profile(char *cmdline) { uint64_t task_counts[CFG_MAX_USER_TASKS+SYS_TASK_NUM]; uint64_t count, pct, total = 0; void *heap; int i; DISABLE_IRQ(); for(i = 0; i < CFG_MAX_USER_TASKS+SYS_TASK_NUM; i++) { task_counts[i] = count = TCBTbl[i].tick_count; total += count; } ENABLE_IRQ(); cli_printf("# Counts %% Name\r\n"); for(i = 0; i < CFG_MAX_USER_TASKS+SYS_TASK_NUM; i++) { count = task_counts[i]; pct = 10000 * count / total; cli_printf("%2d %08x%08x %3u.%02u%% %s\r\n", i, (uint32_t)(count >> 32), (uint32_t)count, (uint32_t)(pct / 100), (uint32_t)(pct % 100), TCBTbl[i].name); } heap = _sbrk(0); if (heap != (void*)-1) { cli_printf("Heap usage: %d bytes\r\n", heap - (void*)&_sheap); } }
// Main program int main(void) { char i; char *heap_end; // Initialize all modules uart_init(115200); accel_init(); touch_init((1 << 9) | (1 << 10)); // Channels 9 and 10 // usb_init(); setvbuf(stdin, NULL, _IONBF, 0); // No buffering // Run tests tests(); delay(500); RGB_LED(0,100,0); // Green // Welcome banner iprintf("\r\n\r\n====== Freescale Freedom FRDM-LK25Z\r\n"); iprintf("Built: %s %s\r\n\r\n", __DATE__, __TIME__); heap_end = _sbrk(0); iprintf("Heap: %p to %p (%d bytes used)\r\n", __heap_start, heap_end, heap_end - __heap_start); iprintf("Stack: %p to %p (%d bytes used)\r\n", &i, __StackTop, __StackTop - &i); iprintf("%d bytes free\r\n", &i - heap_end); for(;;) { iprintf("monitor> "); getchar(); iprintf("\r\n"); iprintf("Inputs: x=%5d y=%5d z=%5d ", accel_x(), accel_y(), accel_z()); iprintf("touch=(%d,%d)\r\n", touch_data(9), touch_data(10)); // usb_dump(); } }
/* sbrk */ #if defined(SYS_sbrk) extern void * _sbrk(intptr_t increment); /* XXX in-kernel prototype */ # if defined(SYS_brk) /* SYS_sbrk && SYS_brk */ extern int _brk(void * addr); /* XXX in-kernel prototype */ void * sbrk(intptr_t increment) /* _brk is used to actually allocate memory */ { void * cur; if((cur = _sbrk(0)) == (void*)-1 || increment == 0) return cur; return _brk(cur + increment) != (void*)-1 ? cur : (void*)-1; }
// show free memory void SimpleShell::mem_command( string parameters, StreamOutput* stream){ bool verbose= shift_parameter( parameters ).find_first_of("Vv") != string::npos ; unsigned long heap= (unsigned long)_sbrk(0); unsigned long m= g_maximumHeapAddress - heap; stream->printf("Unused Heap: %lu bytes\r\n", m); heapWalk(stream, verbose); }
unsigned int _wr4chk(unsigned int x) { if (((x&3) != 0) || (x < ETEXT) || (x > (unsigned int)_sbrk(0))) { fprintf(stderr,"Write check failure %x\n", x); exit(1); } return x; }
unsigned int _rd4chk(unsigned int x) { if (((x&3) != 0) || (x < LOW_LIMIT) || (x > (unsigned int)_sbrk(0))) { fprintf(stderr,"Read check failure %x\n", x); exit(1); } return x; }
void os_bsp_init(void) { /* * XXX this reference is here to keep this function in. */ _sbrk(0); _close(0); }
void *_sbrk_r(struct _reent *ptr, size_t incr) { char *ret; void *_sbrk(size_t); errno = 0; if ((ret = (char *)(_sbrk(incr))) == (void *)-1 && errno != 0) ptr->_errno = errno; return ret; }
void os_bsp_init(void) { /* * XXX these references are here to keep the functions in for libc to find. */ _sbrk(0); _close(0); flash_area_init(bsp_flash_areas, sizeof(bsp_flash_areas) / sizeof(bsp_flash_areas[0])); }
// Adam Greens heap walk from http://mbed.org/forum/mbed/topic/2701/?page=4#comment-22556 static void heapWalk(StreamOutput* stream, bool verbose) { uint32_t chunkNumber = 1; // The __end__ linker symbol points to the beginning of the heap. uint32_t chunkCurr = (uint32_t)&__end__; // __malloc_free_list is the head pointer to newlib-nano's link list of free chunks. uint32_t freeCurr = __malloc_free_list; // Calling _sbrk() with 0 reserves no more memory but it returns the current top of heap. uint32_t heapEnd = _sbrk(0); // accumulate totals uint32_t freeSize= 0; uint32_t usedSize= 0; stream->printf("Used Heap Size: %lu\n", heapEnd - chunkCurr); // Walk through the chunks until we hit the end of the heap. while (chunkCurr < heapEnd) { // Assume the chunk is in use. Will update later. int isChunkFree = 0; // The first 32-bit word in a chunk is the size of the allocation. newlib-nano over allocates by 8 bytes. // 4 bytes for this 32-bit chunk size and another 4 bytes to allow for 8 byte-alignment of returned pointer. uint32_t chunkSize = *(uint32_t*)chunkCurr; // The start of the next chunk is right after the end of this one. uint32_t chunkNext = chunkCurr + chunkSize; // The free list is sorted by address. // Check to see if we have found the next free chunk in the heap. if (chunkCurr == freeCurr) { // Chunk is free so flag it as such. isChunkFree = 1; // The second 32-bit word in a free chunk is a pointer to the next free chunk (again sorted by address). freeCurr = *(uint32_t*)(freeCurr + 4); } // Skip past the 32-bit size field in the chunk header. chunkCurr += 4; // 8-byte align the data pointer. chunkCurr = (chunkCurr + 7) & ~7; // newlib-nano over allocates by 8 bytes, 4 bytes for the 32-bit chunk size and another 4 bytes to allow for 8 // byte-alignment of the returned pointer. chunkSize -= 8; if(verbose) stream->printf(" Chunk: %lu Address: 0x%08lX Size: %lu %s\n", chunkNumber, chunkCurr, chunkSize, isChunkFree ? "CHUNK FREE" : ""); if(isChunkFree) freeSize += chunkSize; else usedSize += chunkSize; chunkCurr = chunkNext; chunkNumber++; } stream->printf("Allocated: %lu, Free: %lu\r\n", usedSize, freeSize); }
void os_bsp_init(void) { /* * XXX this reference is here to keep this function in. */ _sbrk(0); _close(0); flash_area_init(bsp_flash_areas, sizeof(bsp_flash_areas) / sizeof(bsp_flash_areas[0])); }
void * _sbrk_r (struct _reent *ptr, ptrdiff_t incr) { char *ret; void *_sbrk(ptrdiff_t); errno = 0; if ((ret = (char *)(_sbrk (incr))) == (void *) -1 && errno != 0) __errno_r(ptr) = errno; return ret; }
// show free memory void SimpleShell::mem_command( string parameters, StreamOutput *stream) { bool verbose = shift_parameter( parameters ).find_first_of("Vv") != string::npos ; unsigned long heap = (unsigned long)_sbrk(0); unsigned long m = g_maximumHeapAddress - heap; stream->printf("Unused Heap: %lu bytes\r\n", m); uint32_t f = heapWalk(stream, verbose); stream->printf("Total Free RAM: %lu bytes\r\n", m + f); stream->printf("Free AHB0: %lu, AHB1: %lu\r\n", AHB0.free(), AHB1.free()); if (verbose) { AHB0.debug(stream); AHB1.debug(stream); } }
void *malloc(int size) { int *p, *end; int k, n, tries; size = (size + sizeof(int) - 1) / sizeof(int); if (NULL == _arena) { if (size >= THRESHOLD) _asize = size + 1; else _asize = size * OVERALLOC; _arena = _sbrk(_asize * sizeof(int)); if ((int *) -1 == _arena) { errno = ENOMEM; return NULL; } _arena[0] = _asize; freep = _arena; } for (tries = 0; tries < 3; tries++) { end = _arena + _asize; p = freep; do { if (*p > size) { if (size + 1 == *p) { *p = -*p; } else { k = *p; *p = -(size+1); p[size+1] = k - size - 1; } freep = p; return p+1; } p += abs(*p); if (p == end) p = _arena; if (p < _arena || p >= end || 0 == *p) { _write(2, "malloc(): corrupt arena\n", 24); abort(); } } while (p != freep); if (0 == tries) { defrag(); } else { if (size >= THRESHOLD) n = size + 1; else n = size * OVERALLOC; if (_sbrk(n * sizeof(int)) == (void *)-1) { errno = ENOMEM; return NULL; } k = _asize; _asize += n; *end = _asize - k; } } errno = ENOMEM; return NULL; }
// Return free memory between end of heap (or end bss) and whatever is current int freeMemory() { int free_memory, heap_end = (int)_sbrk(0); return (int)&free_memory - (heap_end ? heap_end : (int)&_ebss); }
// Main program int main(void) { char i; char ch; char *heap_end; char inBuffer[BUF_SIZE]; int readLen,bufPos; int n; int nargs[10]; int hasAccelData = 0; int hasTouchData = 0; // Initialize all modules RGB_LED(100,0,0); //uart_init(115200); uart_init(9600); accel_init(); touch_init((1 << 9) | (1 << 10)); // Channels 9 and 10 // usb_init(); setvbuf(stdin, NULL, _IONBF, 0); // No buffering // Run tests tests(); delay(500); // Welcome banner iprintf("\r\n\r\n====== Freescale Freedom FRDM-LK25Z\r\n"); iprintf("Built: %s %s\r\n\r\n", __DATE__, __TIME__); heap_end = _sbrk(0); iprintf("Heap: %p to %p (%d bytes used)\r\n", __heap_start, heap_end, heap_end - (char *)__heap_start); iprintf("Stack: %p to %p (%d bytes used)\r\n", &i, __StackTop, (char *)__StackTop - &i); iprintf("%d bytes free\r\n", &i - heap_end); inBuffer[0] = 0; // reset buffer bufPos = 0; RGB_LED(0,100,0); // Green for(;;) { readLen = uart_read_nonblock(inBuffer+bufPos,BUF_SIZE-(bufPos+2)); if (readLen>0) { bufPos+=readLen; // quick trim while(bufPos>0 && isspace(inBuffer[bufPos-1])) bufPos--; inBuffer[bufPos] = 0; if (inBuffer[bufPos-1] == ';') { iprintf("(in buf = '%s', len=%d)\r\n",inBuffer,bufPos); switch(inBuffer[0]) { case 'C': n = sscanf(inBuffer+1,"%i,%i,%i",&nargs[0],&nargs[1],&nargs[2]); if(n==3) RGB_LED(nargs[0],nargs[1],nargs[2]); break; case 'R': RGB_LED(100,0,0); break; case 'G': RGB_LED(0,100,0); break; case 'B': RGB_LED(0,0,100); break; case 'A': hasAccelData = 1; break; case 'a': hasAccelData = 0; break; case 'T': hasTouchData = 1; break; case 't': hasTouchData = 0; break; case 'i': iprintf("[efb,0.1] empiriKit Freescale Board, v.0.1\r\n"); break; } bufPos = 0; // "clear" the buffer } } if (hasAccelData) iprintf("a%d,%d,%d;\r\n", accel_x(), accel_y(), accel_z()); if (hasTouchData) iprintf("t%d,%d;\r\n", touch_data(9), touch_data(10)); } }
void * malloc (int nbytes) { return _sbrk(nbytes); }
/* sbrk */ #if defined(SYS_sbrk) extern void * _sbrk(intptr_t increment); /* XXX in-kernel prototype */ # if defined(SYS_brk) /* SYS_sbrk && SYS_brk */ extern int _brk(void * addr); /* XXX in-kernel prototype */ void * sbrk(intptr_t increment) /* _brk is used to actually allocate memory */ { void * cur; if((cur = _sbrk(0)) == (void*)-1 || increment == 0) return cur; return _brk(cur + increment) != (void*)-1 ? cur : (void*)-1; } # else /* SYS_sbrk && !SYS_brk */ void * sbrk(intptr_t increment) { return _sbrk(increment); }
void *_sbrk_r(struct _reent *ptr, ptrdiff_t increment) { return _sbrk(increment); }