log对象支持从读取控制台数据

This commit is contained in:
zhangzheng
2023-09-15 00:07:58 +08:00
parent 8beb51f305
commit 4cdd72c0d7
34 changed files with 676 additions and 87 deletions

View File

@@ -129,7 +129,10 @@
"pthread.h": "c",
"*.in": "cpp",
"syscall_backend.h": "c",
"misc_backend.h": "c"
"misc_backend.h": "c",
"queue.h": "c",
"irq.h": "c",
"irq_sender.h": "c"
},
"cortex-debug.showRTOS": false,
}

View File

@@ -15,6 +15,7 @@
#include "thread.h"
#include "stm32f2xx_conf.h"
#include "mpu.h"
#include "core_cm3.h"
__ALIGN__(THREAD_BLOCK_SIZE)
static uint8_t thread_knl_stack[THREAD_BLOCK_SIZE] = {0};
void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE;
@@ -38,6 +39,16 @@ void sys_startup(void)
// 初始化systick时钟
SysTick_Config(SystemCoreClock / SYS_SCHE_HZ);
}
void arch_disable_irq(int inx)
{
NVIC_DisableIRQ(inx);
}
void arch_enable_irq(int inx)
{
NVIC_EnableIRQ(inx);
}
void arch_init(void)
{
SystemInit();

View File

@@ -44,6 +44,16 @@ static inline umword_t arch_get_sp(void)
:);
return ret;
}
static inline umword_t arch_get_isr_no(void)
{
umword_t num;
__asm__ __volatile__(
"mrs %0,IPSR"
: "=r"(num)
:
:);
return num;
}
static inline void arch_set_knl_sp(umword_t sp)
{
write_sysreg(sp, msp);
@@ -60,6 +70,9 @@ static inline umword_t arch_get_user_sp(void)
{
return read_sysreg(psp);
}
void arch_disable_irq(int inx);
void arch_enable_irq(int inx);
#define sti() \
do \
{ \

View File

@@ -3,6 +3,8 @@
#include "types.h"
#include "uart/uart.h"
#include "init.h"
#include "queue.h"
#include <irq.h>
#define CR3_CLEAR_MASK ((uint16_t)(USART_CR3_RTSE | USART_CR3_CTSE))
static void uart_set_word_len(USART_TypeDef *USARTx, uint16_t len)
@@ -124,15 +126,35 @@ static void uart_hardware_flow_rts(USART_TypeDef *USARTx, uint16_t flow)
}
static uart_t uart = {
.baud = 115200};
uart_t *uart_get_global(void)
{
return &uart;
}
#define QUEUE_LEN 129
static queue_t queue;
static uint8_t queue_data[QUEUE_LEN];
void uart_tigger(irq_entry_t *irq)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
// 清除中断标志位
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
q_enqueue(&queue, USART_ReceiveData(USART1));
if (irq->irq->wait_thread && thread_get_status(irq->irq->wait_thread) == THREAD_SUSPEND)
{
thread_ready(irq->irq->wait_thread, TRUE);
}
}
}
void uart_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
q_init(&queue, queue_data, QUEUE_LEN);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
@@ -167,6 +189,7 @@ void uart_init(void)
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
INIT_HIGH_HAD(uart_init);
@@ -186,5 +209,19 @@ void uart_putc(uart_t *uart, int data)
}
int uart_getc(uart_t *uart)
{
uint8_t e;
umword_t status;
status = cpulock_lock();
if (q_dequeue(&queue, &e) >= 0)
{
cpulock_set(status);
return e;
}
cpulock_set(status);
return -1;
}
int uart_get_len(uart_t *uart)
{
return q_queue_len(&queue);
}

View File

