增加mpu支持
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -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,
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,145 +1,47 @@
|
||||
// /*
|
||||
// * mpu.c
|
||||
// *
|
||||
// * Created on: zhangzheng
|
||||
// * Author: Administrator
|
||||
// */
|
||||
/*
|
||||
* mpu.c
|
||||
*
|
||||
* Created on: zhangzheng
|
||||
* Author: Administrator
|
||||
*/
|
||||
|
||||
// #include <type.h>
|
||||
// #include <stm32f2xx.h>
|
||||
// #include <mkrtos/sched.h>
|
||||
// #include <assert.h>
|
||||
// #include <mpu_armv7.h>
|
||||
// #include <mkrtos/mpu.h>
|
||||
#include "types.h"
|
||||
#include "assert.h"
|
||||
#include "mpu.h"
|
||||
#include <stm32f2xx.h>
|
||||
#include <mpu_armv7.h>
|
||||
#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();
|
||||
}
|
||||
|
||||
@@ -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__);
|
||||
}
|
||||
|
||||
// /**
|
||||
|
||||
6
mkrtos_knl/inc/knl/misc.h
Normal file
6
mkrtos_knl/inc/knl/misc.h
Normal file
@@ -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);
|
||||
@@ -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
|
||||
|
||||
34
mkrtos_knl/inc/knl/mm_space.h
Normal file
34
mkrtos_knl/inc/knl/mm_space.h
Normal file
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
8
mkrtos_knl/inc/knl/mpu.h
Normal file
8
mkrtos_knl/inc/knl/mpu.h
Normal file
@@ -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);
|
||||
@@ -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];
|
||||
}
|
||||
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);
|
||||
@@ -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);
|
||||
|
||||
@@ -27,3 +27,5 @@
|
||||
((type *)(((umword_t)(ptr)) - ((umword_t)(&(((type *)0)->member)))))
|
||||
|
||||
#define USED __attribute__((used))
|
||||
|
||||
int ffs(int x);
|
||||
|
||||
@@ -34,3 +34,5 @@ typedef umword_t uintptr_t;
|
||||
#ifndef TRUE
|
||||
#define TRUE (!(FALSE))
|
||||
#endif
|
||||
|
||||
#define WORD_BITS (sizeof(void *) * 8)
|
||||
|
||||
170
mkrtos_knl/knl/misc.c
Normal file
170
mkrtos_knl/knl/misc.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
49
mkrtos_knl/knl/mm_space.c
Normal file
49
mkrtos_knl/knl/mm_space.c
Normal file
@@ -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:*/
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
13
mkrtos_knl/knl/util.c
Normal file
13
mkrtos_knl/knl/util.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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[])
|
||||
{
|
||||
|
||||
@@ -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 \
|
||||
|
||||
Reference in New Issue
Block a user