log对象支持从读取控制台数据
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -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,
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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 \
|
||||
{ \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "irq.h"
|
||||
|
||||
typedef struct uart
|
||||
{
|
||||
@@ -15,4 +16,5 @@ typedef struct uart
|
||||
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);
|
||||
int uart_getc(uart_t *uart);
|
||||
void uart_tigger(irq_entry_t *irq);
|
||||
@@ -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);
|
||||
|
||||
28
mkrtos_knl/inc/knl/irq_sender.h
Normal file
28
mkrtos_knl/inc/knl/irq_sender.h
Normal 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);
|
||||
@@ -11,7 +11,4 @@
|
||||
#include "types.h"
|
||||
#include "kobject.h"
|
||||
|
||||
typedef struct log
|
||||
{
|
||||
kobject_t kobj;
|
||||
} log_t;
|
||||
|
||||
|
||||
@@ -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, ...);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
17
mkrtos_knl/inc/lib/queue.h
Normal file
17
mkrtos_knl/inc/lib/queue.h
Normal 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);
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
150
mkrtos_knl/knl/irq_sender.c
Normal 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);
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 输出数据
|
||||
*
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
47
mkrtos_knl/lib/queue.c
Normal 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;
|
||||
}
|
||||
@@ -38,3 +38,4 @@
|
||||
long syscall_backend(long sys_inx, ...);
|
||||
|
||||
umword_t be_mmap2(va_list ap);
|
||||
umword_t be_munmap(va_list ap);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user