@@ -2,6 +2,7 @@
#pragma once
#include "types.h"
#include "irq.h"
typedef struct uart
{
@@ -16,3 +17,4 @@ uart_t *uart_get_global(void);
void uart_set(uart_t *uart);
void uart_putc(uart_t *uart, int data);
int uart_getc(uart_t *uart);
void uart_tigger(irq_entry_t *irq);

View File

@@ -0,0 +1,13 @@
#pragma once
#include <types.h>
#include <irq_sender.h>
#define IRQ_INVALID_NO ((umword_t)(-1))
#define IRQ_REG_TAB_SIZE 80
#define USER_ISR_START_NO 16
bool_t irq_check_usability(int inx);
void irq_alloc(int inx, irq_sender_t *irq, void (*irq_tigger_func)(irq_entry_t *irq));
void irq_free(int inx);
irq_entry_t *irq_get(int inx);

View File

@@ -0,0 +1,28 @@
#pragma once
#include "types.h"
#include <kobject.h>
#include <ref.h>
#include <thread.h>
struct irq_sender;
typedef struct irq_sender irq_sender_t;
struct irq_entry;
typedef struct irq_entry irq_entry_t;
typedef struct irq_entry
{
irq_sender_t *irq;
void (*irq_tigger_func)(irq_entry_t *irq);
} irq_entry_t;
typedef struct irq_sender
{
kobject_t kobj;
umword_t irq_id; //!< 绑定的中断号
ref_counter_t ref;
thread_t *wait_thread; //!< 等待中断的线程
} irq_sender_t;
void irq_sender_init(irq_sender_t *irq);
int irq_sender_wait(irq_sender_t *irq, thread_t *th);
void irq_sender_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f);

View File

@@ -11,7 +11,4 @@
#include "types.h"
#include "kobject.h"
typedef struct log
{
kobject_t kobj;
} log_t;

View File

@@ -1,14 +1,17 @@
/*
* @Author: zhangzheng 1358745329@qq.com
* @Date: 2023-08-14 09:47:54
* @LastEditors: zhangzheng 1358745329@qq.com
* @LastEditTime: 2023-08-14 13:06:46
* @FilePath: /mkrtos-real/mkrtos_knl/inc/knl/printk.h
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
/**
* @file printk.h
* @author zhagnzheng (1358745329@qq.com)
* @brief
* @version 0.1
* @date 2023-09-14
*
* @copyright Copyright (c) 2023
*
*/
#pragma once
#include "types.h"
void putc(int c);
int getc(void);
void printk(const char *fmt, ...);

View File

@@ -18,9 +18,10 @@
#define IPC_PROT 5
#define MM_PROT 6
#define SYS_PROT 7
#define IRQ_PROT 8
#define FACTORY_PORT_START FACTORY_PROT
#define FACTORY_FUNC_MAX (SYS_PROT + 1)
#define FACTORY_FUNC_MAX (IRQ_PROT + 1)
#define FACTORY_PORT_END FACTORY_FUNC_MAX
typedef struct msg_tag

View File

@@ -1,10 +1,12 @@
/*
* @Author: zhangzheng 1358745329@qq.com
* @Date: 2023-08-14 09:47:54
* @LastEditors: zhangzheng 1358745329@qq.com
* @LastEditTime: 2023-08-18 16:21:48
* @FilePath: /mkrtos-real/mkrtos_knl/inc/knl/thread.h
* @Description: 线程管理相关
/**
* @file thread.h
* @author zhangzheng (1358745329@qq.com)
* @brief
* @version 0.1
* @date 2023-09-14
*
* @copyright Copyright (c) 2023
*
*/
#pragma once

View File

@@ -0,0 +1,17 @@
#pragma once
#include "types.h"
typedef struct queue
{
uint8_t *m;
int front;
int rear;
int size;
} queue_t;
void q_init(queue_t *q, uint8_t *data, int size);
int q_empty(queue_t *q);
int q_enqueue(queue_t *q, uint8_t e);
int q_dequeue(queue_t *q, uint8_t *e);
int q_queue_len(queue_t *q);

View File

@@ -10,4 +10,5 @@ target_include_directories(
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/lib
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/inc
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/drv
)

View File

@@ -15,7 +15,7 @@
#include "mm_man.h"
#include "ipc.h"
static mem_t global_mem; //!< 全局内存管理块
static uint8_t mem_block[960 * 1024]; //!< 内核内存分配堆
static uint8_t mem_block[960 * 1024]; //!< 内核内存分配堆 TODO:自动识别大小或者从bootstrap中读取
static kobject_t *kobj_ls[FACTORY_FUNC_MAX]; //!< 全局静态内核对象
void global_reg_kobj(kobject_t *kobj, int inx)
@@ -42,7 +42,6 @@ static void mem_sys_init(void)
log_dump();
mm_man_dump();
sys_dump();
// ipc_dump();
mem_init(&global_mem);
mem_heap_add(mm_get_global(), mem_block, sizeof(mem_block));
}

