From 32a77c697d52124850e72fac79254e1ec0e8a16d Mon Sep 17 00:00:00 2001 From: root Date: Sat, 26 Aug 2023 23:12:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0mpu=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- mkrtos_knl/arch/armv7m/arch.c | 3 +- mkrtos_knl/arch/armv7m/sche.S | 5 +- mkrtos_knl/arch/armv7m/stm32f203/mpu.c | 188 +++++------------- .../arch/armv7m/stm32f203/stm32f2xx_it.c | 11 +- mkrtos_knl/inc/knl/misc.h | 6 + mkrtos_knl/inc/knl/mm.h | 2 - mkrtos_knl/inc/knl/mm_space.h | 34 ++++ mkrtos_knl/inc/knl/mm_wrap.h | 3 + mkrtos_knl/inc/knl/mpu.h | 8 + mkrtos_knl/inc/knl/obj_space.h | 73 +------ mkrtos_knl/inc/knl/task.h | 3 +- mkrtos_knl/inc/knl/util.h | 2 + mkrtos_knl/inc/lib/types.h | 2 + mkrtos_knl/knl/misc.c | 170 ++++++++++++++++ mkrtos_knl/knl/mm.c | 11 +- mkrtos_knl/knl/mm_space.c | 49 +++++ mkrtos_knl/knl/mm_wrap.c | 9 + mkrtos_knl/knl/obj_space.c | 72 +++++++ mkrtos_knl/knl/task.c | 1 + mkrtos_knl/knl/thread_knl.c | 8 +- mkrtos_knl/knl/util.c | 13 ++ mkrtos_user/lib/mlibc/crt/crt1_init.c | 6 +- mkrtos_user/lib/mlibc/include/limits.h | 2 +- mkrtos_user/lib/mlibc/src/stdio/vfprintf.c | 7 +- mkrtos_user/server/init/src/main.c | 5 + setting.cmake | 10 +- 27 files changed, 464 insertions(+), 242 deletions(-) create mode 100644 mkrtos_knl/inc/knl/misc.h create mode 100644 mkrtos_knl/inc/knl/mm_space.h create mode 100644 mkrtos_knl/inc/knl/mpu.h create mode 100644 mkrtos_knl/knl/misc.c create mode 100644 mkrtos_knl/knl/mm_space.c create mode 100644 mkrtos_knl/knl/util.c diff --git a/.vscode/settings.json b/.vscode/settings.json index 22ad0e3cb..b516dc31f 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -108,7 +108,8 @@ "crt_arch.h": "c", "stdio_impl.h": "c", "uio.h": "c", - "fs_backend.h": "c" + "fs_backend.h": "c", + "mm_space.h": "c" }, "cortex-debug.showRTOS": false, } \ No newline at end of file diff --git a/mkrtos_knl/arch/armv7m/arch.c b/mkrtos_knl/arch/armv7m/arch.c index 8e394c8b9..af9d7b9c5 100644 --- a/mkrtos_knl/arch/armv7m/arch.c +++ b/mkrtos_knl/arch/armv7m/arch.c @@ -14,7 +14,7 @@ #include "config.h" #include "thread.h" #include "stm32f2xx_conf.h" - +#include "mpu.h" __ALIGN__(THREAD_BLOCK_SIZE) static uint8_t thread_knl_stack[THREAD_BLOCK_SIZE] = {0}; void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE; @@ -41,5 +41,6 @@ void sys_startup(void) void arch_init(void) { SystemInit(); + mpu_enable(); } INIT_LOW_HARD(arch_init); diff --git a/mkrtos_knl/arch/armv7m/sche.S b/mkrtos_knl/arch/armv7m/sche.S index c43313384..63502b5d7 100755 --- a/mkrtos_knl/arch/armv7m/sche.S +++ b/mkrtos_knl/arch/armv7m/sche.S @@ -2,7 +2,7 @@ .cpu cortex-m3 .thumb -//.global mpu_update +.global mpu_switch_to .global PendSV_Handler .type PendSV_Handler, %function @@ -77,4 +77,7 @@ super_mode: //更新下msp的值 MSR CONTROL, R0 to_ret: CPSIE I + push {r0-r3, lr} + bl mpu_switch_to + pop {r0-r3, lr} BX LR diff --git a/mkrtos_knl/arch/armv7m/stm32f203/mpu.c b/mkrtos_knl/arch/armv7m/stm32f203/mpu.c index 960292bdc..28d591598 100755 --- a/mkrtos_knl/arch/armv7m/stm32f203/mpu.c +++ b/mkrtos_knl/arch/armv7m/stm32f203/mpu.c @@ -1,145 +1,47 @@ -// /* -// * mpu.c -// * -// * Created on: zhangzheng -// * Author: Administrator -// */ +/* + * mpu.c + * + * Created on: zhangzheng + * Author: Administrator + */ -// #include -// #include -// #include -// #include -// #include -// #include +#include "types.h" +#include "assert.h" +#include "mpu.h" +#include +#include +#include "task.h" +static volatile umword_t *MPUCR = (umword_t *)0xE000ED94; -// uint32_t *MPUCR = (uint32_t *)0xE000ED94; - -// void mpu_disable(void) -// { -// ARM_MPU_Disable(); -// } -// void mpu_enable(void) -// { -// ARM_MPU_Enable(4); -// } - -// void mpu_set(struct region_info *region_i, void *mem_start_addr, int size, int *ret_align_size) -// { -// int ffs_t_; -// int ffs_t; - -// ffs_t_ = ffs(size); -// // if (!is_power_of_2(size)) { -// // ffs_t_++; -// // } -// ffs_t = 1 << ffs_t_; - -// int sub_region_t = ffs_t >> 3; - -// int align_sub_size = ALIGN(size, sub_region_t); - -// uint32_t mem_align_sub_mem_addr = ALIGN((uint32_t)mem_start_addr, sub_region_t); -// uint32_t mem_align_up_mem_addr = ALIGN((uint32_t)mem_start_addr, ffs_t); -// uint32_t mem_align_down_mem_addr = ALIGN_DOWN((uint32_t)mem_start_addr, ffs_t); - -// region_i[0].start_addr = mem_align_sub_mem_addr; -// region_i[0].size = mem_align_up_mem_addr - mem_align_sub_mem_addr; -// region_i[0].block_size = ffs_t; -// region_i[0].block_start_addr = mem_align_down_mem_addr; - -// region_i[0].region = 0xff; -// for (uint32_t i = mem_align_down_mem_addr; i < mem_align_up_mem_addr; i += sub_region_t) -// { -// if (i < mem_align_sub_mem_addr) -// { -// region_i[0].region |= 1 << ((i - mem_align_down_mem_addr) / sub_region_t); -// } -// else -// { -// region_i[0].region &= ~(1 << ((i - mem_align_down_mem_addr) / sub_region_t)); -// } -// } - -// region_i[1].region = 0x00; -// for (uint32_t i = mem_align_up_mem_addr; i < mem_align_up_mem_addr + ffs_t; i += sub_region_t) -// { -// if (i < mem_align_sub_mem_addr + align_sub_size) -// { -// region_i[1].region &= ~(1 << ((i - mem_align_up_mem_addr) / sub_region_t)); -// } -// else -// { -// region_i[1].region |= (1 << ((i - mem_align_up_mem_addr) / sub_region_t)); -// } -// } -// region_i[1].start_addr = mem_align_up_mem_addr; -// region_i[1].size = (mem_align_sub_mem_addr + align_sub_size) - mem_align_up_mem_addr; -// region_i[1].block_size = ffs_t; -// region_i[1].block_start_addr = mem_align_up_mem_addr; - -// *ret_align_size = sub_region_t; - -// #if 1 -// kprint("st:0x%x re:0x%x sub:0x%x\n region:[", region_i[0].block_start_addr, region_i[0].region, sub_region_t); -// for (int i = 0; i < 8; i++) -// { -// if (region_i[0].region & (1 << i)) -// { -// kprint("x"); -// } -// else -// { -// kprint("o"); -// } -// } -// kprint("]\n"); -// kprint("st:0x%x re:0x%x sub:0x%x\n region:[", region_i[1].block_start_addr, region_i[1].region, sub_region_t); -// for (int i = 0; i < 8; i++) -// { -// if (region_i[1].region & (1 << i)) -// { -// kprint("x"); -// } -// else -// { -// kprint("o"); -// } -// } -// kprint("]\n"); -// #endif -// region_i[0].rbar = ARM_MPU_RBAR(0, region_i[0].block_start_addr); -// region_i[0].rasr = ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, region_i[0].region, ffs_t_ - 1); - -// region_i[1].rbar = ARM_MPU_RBAR(1, region_i[1].block_start_addr); -// region_i[1].rasr = ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, region_i[1].region, ffs_t_ - 1); - -// // region_i[2].rbar = ARM_MPU_RBAR(2, 0x20010000/*TODO:*/); -// // region_i[2].rasr = ARM_MPU_RASR(0UL, ARM_MPU_AP_URO, 0UL -// // , 0UL, 1UL, 1UL, 0x0/*TODO:*/, 16-1/*TODO:*/); - -// region_i[2].rbar = ARM_MPU_RBAR(2, 0x8000000 /*TODO:*/); -// region_i[2].rasr = ARM_MPU_RASR(0UL, ARM_MPU_AP_URO, 0UL, 0UL, 1UL, 1UL, 0x0 /*TODO:*/, ffs(1024 * 1024) - 1 /*TODO:*/); -// } - -// void mpu_update_to(struct task *tk) -// { -// mpu_disable(); -// if (tk->mpu) -// { -// ARM_MPU_SetRegion(tk->mpu->mpu_info[0].rbar, tk->mpu->mpu_info[0].rasr); -// ARM_MPU_SetRegion(tk->mpu->mpu_info[1].rbar, tk->mpu->mpu_info[1].rasr); -// ARM_MPU_SetRegion(tk->mpu->mpu_info[2].rbar, tk->mpu->mpu_info[2].rasr); -// } -// else -// { -// ARM_MPU_ClrRegion(0); -// ARM_MPU_ClrRegion(1); -// ARM_MPU_ClrRegion(2); -// } - -// mpu_enable(); -// } -// void mpu_update(void) -// { -// mpu_update_to(get_current_task()); -// } +void mpu_disable(void) +{ + ARM_MPU_Disable(); +} +void mpu_enable(void) +{ + ARM_MPU_Enable(4); +} +void mpu_calc_regs(region_info_t *region, umword_t addr, int ffs, uint8_t attrs, uint8_t regions_bits) +{ + region->rbar = ARM_MPU_RBAR(region->region_inx, addr); + region->rasr = ARM_MPU_RASR(0, attrs, 0UL, 0UL, + 1UL, 1UL, regions_bits, ffs - 1); +} +void mpu_switch_to(void) +{ + struct task *tk = thread_get_current_task(); + mpu_disable(); + for (int i = 0; i < REGION_NUM; i++) + { + if (tk->mm_space.pt_regions[i].region_inx >= 0) + { + ARM_MPU_SetRegion(tk->mm_space.pt_regions[i].rbar, + tk->mm_space.pt_regions[i].rasr); + } + else + { + ARM_MPU_ClrRegion(i); + } + } + mpu_enable(); +} diff --git a/mkrtos_knl/arch/armv7m/stm32f203/stm32f2xx_it.c b/mkrtos_knl/arch/armv7m/stm32f203/stm32f2xx_it.c index fb9f96742..20aef8bc7 100755 --- a/mkrtos_knl/arch/armv7m/stm32f203/stm32f2xx_it.c +++ b/mkrtos_knl/arch/armv7m/stm32f203/stm32f2xx_it.c @@ -52,6 +52,7 @@ */ void NMI_Handler(void) { + printk("%s\n", __FUNCTION__); } /** @@ -61,7 +62,8 @@ void NMI_Handler(void) */ void HardFault_Handler(void) { - printk("HardFault_Handler\n"); + printk("%s\n", __FUNCTION__); + /* Go to infinite loop when Hard Fault exception occurs */ while (1) { @@ -75,6 +77,7 @@ void HardFault_Handler(void) */ void MemManage_Handler(void) { + printk("%s\n", __FUNCTION__); /* Go to infinite loop when Memory Manage exception occurs */ while (1) { @@ -88,6 +91,8 @@ void MemManage_Handler(void) */ void BusFault_Handler(void) { + printk("%s\n", __FUNCTION__); + /* Go to infinite loop when Bus Fault exception occurs */ while (1) { @@ -101,7 +106,8 @@ void BusFault_Handler(void) */ void UsageFault_Handler(void) { - printk("UsageFault_Handler\n"); + printk("%s\n", __FUNCTION__); + /* Go to infinite loop when Usage Fault exception occurs */ while (1) { @@ -124,6 +130,7 @@ void UsageFault_Handler(void) */ void DebugMon_Handler(void) { + printk("%s\n", __FUNCTION__); } // /** diff --git a/mkrtos_knl/inc/knl/misc.h b/mkrtos_knl/inc/knl/misc.h new file mode 100644 index 000000000..4f8e5a26c --- /dev/null +++ b/mkrtos_knl/inc/knl/misc.h @@ -0,0 +1,6 @@ +#pragma once + +#include "mm_space.h" +#include "ram_limit.h" +#include "types.h" +void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size); \ No newline at end of file diff --git a/mkrtos_knl/inc/knl/mm.h b/mkrtos_knl/inc/knl/mm.h index cd992f5d9..ff7b67692 100755 --- a/mkrtos_knl/inc/knl/mm.h +++ b/mkrtos_knl/inc/knl/mm.h @@ -44,6 +44,4 @@ size_t mem_get_free_size(mem_t *_this); struct mem_heap *mem_get_free(mem_t *_this, struct mem_heap *next, int32_t hope_size, uint32_t *ret_addr); -#if MEM_TRACE void mem_trace(mem_t *_this); -#endif diff --git a/mkrtos_knl/inc/knl/mm_space.h b/mkrtos_knl/inc/knl/mm_space.h new file mode 100644 index 000000000..6d44954b5 --- /dev/null +++ b/mkrtos_knl/inc/knl/mm_space.h @@ -0,0 +1,34 @@ +#pragma once + +#include "types.h" + +#define REGION_NUM 8 //!< 默认为8 +typedef struct region_info +{ + umword_t start_addr; //!< 内存申请的开始地址 + umword_t block_start_addr; //!< 块申请的开始地址 + umword_t block_size; //!< 保护的块大小 + umword_t size; //!< 实际申请的内存大小 + umword_t rbar; //!< mpu保护寄存器信息 + umword_t rasr; //!< mpu保护寄存器信息 + int16_t region_inx; + uint8_t region; //!< 区域禁止信息 +} region_info_t; + +typedef struct mm_space +{ + region_info_t pt_regions[REGION_NUM]; +} mm_space_t; + +enum region_rights +{ + REGION_PRIV = 1, + REGION_RO = 2, + REGION_RWX = 3, +}; + +region_info_t *mm_space_alloc_pt_region(mm_space_t *m_space); +void mm_space_free_pt_region(mm_space_t *m_space, region_info_t *ri); + +void mm_space_init(mm_space_t *mm_space); +bool_t mm_space_add(mm_space_t *m_space, umword_t addr, umword_t size, uint8_t attrs); \ No newline at end of file diff --git a/mkrtos_knl/inc/knl/mm_wrap.h b/mkrtos_knl/inc/knl/mm_wrap.h index 330a288de..84f69e5e1 100755 --- a/mkrtos_knl/inc/knl/mm_wrap.h +++ b/mkrtos_knl/inc/knl/mm_wrap.h @@ -4,5 +4,8 @@ void *mm_limit_alloc(ram_limit_t *limit, size_t size); void mm_limit_free(ram_limit_t *limit, void *mem); +struct mem_heap *mm_get_free(struct mem_heap *next, + umword_t hope_size, umword_t *ret_addr); +void mm_trace(void); void *mm_limit_alloc_align(ram_limit_t *limit, size_t size, size_t align); void mm_limit_free_align(ram_limit_t *limit, void *mem, size_t size); diff --git a/mkrtos_knl/inc/knl/mpu.h b/mkrtos_knl/inc/knl/mpu.h new file mode 100644 index 000000000..7c3b481f7 --- /dev/null +++ b/mkrtos_knl/inc/knl/mpu.h @@ -0,0 +1,8 @@ +#pragma once +#include "mm_space.h" + +void mpu_disable(void); +void mpu_enable(void); +void mpu_calc_regs(region_info_t *region, umword_t addr, int ffs, + uint8_t attrs, uint8_t regions_bits); +void mpu_switch_to(void); \ No newline at end of file diff --git a/mkrtos_knl/inc/knl/obj_space.h b/mkrtos_knl/inc/knl/obj_space.h index a4ae06e17..538a6f8a7 100755 --- a/mkrtos_knl/inc/knl/obj_space.h +++ b/mkrtos_knl/inc/knl/obj_space.h @@ -47,72 +47,7 @@ typedef struct obj_space { obj_map_tab_t tab; } obj_space_t; - -static inline void obj_space_init(obj_space_t *obj_space, ram_limit_t *ram) -{ - for (int i = 0; i < OBJ_MAP_TAB_SIZE; i++) - { - obj_space->tab.tabs[i] = NULL; - } -} -static inline void obj_space_del(obj_space_t *obj_space, obj_addr_t inx) -{ - assert(obj_space); - if (inx > OBJ_MAP_MAX_ADDR) - { - return; - } - int tab_inx = inx / OBJ_MAP_ENTRY_SIZE; - int entry_inx = inx % OBJ_MAP_ENTRY_SIZE; - - if (!obj_space->tab.tabs[tab_inx]) - { - return; - } - obj_space->tab.tabs[tab_inx]->items[entry_inx].kobj.obj = NULL; -} -static inline obj_map_entry_t *obj_space_insert(obj_space_t *obj_space, ram_limit_t *ram, kobject_t *kobj, obj_addr_t inx) -{ - assert(obj_space); - assert(kobj); - if (inx > OBJ_MAP_MAX_ADDR) - { - return NULL; - } - int tab_inx = inx / OBJ_MAP_ENTRY_SIZE; - int entry_inx = inx % OBJ_MAP_ENTRY_SIZE; - - if (!obj_space->tab.tabs[tab_inx]) - { - obj_space->tab.tabs[tab_inx] = mm_limit_alloc(ram, sizeof(obj_map_item_t)); - if (!obj_space->tab.tabs[tab_inx]) - { - return NULL; - } - } - obj_map_entry_t *entry = &obj_space->tab.tabs[tab_inx]->items[entry_inx]; - - if (entry->kobj.obj == NULL) - { - slist_init(&entry->node); - } - entry->kobj.obj = kobj; - return entry; -} -static inline obj_map_entry_t *obj_space_lookup(obj_space_t *obj_space, obj_addr_t inx) -{ - assert(obj_space); - if (inx > OBJ_MAP_MAX_ADDR) - { - return NULL; - } - int tab_inx = inx / OBJ_MAP_ENTRY_SIZE; - int entry_inx = inx % OBJ_MAP_ENTRY_SIZE; - - if (!obj_space->tab.tabs[tab_inx]) - { - return NULL; - } - - return &obj_space->tab.tabs[tab_inx]->items[entry_inx]; -} \ No newline at end of file +void obj_space_init(obj_space_t *obj_space, ram_limit_t *ram); +void obj_space_del(obj_space_t *obj_space, obj_addr_t inx); +obj_map_entry_t *obj_space_insert(obj_space_t *obj_space, ram_limit_t *ram, kobject_t *kobj, obj_addr_t inx); +obj_map_entry_t *obj_space_lookup(obj_space_t *obj_space, obj_addr_t inx); \ No newline at end of file diff --git a/mkrtos_knl/inc/knl/task.h b/mkrtos_knl/inc/knl/task.h index d6c0bcff8..f228acfbf 100755 --- a/mkrtos_knl/inc/knl/task.h +++ b/mkrtos_knl/inc/knl/task.h @@ -6,11 +6,12 @@ #include "assert.h" #include "kobject.h" #include "obj_space.h" - +#include "mm_space.h" typedef struct task { kobject_t kobj; obj_space_t obj_space; + mm_space_t mm_space; } task_t; task_t *thread_get_current_task(void); diff --git a/mkrtos_knl/inc/knl/util.h b/mkrtos_knl/inc/knl/util.h index 3f93d6749..0151509a2 100755 --- a/mkrtos_knl/inc/knl/util.h +++ b/mkrtos_knl/inc/knl/util.h @@ -27,3 +27,5 @@ ((type *)(((umword_t)(ptr)) - ((umword_t)(&(((type *)0)->member))))) #define USED __attribute__((used)) + +int ffs(int x); diff --git a/mkrtos_knl/inc/lib/types.h b/mkrtos_knl/inc/lib/types.h index 17dd0fd8e..1b9f808b6 100755 --- a/mkrtos_knl/inc/lib/types.h +++ b/mkrtos_knl/inc/lib/types.h @@ -34,3 +34,5 @@ typedef umword_t uintptr_t; #ifndef TRUE #define TRUE (!(FALSE)) #endif + +#define WORD_BITS (sizeof(void *) * 8) diff --git a/mkrtos_knl/knl/misc.c b/mkrtos_knl/knl/misc.c new file mode 100644 index 000000000..dcd046762 --- /dev/null +++ b/mkrtos_knl/knl/misc.c @@ -0,0 +1,170 @@ + +#include "types.h" +#include "mm_wrap.h" +#include "mm.h" +#include "mm_space.h" +#include "util.h" +#include "mpu.h" +#include "printk.h" +static bool_t mpu_calc( + mm_space_t *ms, + umword_t mem_start_addr, + int size, + umword_t *ret_align_size, + umword_t *alloc_addr) +{ + int ffs_t_; + int ffs_t; + region_info_t *region[2]; + + region[0] = mm_space_alloc_pt_region(ms); + region[1] = mm_space_alloc_pt_region(ms); + + if (!region[0] || !region[1]) + { + if (!region[0]) + { + mm_space_free_pt_region(ms, region[0]); + } + if (!region[1]) + { + mm_space_free_pt_region(ms, region[1]); + } + return FALSE; + } + + ffs_t_ = ffs(size); + // if (!is_power_of_2(size)) { + // ffs_t_++; + // } + ffs_t = 1 << ffs_t_; + + int sub_region_t = ffs_t >> 3; + int align_sub_size = ALIGN(size, sub_region_t); + + umword_t mem_align_sub_mem_addr = ALIGN((umword_t)mem_start_addr, sub_region_t); + umword_t mem_align_up_mem_addr = ALIGN((umword_t)mem_start_addr, ffs_t); + umword_t mem_align_down_mem_addr = ALIGN_DOWN((umword_t)mem_start_addr, ffs_t); + + region[0]->start_addr = mem_align_sub_mem_addr; + region[0]->size = mem_align_up_mem_addr - mem_align_sub_mem_addr; + region[0]->block_size = ffs_t; + region[0]->block_start_addr = mem_align_down_mem_addr; + + if (alloc_addr) + { + *alloc_addr = region[0]->start_addr; + } + + region[0]->region = 0xff; + for (umword_t i = mem_align_down_mem_addr; i < mem_align_up_mem_addr; i += sub_region_t) + { + if (i < mem_align_sub_mem_addr) + { + region[0]->region |= 1 << ((i - mem_align_down_mem_addr) / sub_region_t); + } + else + { + region[0]->region &= ~(1 << ((i - mem_align_down_mem_addr) / sub_region_t)); + } + } + + region[1]->region = 0x00; + for (umword_t i = mem_align_up_mem_addr; i < mem_align_up_mem_addr + ffs_t; i += sub_region_t) + { + if (i < mem_align_sub_mem_addr + align_sub_size) + { + region[1]->region &= ~(1 << ((i - mem_align_up_mem_addr) / sub_region_t)); + } + else + { + region[1]->region |= (1 << ((i - mem_align_up_mem_addr) / sub_region_t)); + } + } + region[1]->start_addr = mem_align_up_mem_addr; + region[1]->size = (mem_align_sub_mem_addr + align_sub_size) - mem_align_up_mem_addr; + region[1]->block_size = ffs_t; + region[1]->block_start_addr = mem_align_up_mem_addr; + + *ret_align_size = sub_region_t; + +#if 1 + printk("st:0x%x re:0x%x sub:0x%x\n region:[", region[0]->block_start_addr, region[0]->region, sub_region_t); + for (int i = 0; i < 8; i++) + { + if (region[0]->region & (1 << i)) + { + printk("x"); + } + else + { + printk("o"); + } + } + printk("]\n"); + printk("st:0x%x re:0x%x sub:0x%x\n region:[", region[1]->block_start_addr, region[1]->region, sub_region_t); + for (int i = 0; i < 8; i++) + { + if (region[1]->region & (1 << i)) + { + printk("x"); + } + else + { + printk("o"); + } + } + printk("]\n"); +#endif + mpu_calc_regs(region[0], region[0]->block_start_addr, ffs_t_, REGION_RWX, region[0]->region); + mpu_calc_regs(region[1], region[1]->block_start_addr, ffs_t_, REGION_RWX, region[1]->region); + // region_i[2].rbar = ARM_MPU_RBAR(2, 0x20010000/*TODO:*/); + // region_i[2].rasr = ARM_MPU_RASR(0UL, ARM_MPU_AP_URO, 0UL + // , 0UL, 1UL, 1UL, 0x0/*TODO:*/, 16-1/*TODO:*/); + + // region_i[2].rbar = ARM_MPU_RBAR(2, 0x8000000 /*TODO:*/); + // region_i[2].rasr = ARM_MPU_RASR(0UL, ARM_MPU_AP_URO, 0UL, 0UL, 1UL, 1UL, 0x0 /*TODO:*/, ffs(1024 * 1024) - 1 /*TODO:*/); + return TRUE; +} + +void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size) +{ + umword_t pre_alloc_addr; + struct mem_heap *heap = NULL; + /*TODO:临界区保护*/ +again_alloc: + heap = mm_get_free(heap, ram_size, &pre_alloc_addr); + if (!heap) + { + printk("The system is low on memory.\n"); + mm_trace(); + return NULL; + } + + umword_t need_align; + umword_t alloc_addr; + + if (mpu_calc(ms, pre_alloc_addr, ram_size, + &need_align, &alloc_addr) == FALSE) + { + printk("The MPU area is exhausted."); + return NULL; + } + + void *ram = mm_limit_alloc_align(r_limit, ram_size, need_align); + if (!ram) + { + printk("The system is low on memory.\n"); + return NULL; + } + + //!< 申请的地址与预分配的地址不同 + if (ram != (void *)alloc_addr) + { + printk("Again.\n"); + mm_limit_free_align(r_limit, ram, need_align); + heap = heap->next; + goto again_alloc; + } + return ram; +} diff --git a/mkrtos_knl/knl/mm.c b/mkrtos_knl/knl/mm.c index c7dd45554..3a16e9109 100755 --- a/mkrtos_knl/knl/mm.c +++ b/mkrtos_knl/knl/mm.c @@ -350,19 +350,16 @@ struct mem_heap *mem_get_free(mem_t *_this, struct mem_heap *next, return NULL; } -#if MEM_TRACE void mem_trace(mem_t *_this) { struct mem_heap *mem; - kprint("start heap:0x%x.\n", _this->heap_start); - kprint("l heap:0x%x.\n", _this->l_heap); - kprint("end heap:0x%x.\n", _this->heap_end); + printk("start heap:0x%x.\n", _this->heap_start); + printk("l heap:0x%x.\n", _this->l_heap); + printk("end heap:0x%x.\n", _this->heap_end); for (mem = _this->heap_start; mem != _this->heap_end; mem = mem->next) { - knl_check_user_ram_access_exit(mem, sizeof(struct mem_heap), 1, _this->blong_user); - kprint("%d [0x%x-] %dB\n", mem->used, mem, mem->size); + printk("%d [0x%x-] %dB\n", mem->used, mem, mem->size); } } -#endif diff --git a/mkrtos_knl/knl/mm_space.c b/mkrtos_knl/knl/mm_space.c new file mode 100644 index 000000000..df79c185e --- /dev/null +++ b/mkrtos_knl/knl/mm_space.c @@ -0,0 +1,49 @@ + +#include "types.h" +#include "util.h" +#include "mm_space.h" +#include "mpu.h" +void mm_space_init(mm_space_t *mm_space) +{ + for (int i = 0; i < REGION_NUM; i++) + { + mm_space->pt_regions[i].region_inx = -1; + } +} +region_info_t *mm_space_alloc_pt_region(mm_space_t *m_space) +{ + for (int i = 0; i < 8; i++) + { + /*TODO:原子操作*/ + if (m_space->pt_regions[i].region_inx < 0) + { + m_space->pt_regions[i].region_inx = (int16_t)i; + return &m_space->pt_regions[i]; + } + } + return NULL; +} +void mm_space_free_pt_region(mm_space_t *m_space, region_info_t *ri) +{ + ri->region_inx = -1; +} + +bool_t mm_space_add(mm_space_t *m_space, + umword_t addr, + umword_t size, + uint8_t attrs + ) +{ + region_info_t *ri = mm_space_alloc_pt_region(m_space); + + if (!ri) + { + return FALSE; + } + mpu_calc_regs(ri, addr, ffs(size), attrs, 0); + return TRUE; +} +void mm_space_del(mm_space_t *m_space) +{ + /*TODO:*/ +} diff --git a/mkrtos_knl/knl/mm_wrap.c b/mkrtos_knl/knl/mm_wrap.c index 588c1fad4..c82da608a 100755 --- a/mkrtos_knl/knl/mm_wrap.c +++ b/mkrtos_knl/knl/mm_wrap.c @@ -28,6 +28,15 @@ void mm_limit_free(ram_limit_t *limit, void *mem) mem_free(mm_get_global(), (char *)mem - sizeof(size_t)); ram_limit_free(limit, size); } +struct mem_heap *mm_get_free(struct mem_heap *next, + umword_t hope_size, umword_t *ret_addr) +{ + return mem_get_free(mm_get_global(), next, hope_size, (uint32_t *)ret_addr); +} +void mm_trace(void) +{ + mem_trace(mm_get_global()); +} void *mm_limit_alloc_align(ram_limit_t *limit, size_t size, size_t align) { if (ram_limit_alloc(limit, size) == FALSE) diff --git a/mkrtos_knl/knl/obj_space.c b/mkrtos_knl/knl/obj_space.c index e69de29bb..183696bd0 100755 --- a/mkrtos_knl/knl/obj_space.c +++ b/mkrtos_knl/knl/obj_space.c @@ -0,0 +1,72 @@ + +#include "obj_space.h" +#include "types.h" + +void obj_space_init(obj_space_t *obj_space, ram_limit_t *ram) +{ + for (int i = 0; i < OBJ_MAP_TAB_SIZE; i++) + { + obj_space->tab.tabs[i] = NULL; + } +} +void obj_space_del(obj_space_t *obj_space, obj_addr_t inx) +{ + assert(obj_space); + if (inx > OBJ_MAP_MAX_ADDR) + { + return; + } + int tab_inx = inx / OBJ_MAP_ENTRY_SIZE; + int entry_inx = inx % OBJ_MAP_ENTRY_SIZE; + + if (!obj_space->tab.tabs[tab_inx]) + { + return; + } + obj_space->tab.tabs[tab_inx]->items[entry_inx].kobj.obj = NULL; +} +obj_map_entry_t *obj_space_insert(obj_space_t *obj_space, ram_limit_t *ram, kobject_t *kobj, obj_addr_t inx) +{ + assert(obj_space); + assert(kobj); + if (inx > OBJ_MAP_MAX_ADDR) + { + return NULL; + } + int tab_inx = inx / OBJ_MAP_ENTRY_SIZE; + int entry_inx = inx % OBJ_MAP_ENTRY_SIZE; + + if (!obj_space->tab.tabs[tab_inx]) + { + obj_space->tab.tabs[tab_inx] = mm_limit_alloc(ram, sizeof(obj_map_item_t)); + if (!obj_space->tab.tabs[tab_inx]) + { + return NULL; + } + } + obj_map_entry_t *entry = &obj_space->tab.tabs[tab_inx]->items[entry_inx]; + + if (entry->kobj.obj == NULL) + { + slist_init(&entry->node); + } + entry->kobj.obj = kobj; + return entry; +} +obj_map_entry_t *obj_space_lookup(obj_space_t *obj_space, obj_addr_t inx) +{ + assert(obj_space); + if (inx > OBJ_MAP_MAX_ADDR) + { + return NULL; + } + int tab_inx = inx / OBJ_MAP_ENTRY_SIZE; + int entry_inx = inx % OBJ_MAP_ENTRY_SIZE; + + if (!obj_space->tab.tabs[tab_inx]) + { + return NULL; + } + + return &obj_space->tab.tabs[tab_inx]->items[entry_inx]; +} diff --git a/mkrtos_knl/knl/task.c b/mkrtos_knl/knl/task.c index 4774e016e..d03e767fa 100755 --- a/mkrtos_knl/knl/task.c +++ b/mkrtos_knl/knl/task.c @@ -37,6 +37,7 @@ void task_init(task_t *task, ram_limit_t *ram) kobject_init(&task->kobj); obj_space_init(&task->obj_space, ram); + mm_space_init(&task->mm_space); } task_t *task_create(ram_limit_t *lim) diff --git a/mkrtos_knl/knl/thread_knl.c b/mkrtos_knl/knl/thread_knl.c index 55e5aa359..f66023c31 100755 --- a/mkrtos_knl/knl/thread_knl.c +++ b/mkrtos_knl/knl/thread_knl.c @@ -19,6 +19,7 @@ #include "app.h" #include "mm_wrap.h" #include "thread_armv7m.h" +#include "misc.h" static thread_t *knl_thread; static task_t knl_task; @@ -37,6 +38,7 @@ static void knl_init_1(void) thread_ready(cur_th, FALSE); } INIT_STAGE1(knl_init_1); + /** * 初始化init线程 * 初始化用户态任务 @@ -51,18 +53,18 @@ static void knl_init_2(void) assert(init_task); app_info_t *app = app_info_get((void *)(KNL_TEXT + INIT_OFFSET)); - void *ram = mm_limit_alloc_align(&root_factory_get()->limit, app->i.ram_size, 8); - + // 申请init的ram内存 + void *ram = mpu_ram_alloc(&init_task->mm_space, &root_factory_get()->limit, app->i.ram_size); if (!ram) { printk("申请init进程内存失败.\n"); assert(ram); } + mm_space_add(&init_task->mm_space, KNL_TEXT, 64*1024*1024, REGION_RO); void *sp_addr = (char *)ram + app->i.stack_offset - app->i.data_offset; void *sp_addr_top = (char *)sp_addr + app->i.stack_size; thread_bind(init_thread, &init_task->kobj); - // thread_set_exc_regs(init_thread, KNL_TEXT + INIT_OFFSET); thread_user_pf_set(init_thread, (void *)(KNL_TEXT + INIT_OFFSET), sp_addr_top, ram); assert(obj_map_root(&init_thread->kobj, &init_task->obj_space, &root_factory_get()->limit, THREAD_PROT)); assert(obj_map_root(&init_task->kobj, &init_task->obj_space, &root_factory_get()->limit, TASK_PROT)); diff --git a/mkrtos_knl/knl/util.c b/mkrtos_knl/knl/util.c new file mode 100644 index 000000000..8aa61d5ba --- /dev/null +++ b/mkrtos_knl/knl/util.c @@ -0,0 +1,13 @@ +#include "types.h" + +int ffs(int x) +{ + int ret; + + __asm__ volatile("clz\t%0, %1" + : "=r"(ret) + : "r"(x) + : "cc"); + ret = WORD_BITS - ret; + return ret; +} diff --git a/mkrtos_user/lib/mlibc/crt/crt1_init.c b/mkrtos_user/lib/mlibc/crt/crt1_init.c index 285b4286d..7384eab7f 100644 --- a/mkrtos_user/lib/mlibc/crt/crt1_init.c +++ b/mkrtos_user/lib/mlibc/crt/crt1_init.c @@ -11,9 +11,7 @@ weak void _fini(); int __libc_start_main_init(int (*main)(int,char **,char **), int argc, char **argv, void (*init_dummy)(), void(*fini_dummy)(), void(*ldso_dummy)()); -void _start_c_init(long *p) +void _start_c_init(void) { - int argc = p[0]; - char **argv = (void *)(p+1); - __libc_start_main_init(main, argc, argv, _init, _fini, 0); + __libc_start_main_init(main, NULL, NULL, _init, _fini, 0); } diff --git a/mkrtos_user/lib/mlibc/include/limits.h b/mkrtos_user/lib/mlibc/include/limits.h index 53a27b9de..a20f44340 100644 --- a/mkrtos_user/lib/mlibc/include/limits.h +++ b/mkrtos_user/lib/mlibc/include/limits.h @@ -84,7 +84,7 @@ #define LINE_MAX 4096 #define RE_DUP_MAX 255 -#define NL_ARGMAX 9 +#define NL_ARGMAX 6 #define NL_MSGMAX 32767 #define NL_SETMAX 255 #define NL_TEXTMAX 2048 diff --git a/mkrtos_user/lib/mlibc/src/stdio/vfprintf.c b/mkrtos_user/lib/mlibc/src/stdio/vfprintf.c index a712d80fb..3e8587fd2 100644 --- a/mkrtos_user/lib/mlibc/src/stdio/vfprintf.c +++ b/mkrtos_user/lib/mlibc/src/stdio/vfprintf.c @@ -125,8 +125,9 @@ static void pop_arg(union arg *arg, int type, va_list *ap) break; case UMAX: arg->i = va_arg(*ap, uintmax_t); break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t); break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *); - break; case DBL: arg->f = va_arg(*ap, double); - break; case LDBL: arg->f = va_arg(*ap, long double); + break; case LDBL:case DBL: arg->f = va_arg(*ap, double); + // break; + // case LDBL: arg->f = va_arg(*ap, long double); } } @@ -137,7 +138,7 @@ static void out(FILE *f, const char *s, size_t l) static void pad(FILE *f, char c, int w, int l, int fl) { - char pad[256]; + char pad[64]; if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return; l = w - l; memset(pad, c, l>sizeof pad ? sizeof pad : l); diff --git a/mkrtos_user/server/init/src/main.c b/mkrtos_user/server/init/src/main.c index deddc9f53..88f1649e9 100644 --- a/mkrtos_user/server/init/src/main.c +++ b/mkrtos_user/server/init/src/main.c @@ -14,6 +14,11 @@ void printf_test(void) printf("print test0.\n"); printf("print test1.\n"); printf("print test2.\n"); + float a=1.1; + float b=1.2; + float c=a+b; + c=c; + printf("%c %d %lf\n", 'a', 1234, 1.1); } int main(int argc, char *args[]) { diff --git a/setting.cmake b/setting.cmake index 05921cb38..5a8f14e47 100755 --- a/setting.cmake +++ b/setting.cmake @@ -1,6 +1,6 @@ set(CMAKE_TOOLCHAIN_PATH "/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/" CACHE STRING " " FORCE) set(CROSS_COMPILE ${CMAKE_TOOLCHAIN_PATH}arm-none-eabi- CACHE PATH "" FORCE) -set(GCC_LIB_PATH "/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/") +set(GCC_LIB_PATH "/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m") set(CMAKE_INSTALL_PATH "${CMAKE_BINARY_DIR}deploy" CACHE PATH "" FORCE) set(CMAKE_C_COMPILER "${CROSS_COMPILE}gcc" CACHE PATH "" FORCE) @@ -20,12 +20,14 @@ set(CMAKE_SIZE "${CROSS_COMPILE}size" CACHE PATH "" FORCE) # -mfloat-abi=soft -u _printf_float -set(CMAKE_C_FLAGS "-mcpu=cortex-m3 -mthumb -O0 -g -lc -lrdimon \ +set(CMAKE_C_FLAGS "-mcpu=cortex-m3 -mthumb -O0 -g -lc -lrdimon -mfloat-abi=soft \ -std=gnu11 -ffunction-sections -fdata-sections -fno-builtin \ --nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker --gc-sections -fno-stack-protector \ +-nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker \ +--gc-sections -fno-stack-protector \ " CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS "-mcpu=cortex-m3 -mthumb -mno-thumb-interwork -mfix-cortex-m3-ldrd -O0 -g -std=c++11 \ +set(CMAKE_CXX_FLAGS "-mcpu=cortex-m3 -mthumb -mno-thumb-interwork \ +-mfix-cortex-m3-ldrd -O0 -g -std=c++11 \ -fmessage-length=0 -Xlinker --print-map -Wall -W -fno-stack-protector -g \ -mfloat-abi=soft -lc -lrdimon -u _printf_float \ -ffunction-sections -fdata-sections -fno-builtin -nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker -Wl,-gc-sections \