/** * This function will initialize thread stack * * @param tentry the entry of thread * @param parameter the parameter of entry * @param stack_addr the beginning stack address * @param texit the function will be called when thread exit * * @return stack address */ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) { rt_uint32_t *stk; stack_addr += sizeof(rt_uint32_t); stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); stk = (rt_uint32_t *)stack_addr; *(--stk) = (rt_uint32_t)tentry; /* entry point */ *(--stk) = (rt_uint32_t)texit; /* lr */ *(--stk) = 0xdeadbeef; /* r12 */ *(--stk) = 0xdeadbeef; /* r11 */ *(--stk) = 0xdeadbeef; /* r10 */ *(--stk) = 0xdeadbeef; /* r9 */ *(--stk) = 0xdeadbeef; /* r8 */ *(--stk) = 0xdeadbeef; /* r7 */ *(--stk) = 0xdeadbeef; /* r6 */ *(--stk) = 0xdeadbeef; /* r5 */ *(--stk) = 0xdeadbeef; /* r4 */ *(--stk) = 0xdeadbeef; /* r3 */ *(--stk) = 0xdeadbeef; /* r2 */ *(--stk) = 0xdeadbeef; /* r1 */ *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ /* cpsr */ if ((rt_uint32_t)tentry & 0x01) *(--stk) = SVCMODE | 0x20; /* thumb mode */ else *(--stk) = SVCMODE; /* arm mode */ /* return task's current stack address */ return (rt_uint8_t *)stk; }
/** * This function will initialize thread stack * * @param tentry the entry of thread * @param parameter the parameter of entry * @param stack_addr the beginning stack address * @param texit the function will be called when thread exit * * @return stack address */ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) { struct stack_frame *stack_frame; rt_uint8_t *stk; unsigned long i; stk = stack_addr + sizeof(rt_uint32_t); stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8); stk -= sizeof(struct stack_frame); stack_frame = (struct stack_frame *)stk; /* init all register */ for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++) { ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef; } stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */ stack_frame->exception_stack_frame.r1 = 0; /* r1 */ stack_frame->exception_stack_frame.r2 = 0; /* r2 */ stack_frame->exception_stack_frame.r3 = 0; /* r3 */ stack_frame->exception_stack_frame.r12 = 0; /* r12 */ stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */ stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */ stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */ /* return task's current stack address */ return stk; }
/** * @brief ry_meminit This function should be called first.It * initial the memmory infomation * * @author renyong (2012-11-30) * * @param start_addr in: the start of the memmory * @param end_addr in: the end of the memmory * * @return int return RY_OK when success or return RY_ERROR */ int ry_meminit(void * start_addr,void * end_addr) { struct st_ry_mem_node *mem; unsigned int begin_align = RY_ALIGN((unsigned int)start_addr,RY_ALIGN_SIZE); unsigned int end_align = RT_ALIGN_DOWN((unsigned int)end_addr,RY_ALIGN_SIZE); if ((end_align >(2*SIZEOF_STRUCT_MEM))&& ((end_align - 2*SIZEOF_STRUCT_MEM )>=begin_align)) { /*calculate the memory size */ ry_mem_info.max = end_align - begin_align - 2 * SIZEOF_STRUCT_MEM; } else { RY_MEM_DEBUG("mem init failed ,start 0x%x, end 0x%x\r\n", (unsigned int)start_addr,(unsigned int)end_addr); return RY_ERROR; } /*the start of the mem */ ry_mem_info.phead=begin_align; printf("size of struct is %d\r\n",SIZEOF_STRUCT_MEM); RY_MEM_DEBUG("mem init: start 0x%x,size %d\r\n", begin_align,ry_mem_info.max); /* * init the ry_mem_info */ ry_mem_info.unused=ry_mem_info.max; ry_mem_info.used=0; /* * init the start of the mem */ mem=(struct st_ry_mem_node *)(ry_mem_info.phead); mem->isuse=0; mem->next=begin_align+ry_mem_info.max+SIZEOF_STRUCT_MEM; mem->pre=0; mem->magic=RY_MEM_MAGIC; /* * init the end of the mem */ ry_mem_info.ptail=mem->next; mem=(struct st_ry_mem_node *)ry_mem_info.ptail; mem->isuse=1; mem->next=ry_mem_info.max+SIZEOF_STRUCT_MEM; mem->pre=ry_mem_info.max+SIZEOF_STRUCT_MEM; /* * init the lower free point */ ry_mem_info.lfree=ry_mem_info.phead; #if RY_MEM_MUTEX_ENABLE RY_MEM_MUTEX_INIT(ry_mem_info.mutex); #endif /*init the mutex*/ return RY_OK; }
int pthread_attr_setstack(pthread_attr_t *attr, void *stack_base, size_t stack_size) { RT_ASSERT(attr != RT_NULL); attr->stack_base = stack_base; attr->stack_size = RT_ALIGN_DOWN(stack_size, RT_ALIGN_SIZE); return 0; }
void rt_ringbuffer_init(struct rt_ringbuffer* rb, rt_uint8_t *pool, rt_uint16_t size) { RT_ASSERT(rb != RT_NULL); /* initialize read and write index */ rb->read_index = rb->write_index = 0; /* set buffer pool and size */ rb->buffer_ptr = pool; rb->buffer_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE); }
/** * @ingroup SystemInit * * This function will init system heap * * @param begin_addr the beginning address of system page * @param end_addr the end address of system page */ void rt_system_heap_init(void *begin_addr, void *end_addr) { rt_uint32_t limsize, npages; RT_DEBUG_NOT_IN_INTERRUPT; /* align begin and end addr to page */ heap_start = RT_ALIGN((rt_uint32_t)begin_addr, RT_MM_PAGE_SIZE); heap_end = RT_ALIGN_DOWN((rt_uint32_t)end_addr, RT_MM_PAGE_SIZE); if (heap_start >= heap_end) { rt_kprintf("rt_system_heap_init, wrong address[0x%x - 0x%x]\n", (rt_uint32_t)begin_addr, (rt_uint32_t)end_addr); return; } limsize = heap_end - heap_start; npages = limsize / RT_MM_PAGE_SIZE; /* initialize heap semaphore */ rt_sem_init(&heap_sem, "heap", 1, RT_IPC_FLAG_FIFO); RT_DEBUG_LOG(RT_DEBUG_SLAB, ("heap[0x%x - 0x%x], size 0x%x, 0x%x pages\n", heap_start, heap_end, limsize, npages)); /* init pages */ rt_page_init((void *)heap_start, npages); /* calculate zone size */ zone_size = ZALLOC_MIN_ZONE_SIZE; while (zone_size < ZALLOC_MAX_ZONE_SIZE && (zone_size << 1) < (limsize/1024)) zone_size <<= 1; zone_limit = zone_size / 4; if (zone_limit > ZALLOC_ZONE_LIMIT) zone_limit = ZALLOC_ZONE_LIMIT; zone_page_cnt = zone_size / RT_MM_PAGE_SIZE; RT_DEBUG_LOG(RT_DEBUG_SLAB, ("zone size 0x%x, zone page count 0x%x\n", zone_size, zone_page_cnt)); /* allocate memusage array */ limsize = npages * sizeof(struct memusage); limsize = RT_ALIGN(limsize, RT_MM_PAGE_SIZE); memusage = rt_page_alloc(limsize/RT_MM_PAGE_SIZE); RT_DEBUG_LOG(RT_DEBUG_SLAB, ("memusage 0x%x, size 0x%x\n", (rt_uint32_t)memusage, limsize)); }
/** * @ingroup SystemInit * * This function will init system heap * * @param begin_addr the beginning address of system page * @param end_addr the end address of system page */ void rt_system_heap_init(void *begin_addr, void *end_addr) { struct heap_mem *mem; rt_uint32_t begin_align = RT_ALIGN((rt_uint32_t)begin_addr, RT_ALIGN_SIZE); rt_uint32_t end_align = RT_ALIGN_DOWN((rt_uint32_t)end_addr, RT_ALIGN_SIZE); RT_DEBUG_NOT_IN_INTERRUPT; /* alignment addr */ if ((end_align > (2 * SIZEOF_STRUCT_MEM)) && ((end_align - 2 * SIZEOF_STRUCT_MEM) >= begin_align)) { /* calculate the aligned memory size */ mem_size_aligned = end_align - begin_align - 2 * SIZEOF_STRUCT_MEM; } else { rt_kprintf("mem init, error begin address 0x%x, and end address 0x%x\n", (rt_uint32_t)begin_addr, (rt_uint32_t)end_addr); return; } /* point to begin address of heap */ heap_ptr = (rt_uint8_t *)begin_align; RT_DEBUG_LOG(RT_DEBUG_MEM, ("mem init, heap begin address 0x%x, size %d\n", (rt_uint32_t)heap_ptr, mem_size_aligned)); /* initialize the start of the heap */ mem = (struct heap_mem *)heap_ptr; mem->magic = HEAP_MAGIC; mem->next = mem_size_aligned + SIZEOF_STRUCT_MEM; mem->prev = 0; mem->used = 0; /* initialize the end of the heap */ heap_end = (struct heap_mem *)&heap_ptr[mem->next]; heap_end->magic = HEAP_MAGIC; heap_end->used = 1; heap_end->next = mem_size_aligned + SIZEOF_STRUCT_MEM; heap_end->prev = mem_size_aligned + SIZEOF_STRUCT_MEM; rt_sem_init(&heap_sem, "heap", 1, RT_IPC_FLAG_FIFO); /* initialize the lowest-free pointer to the start of the heap */ lfree = (struct heap_mem *)heap_ptr; }
/** * This function will initialize thread stack * * @param tentry the entry of thread * @param parameter the parameter of entry * @param stack_addr the beginning stack address * @param texit the function will be called when thread exit * * @return stack address */ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) { rt_uint32_t *stk; //stk = (rt_uint32_t*)stack_addr; stack_addr += sizeof(rt_uint32_t); stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); stk = (rt_uint32_t *)stack_addr; *(--stk) = (rt_uint32_t)tentry; /* entry point */ *(--stk) = (rt_uint32_t)texit; /* ra */ *(--stk) = (rt_uint32_t)parameter; /* a0 */ *(--stk) = 0xffffffff; /* a1 */ *(--stk) = 0xffffffff; /* a2 */ *(--stk) = 0xffffffff; /* a3 */ *(--stk) = 0xffffffff; /* a4 */ *(--stk) = 0xffffffff; /* a5 */ *(--stk) = 0xffffffff; /* a6 */ *(--stk) = 0xffffffff; /* a7 */ *(--stk) = 0xffffffff; /* s0/fp */ *(--stk) = 0xffffffff; /* s1 */ *(--stk) = 0xffffffff; /* s2 */ *(--stk) = 0xffffffff; /* s3 */ *(--stk) = 0xffffffff; /* s4 */ *(--stk) = 0xffffffff; /* s5 */ *(--stk) = 0xffffffff; /* s6 */ *(--stk) = 0xffffffff; /* s7 */ *(--stk) = 0xffffffff; /* s8 */ *(--stk) = 0xffffffff; /* s9 */ *(--stk) = 0xffffffff; /* s10*/ *(--stk) = 0xffffffff; /* s11*/ *(--stk) = 0xffffffff; /* t0 */ *(--stk) = 0xffffffff; /* t1 */ *(--stk) = 0xffffffff; /* t2 */ *(--stk) = 0xffffffff; /* t3 */ *(--stk) = 0xffffffff; /* t4 */ *(--stk) = 0xffffffff; /* t5 */ *(--stk) = 0xffffffff; /* t6 */ *(--stk) = 0xffffffff; /* tp */ *(--stk) = 0xffffffff; /* gp */ *(--stk) = 0x880; /* mie */ // *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ /* return task's current stack address */ return (rt_uint8_t *)stk; }
/** * This function will initialize a memory pool object, normally which is used * for static object. * * @param mp the memory pool object * @param name the name of memory pool * @param start the star address of memory pool * @param size the total size of memory pool * @param block_size the size for each block * * @return RT_EOK */ rt_err_t rt_mp_init(struct rt_mempool *mp, const char *name, void *start, rt_size_t size, rt_size_t block_size) { rt_uint8_t *block_ptr; register rt_base_t offset; /* parameter check */ RT_ASSERT(mp != RT_NULL); /* initialize object */ rt_object_init(&(mp->parent), RT_Object_Class_MemPool, name); /* initialize memory pool */ mp->start_address = start; mp->size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE); /* align the block size */ block_size = RT_ALIGN(block_size, RT_ALIGN_SIZE); mp->block_size = block_size; /* align to align size byte */ mp->block_total_count = mp->size / (mp->block_size + sizeof(rt_uint8_t *)); mp->block_free_count = mp->block_total_count; /* initialize suspended thread list */ rt_list_init(&(mp->suspend_thread)); mp->suspend_thread_count = 0; /* initialize free block list */ block_ptr = (rt_uint8_t *)mp->start_address; for (offset = 0; offset < mp->block_total_count; offset ++) { *(rt_uint8_t **)(block_ptr + offset * (block_size + sizeof(rt_uint8_t *))) = (rt_uint8_t *)(block_ptr + (offset + 1) * (block_size + sizeof(rt_uint8_t *))); } *(rt_uint8_t **)(block_ptr + (offset - 1) * (block_size + sizeof(rt_uint8_t *))) = RT_NULL; mp->block_list = block_ptr; return RT_EOK; }
/* * The initialized memory pool will be: * +-----------------------------------+--------------------------+ * | whole freed memory block | Used Memory Block Tailer | * +-----------------------------------+--------------------------+ * * block_list --> whole freed memory block * * The length of Used Memory Block Tailer is 0, * which is prevents block merging across list */ rt_err_t rt_memheap_init(struct rt_memheap *memheap, const char *name, void *start_addr, rt_uint32_t size) { struct rt_memheap_item *item; RT_ASSERT(memheap != RT_NULL); /* initialize pool object */ rt_object_init(&(memheap->parent), RT_Object_Class_MemHeap, name); memheap->start_addr = start_addr; memheap->pool_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE); memheap->available_size = memheap->pool_size - (2 * RT_MEMHEAP_SIZE); memheap->max_used_size = memheap->pool_size - memheap->available_size; /* initialize the free list header */ item = &(memheap->free_header); item->magic = RT_MEMHEAP_MAGIC; item->pool_ptr = memheap; item->next = RT_NULL; item->prev = RT_NULL; item->next_free = item; item->prev_free = item; /* set the free list to free list header */ memheap->free_list = item; /* initialize the first big memory block */ item = (struct rt_memheap_item *)start_addr; item->magic = RT_MEMHEAP_MAGIC; item->pool_ptr = memheap; item->next = RT_NULL; item->prev = RT_NULL; item->next_free = item; item->prev_free = item; item->next = (struct rt_memheap_item *) ((rt_uint8_t *)item + memheap->available_size + RT_MEMHEAP_SIZE); item->prev = item->next; /* block list header */ memheap->block_list = item; /* place the big memory block to free list */ item->next_free = memheap->free_list->next_free; item->prev_free = memheap->free_list; memheap->free_list->next_free->prev_free = item; memheap->free_list->next_free = item; /* move to the end of memory pool to build a small tailer block, * which prevents block merging */ item = item->next; /* it's a used memory block */ item->magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED; item->pool_ptr = memheap; item->next = (struct rt_memheap_item *)start_addr; item->prev = (struct rt_memheap_item *)start_addr; /* not in free list */ item->next_free = item->prev_free = RT_NULL; /* initialize semaphore lock */ rt_sem_init(&(memheap->lock), name, 1, RT_IPC_FLAG_FIFO); RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x\n", start_addr, size, &(memheap->free_header))); return RT_EOK; }