View File

@@ -28,7 +28,7 @@ typedef struct ipc_wait_item
typedef struct ipc
{
kobject_t kobj; //!< 内核对象
spinlock_t lock; //!< 操作的锁TODO: 使用内核对象锁
spinlock_t lock; //!< 操作的锁 TODO: 使用内核对象锁
slist_head_t wait_send; //!< 发送等待队列
slist_head_t recv_send; //!< 发送等待队列
slist_head_t node; //!< 超时检查链表
@@ -40,11 +40,11 @@ typedef struct ipc
enum ipc_op
{
IPC_CALL, //!< 客户端CALL操作
IPC_WAIT, //!< 服务端等待接收信息
IPC_REPLY, //!< 服务端回复信息
IPC_BIND, //!< 绑定服务端线程
IPC_UNBIND, //!< 解除绑定
IPC_CALL, //!< 客户端CALL操作
IPC_WAIT, //!< 服务端等待接收信息
IPC_REPLY, //!< 服务端回复信息
IPC_BIND, //!< 绑定服务端线程
IPC_UNBIND, //!< 解除绑定
};
static void wake_up_th(ipc_t *ipc);
static slist_head_t wait_list;

View File

@@ -1,4 +1,57 @@
#include <arch.h>
#include <types.h>
#include <kobject.h>
#include <thread.h>
#include <ref.h>
#include <init.h>
#include <mm_wrap.h>
#include <factory.h>
#include <irq.h>
/*TODO:换成更节省内存的方式*/
static irq_entry_t irqs[IRQ_REG_TAB_SIZE] = {0};
static void irq_tigger(irq_entry_t *irq);
bool_t irq_check_usability(int inx)
{
if (inx >= IRQ_REG_TAB_SIZE)
{
return FALSE;
}
return irqs[inx].irq_tigger_func == NULL;
}
void irq_alloc(int inx, irq_sender_t *irq, void (*irq_tigger_func)(irq_entry_t *irq))
{
assert(irqs[inx].irq_tigger_func == NULL);
irqs[inx].irq = irq;
irqs[inx].irq_tigger_func = irq_tigger_func;
}
void irq_free(int inx)
{
assert(inx < IRQ_REG_TAB_SIZE);
irqs[inx].irq_tigger_func = NULL;
}
irq_entry_t *irq_get(int inx)
{
assert(inx < IRQ_REG_TAB_SIZE);
return &irqs[inx];
}
/**
* @brief 中断的入口函数
*
*/
void entry_handler(void)
{
umword_t isr_no = arch_get_isr_no();
isr_no -= USER_ISR_START_NO;
if (!irq_check_usability(isr_no))
{
if (irqs[isr_no].irq_tigger_func)
{
irqs[isr_no].irq_tigger_func(&irqs[isr_no]);
}
}
}

150
mkrtos_knl/knl/irq_sender.c Normal file
View File

@@ -0,0 +1,150 @@
#include <arch.h>
#include <types.h>
#include <kobject.h>
#include <thread.h>
#include <ref.h>
#include <init.h>
#include <mm_wrap.h>
#include <factory.h>
#include <irq.h>
enum irq_sender_op
{
BIND_IRQ, //!< 绑定一个中断号
UNBIND_IRQ, //!< 解除绑定
WAIT_IRQ, //!< 等待中断触发
ACK_IRQ, //!< 中断确认
};
/**
* @brief irq_sender的默认中断触发函数
*
* @param irq
*/
static void irq_tigger(irq_entry_t *irq)
{
if (irq->irq->wait_thread && thread_get_status(irq->irq->wait_thread) == THREAD_SUSPEND)
{
arch_disable_irq(irq->irq->irq_id);
thread_ready(irq->irq->wait_thread, TRUE);
}
}
int irq_sender_wait(irq_sender_t *irq, thread_t *th)
{
// TODO:临界保护
if (!irq->wait_thread)
{
irq->wait_thread = th;
ref_counter_inc(&irq->wait_thread->ref); //! 线程引用计数+1
thread_suspend(irq->wait_thread);
ref_counter_dec(&irq->wait_thread->ref); //! 线程引用计数+1
irq->wait_thread = NULL;
return 0;
}
else
{
return -EACCES;
}
}
void irq_sender_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f)
{
assert(kobj);
assert(f);
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL);
thread_t *th = thread_get_current();
irq_sender_t *irq = container_of(kobj, irq_sender_t, kobj);
if (sys_p.prot != IPC_PROT)
{
f->r[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw;
return;
}
switch (sys_p.op)
{
case BIND_IRQ:
{
umword_t irq_no = f->r[1];
if (irq_check_usability(irq_no))
{
irq->irq_id = irq_no;
irq_alloc(irq_no, irq, irq_tigger);
ref_counter_inc(&irq->ref);
tag = msg_tag_init4(0, 0, 0, 0);
}
else
{
tag = msg_tag_init4(0, 0, 0, -EACCES);
}
}
break;
case UNBIND_IRQ:
{
umword_t irq_no = f->r[1];
if (!irq_check_usability(irq_no) && irq_get(irq_no)->irq == irq)
{
irq_free(irq_no);
ref_counter_dec(&irq->ref);
tag = msg_tag_init4(0, 0, 0, 0);
}
else
{
tag = msg_tag_init4(0, 0, 0, -EACCES);
}
}
break;
case WAIT_IRQ:
{
int ret = irq_sender_wait(irq, th);
msg_tag_init4(0, 0, 0, ret);
}
break;
case ACK_IRQ:
{
arch_enable_irq(irq->irq_id);
}
break;
default:
break;
}
f->r[0] = tag.raw;
}
void irq_sender_init(irq_sender_t *irq)
{
kobject_init(&irq->kobj);
ref_counter_init(&irq->ref);
ref_counter_inc(&irq->ref);
irq->kobj.invoke_func = irq_sender_syscall;
irq->irq_id = IRQ_INVALID_NO;
}
static irq_sender_t *irq_create(ram_limit_t *lim)
{
irq_sender_t *irq = mm_limit_alloc(lim, sizeof(irq_sender_t));
if (!irq)
{
return NULL;
}
irq_sender_init(irq);
return irq;
}
static kobject_t *irq_create_func(ram_limit_t *lim, umword_t arg0, umword_t arg1,
umword_t arg2, umword_t arg3)
{
irq_sender_t *irq = irq_create(lim);
if (!irq)
{
return NULL;
}
return &irq->kobj;
}
/**
* @brief 工厂注册函数
*
*/
static void irq_factory_register(void)
{
factory_register(irq_create_func, IRQ_PROT);
}
INIT_KOBJ(irq_factory_register);

View File

@@ -1,10 +1,12 @@
/*
* @Author: zhangzheng 1358745329@qq.com
* @Date: 2023-08-14 09:47:54
* @LastEditors: zhangzheng 1358745329@qq.com
* @LastEditTime: 2023-08-14 13:10:35
* @FilePath: /mkrtos-real/mkrtos_knl/knl/log.c
* @Description: 内核的信息输出对象,用户态使用该对象进行数据输出。
/**
* @file log.c
* @author zhangzheng (1358745329@qq.com)
* @brief
* @version 0.1
* @date 2023-09-14
*
* @copyright Copyright (c) 2023
*
*/
#include "log.h"
@@ -15,6 +17,12 @@
#include "printk.h"
#include "types.h"
#include "util.h"
#include "irq_sender.h"
#include "uart/uart.h"
typedef struct log
{
irq_sender_t kobj;
} log_t;
static log_t log;
enum log_op
@@ -25,11 +33,18 @@ enum log_op
};
static void log_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f);
static void log_trigger(irq_entry_t *irq)
{
uart_tigger(irq);
}
static void log_reg(void)
{
kobject_init(&log.kobj);
log.kobj.invoke_func = log_syscall;
global_reg_kobj(&log.kobj, LOG_PROT);
// kobject_init(&log.kobj);
irq_sender_init(&log.kobj);
log.kobj.kobj.invoke_func = log_syscall;
global_reg_kobj(&log.kobj.kobj, LOG_PROT);
irq_alloc(37 /*USART1_IRQn*/, &log.kobj, log_trigger);
}
INIT_KOBJ(log_reg);
static msg_tag_t log_write_data(log_t *log, const char *data, int len)
@@ -40,33 +55,68 @@ static msg_tag_t log_write_data(log_t *log, const char *data, int len)
}
return msg_tag_init(0);
}
static int log_read_data(log_t *log, uint8_t *data, int len)
{
for (int i = 0; i < len; i++)
{
again:;
int c = getc();
if (c < 0 && i == 0)
{
int ret = irq_sender_wait(&log->kobj, thread_get_current());
if (ret < 0)
{
return ret;
}
goto again;
}
else if (c < 0)
{
return i;
}
data[i] = (uint8_t)c;
}
return len;
}
static void
log_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f)
{
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL);
if (sys_p.prot != LOG_PROT)
if (sys_p.prot == LOG_PROT)
{
switch (sys_p.op)
{
case WRITE_DATA:
tag = log_write_data(
(log_t *)kobj, (const char *)(&f->r[1]),
MIN(in_tag.msg_buf_len * WORD_BYTES, WORD_BYTES * 5));
break;
case READ_DATA:
{
int ret = log_read_data((log_t *)kobj, (uint8_t *)(&f->r[1]), MIN(f->r[1], WORD_BYTES * 5));
tag = msg_tag_init4(0, 0, 0, ret);
}
break;
case SET_FLAGS:
printk("don't support set flags.\n");
break;
default:
tag = msg_tag_init4(0, 0, 0, -ENOSYS);
break;
}
f->r[0] = tag.raw;
}
else if (sys_p.prot == IRQ_PROT)
{
irq_sender_syscall(kobj, sys_p, in_tag, f);
}
else
{
f->r[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw;
return;
}
switch (sys_p.op)
{
case WRITE_DATA:
tag = log_write_data(
(log_t *)kobj, (const char *)(&f->r[1]),
MIN(in_tag.msg_buf_len * WORD_BYTES, WORD_BYTES * 5));
break;
case READ_DATA:
printk("don't support read data.\n");
break;
case SET_FLAGS:
printk("don't support set flags.\n");
break;
default:
tag = msg_tag_init4(0, 0, 0, -ENOSYS);
break;
}
f->r[0] = tag.raw;
return;
}

View File

@@ -1,15 +1,18 @@
/*
* @Author: zhangzheng 1358745329@qq.com
* @Date: 2023-08-14 09:47:54
* @LastEditors: zhangzheng 1358745329@qq.com
* @LastEditTime: 2023-08-14 13:11:18
* @FilePath: /mkrtos-real/mkrtos_knl/knl/printk.c
* @Description: 内核信息输出,内核内使用
/**
* @file printk.c
* @author zhangzheng (1358745329@qq.com)
* @brief
* @version 0.1
* @date 2023-09-14
*
* @copyright Copyright (c) 2023
*
*/
#include "printk.h"
#include "stdarg.h"
#include "xprintf.h"
#include "spinlock.h"
#include "uart/uart.h"
static spinlock_t lock;
static char print_cache[128];
@@ -35,6 +38,10 @@ void putc(int c)
{
xputc(c);
}
int getc(void)
{
return uart_getc(uart_get_global());
}
/**
* @brief 输出数据
*

View File

@@ -37,7 +37,7 @@ end:;
addr_t u_sp = arch_get_user_sp();
pf_s_t *pf_a = (pf_s_t *)u_sp;
// pf_a->rg0[0] = tag.raw;
pf_a->rg0[0] = entry.r[0];
pf_a->rg0[1] = entry.r[1];
pf_a->rg0[2] = entry.r[2];
pf_a->rg0[3] = entry.r[3];

View File

@@ -213,6 +213,7 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t
stack_bottom = (umword_t)(cur_th->msg.msg);
}
thread_set_exc_regs(tag_th, f->r[1], f->r[2], f->r[3], stack_bottom);
tag = msg_tag_init4(0, 0, 0, 0);
}
break;
case MSG_BUG_SET:
@@ -242,6 +243,7 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t
tag_th->sche.prio = (f->r[1] >= PRIO_MAX ? PRIO_MAX - 1 : f->r[1]);
thread_ready(tag_th, TRUE);
}
tag = msg_tag_init4(0, 0, 0, 0);
}
break;
case BIND_TASK:
@@ -253,6 +255,7 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t
return;
}
thread_bind(tag_th, task_kobj);
tag = msg_tag_init4(0, 0, 0, 0);
printk("thread bind to %d\n", f->r[7], f->r[1]);
}
break;

View File

@@ -9,4 +9,6 @@ target_include_directories(
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/lib
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/drv
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/inc
)

47
mkrtos_knl/lib/queue.c Normal file
View File

@@ -0,0 +1,47 @@
#include "types.h"
#include "queue.h"
#include <assert.h>
void q_init(queue_t *q, uint8_t *data, int size)
{
q->front = 0;
q->rear = 0;
q->m = data;
q->size = size;
}
int q_empty(queue_t *q)
{
assert(q);
if (q->front == q->rear)
{
return 1;
}
else
{
return 0;
}
}
int q_enqueue(queue_t *q, uint8_t e)
{
if (((q->rear + 1) % q->size) == q->front)
{
return -1;
}
q->m[q->rear] = e;
q->rear = (q->rear + 1) % q->size;
return 0;
}
int q_dequeue(queue_t *q, uint8_t *e)
{
if (q->front == q->rear)
{
return -1;
}
*e = q->m[q->front];
q->front = (q->front + 1) % q->size;
return 0;
}
int q_queue_len(queue_t *q)
{
return (q->rear - q->front + q->size) % q->size;
}

View File

@@ -38,3 +38,4 @@
long syscall_backend(long sys_inx, ...);
umword_t be_mmap2(va_list ap);
umword_t be_munmap(va_list ap);

View File

@@ -4,21 +4,27 @@
#include "u_ipc.h"
#include "u_mm.h"
#include "u_app.h"
#include "u_log.h"
#include <pthread_impl.h>
#include <assert.h>
static pthread_spinlock_t lock;
extern void *app_start_addr;
// extern char __heap_start__[];
extern umword_t __heap_size__;
// extern void *_start_;
static umword_t mm_bitemp[32 /*TODO:自动分配,或者静态划分*/];
// extern char heap[];
static void *mm_page_alloc(void)
static void *mm_page_alloc(int page_nr)
{
// pthread_spin_lock(&lock);
int cnt = 0;
mword_t find_inx = -1;
app_info_t *info = app_info_get(app_start_addr);
assert(info);
void *heap_addr = RAM_BASE() + info->i.heap_offset - info->i.data_offset;
size_t max_page_nr = (info->i.heap_size) / 512;
printf("heap is 0x%x, max page nr is %d.\n", heap_addr, max_page_nr);
for (umword_t i = 0; i < max_page_nr; i++)
size_t max_page_nr = (info->i.heap_size) / PAGE_SIZE;
if (max_page_nr > sizeof(mm_bitemp) * WORD_BITS)
{
ulog_write_str(LOG_PROT, "mm bitmap is to small.\n");
}
// printf("heap is 0x%x, max page nr is %d.\n", heap_addr, max_page_nr);
pthread_spin_lock(&lock);
for (umword_t i = 0; i < ROUND_UP(max_page_nr, WORD_BITS); i++)
{
if (mm_bitemp[i] != (umword_t)(-1))
{
@@ -27,19 +33,56 @@ static void *mm_page_alloc(void)
if (MK_GET_BIT(mm_bitemp[i], j) == 0)
{
// 找到空闲的
umword_t find_inx = i * WORD_BITS + j;
MK_SET_BIT(mm_bitemp[i], j);
// pthread_spin_unlock(&lock);
return find_inx * PAGE_SIZE + (char *)heap_addr;
if (find_inx == -1)
{
find_inx = i * WORD_BITS + j;
}
cnt++;
if (find_inx + cnt >= max_page_nr)
{
pthread_spin_unlock(&lock);
return NULL;
}
if (cnt >= page_nr)
{
for (int m = find_inx; m < find_inx + cnt; m++)
{
MK_SET_BIT(mm_bitemp[m / WORD_BITS], m % WORD_BITS);
}
pthread_spin_unlock(&lock);
printf("st_inx:%d, cnt:%d\n", find_inx, cnt);
return find_inx * PAGE_SIZE + (char *)heap_addr;
}
}
else
{
cnt = 0;
find_inx = -1;
}
}
}
}
// pthread_spin_unlock(&lock);
pthread_spin_unlock(&lock);
return NULL;
}
static void mm_page_free(int st, int nr)
{
app_info_t *info = app_info_get(app_start_addr);
assert(info);
void *heap_addr = RAM_BASE() + info->i.heap_offset - info->i.data_offset;
size_t max_page_nr = (info->i.heap_size) / PAGE_SIZE;
pthread_spin_lock(&lock);
for (int i = st; (i < st + nr) && (i < max_page_nr); i++)
{
MK_CLR_BIT(mm_bitemp[i / WORD_BITS], i % WORD_BITS);
}
pthread_spin_unlock(&lock);
}
static int sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_t _offset, umword_t *addr)
{
if (fd >= 0)
@@ -47,7 +90,7 @@ static int sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_t
return -ENOSYS;
}
len = ALIGN(len, PAGE_SIZE);
*addr = (umword_t)mm_page_alloc();
*addr = (umword_t)mm_page_alloc(len / PAGE_SIZE);
return 0;
}
@@ -72,3 +115,18 @@ umword_t be_mmap2(va_list ap)
}
return addr;
}
umword_t be_munmap(va_list ap)
{
void *start;
size_t len;
ARG_2_BE(ap, len, size_t, start, void *);
app_info_t *info = app_info_get(app_start_addr);
assert(info);
void *heap_addr = RAM_BASE() + info->i.heap_offset - info->i.data_offset;
len = ALIGN(len, PAGE_SIZE);
printf("munmap 0x%x, 0x%x.\n", start, len);
mm_page_free(((umword_t)(start) - (umword_t)heap_addr) / PAGE_SIZE, len / PAGE_SIZE);
return 0;
}

View File

@@ -8,6 +8,7 @@ typedef long (*sys_call_func)(va_list ap);
static const sys_call_func sys_call_list[] = {
// TODO: add syscall func pointer.
[SYS_munmap] = be_munmap,
[SYS_mmap2] = be_mmap2,
[SYS_read] = sys_be_read,
[SYS_write] = sys_be_read,

View File

@@ -1,5 +1,7 @@
#include "u_types.h"
#define APP_MAGIC "MKRTOS."
typedef struct app_info
{
const char d[32];
@@ -28,5 +30,14 @@ typedef struct app_info
static inline app_info_t *app_info_get(void *addr)
{
return (app_info_t *)addr;
app_info_t *app = (app_info_t *)addr;
const char *magic = APP_MAGIC;
for (int i = 0; i < sizeof(app->magic) - 1; i++)
{
if (app->magic[i] != magic[i])
{
return NULL;
}
}
return app;
}

View File

@@ -5,3 +5,4 @@
#define ULOG_RW_MAX_BYTES (WORD_BYTES * 5)
void ulog_write_bytes(obj_handler_t obj_inx, const uint8_t *data, umword_t len);
void ulog_write_str(obj_handler_t obj_inx, const char *str);
int ulog_read_bytes(obj_handler_t obj_inx, uint8_t *data, umword_t len);

View File

@@ -9,6 +9,7 @@
#define IPC_PROT 5
#define MM_PROT 6
#define SYS_PROT 7
#define IRQ_PROT 8
#define THREAD_MAIN THREAD_PROT
#define TASK_THIS TASK_PROT

View File

@@ -11,6 +11,47 @@ enum log_op
READ_DATA,
SET_FLAGS
};
static msg_tag_t ulog_read_bytes_raw(obj_handler_t obj_inx, umword_t data[5], int len)
{
register volatile umword_t r0 asm("r0");
register volatile umword_t r1 asm("r1");
register volatile umword_t r2 asm("r2");
register volatile umword_t r3 asm("r3");
register volatile umword_t r4 asm("r4");
register volatile umword_t r5 asm("r5");
syscall(syscall_prot_create(READ_DATA, LOG_PROT, obj_inx),
msg_tag_init4(0, 0, 0, 0).raw,
len,
0,
0,
0,
0);
msg_tag_t tag = msg_tag_init(r0);
{
((umword_t *)data)[0] = r1;
((umword_t *)data)[1] = r2;
((umword_t *)data)[2] = r3;
((umword_t *)data)[3] = r4;
((umword_t *)data)[4] = r5;
}
return tag;
}
int ulog_read_bytes(obj_handler_t obj_inx, uint8_t *data, umword_t len)
{
umword_t buffer[5];
msg_tag_t tag = ulog_read_bytes_raw(obj_inx, buffer, len);
if (msg_tag_get_val(tag) > 0)
{
for (int i = 0; i < msg_tag_get_val(tag); i++)
{
data[i] = ((uint8_t *)buffer)[i];
}
}
return msg_tag_get_val(tag);
}
void ulog_write_bytes(obj_handler_t obj_inx, const uint8_t *data, umword_t len)
{
uint8_t write_buf[ULOG_RW_MAX_BYTES] = {0};
@@ -38,6 +79,10 @@ void ulog_write_bytes(obj_handler_t obj_inx, const uint8_t *data, umword_t len)
{
return;
}
for (int i = 0; i < ULOG_RW_MAX_BYTES; i++)
{
write_buf[i] = 0;
}
}
}

View File

@@ -5,8 +5,9 @@
#include "u_task.h"
#include "u_hd_man.h"
#include <pthread.h>
#define HANDLER_START_INX 10
#define HANDLER_MAX_NR 64
#define HANDLER_START_INX 10 //!< fd开始的值前10个内核保留
#define HANDLER_MAX_NR 64 //!< 单个task最大支持的hd数量
static umword_t bitmap_handler_alloc[HANDLER_MAX_NR / WORD_BYTES];
static pthread_spinlock_t lock;
@@ -39,6 +40,11 @@ void handler_free(obj_handler_t hd_inx)
hd_inx -= HANDLER_START_INX;
umword_t word_offset = hd_inx / WORD_BITS;
umword_t bits_offset = hd_inx % WORD_BITS;
if (word_offset >= (HANDLER_MAX_NR / WORD_BYTES))
{
return;
}
pthread_spin_lock(&lock);
MK_CLR_BIT(bitmap_handler_alloc[word_offset], bits_offset);
pthread_spin_unlock(&lock);

View File

@@ -13,8 +13,18 @@
extern void futex_init(void);
int main(int argc, char *args[])
{
uint8_t data[10];
// futex_init();
ulog_write_str(LOG_PROT, "init..\n");
// while (1)
// {
// int len = ulog_read_bytes(LOG_PROT, data, sizeof(data) - 1);
// if (len > 0)
// {
// data[len] = 0;
// printf("%s\n", data);
// }
// }
#if 0
mm_test();
ulog_test();

View File

@@ -13,5 +13,5 @@
#define STACK_ATTR
#endif
__attribute__((used)) HEAP_ATTR char heap[HEAP_SIZE];
__attribute__((used)) HEAP_ATTR static char heap[HEAP_SIZE];
__attribute__((used)) STACK_ATTR static char stack[STACK_SIZE];

View File

@@ -9,11 +9,27 @@
#include <assert.h>
#include <stdio.h>
#include <malloc.h>
void malloc_test(void)
{
void *mem = malloc(1024);
assert(mem);
void *mem1 = malloc(1024);
assert(mem1);
free(mem);
free(mem1);
mem = malloc(4 * 1024);
assert(mem);
free(mem);
mem1 = malloc(1024);
assert(mem1);
free(mem1);
}
int main(int argc, char *args[])
{
ulog_write_str(LOG_PROT, "MKRTOS:\n");
void *mem = malloc(12);
free(mem);
malloc_test();
ipc_wait(12, 0);
ipc_reply(12, msg_tag_init4(0, 0, 0, 0));
char *buf;