原始版本

This commit is contained in:
冯佳
2025-06-19 21:56:46 +08:00
parent fe98e5f010
commit a4841450cf
4152 changed files with 1910684 additions and 0 deletions

View File

@ -0,0 +1,13 @@
# RT-Thread building script for component
from building import *
Import('rtconfig')
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_vdsp.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,161 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-02-13 mojingxian First version
*/
.global _rt_hw_interrupt_disable;
.global _rt_hw_interrupt_enable;
.global _interrupt_thread_switch;
.extern _rt_interrupt_from_thread;
.extern _rt_interrupt_to_thread;
.extern _rt_thread_switch_interrupt_flag;
.section/DOUBLE64 program;
/*
* rt_base_t rt_hw_interrupt_disable();
* return value in R0.
*/
_rt_hw_interrupt_disable:
CLI R0;
_rt_hw_interrupt_disable.end:
NOP;
NOP;
NOP;
RTS;
/*
* void rt_hw_interrupt_enable(rt_base_t level);
* R0->level
*/
_rt_hw_interrupt_enable:
STI R0;
_rt_hw_interrupt_enable.end:
NOP;
NOP;
NOP;
RTS;
_interrupt_thread_switch:
/* Save context, interrupts disabled by IPEND[4] bit */
[ -- SP ] = R0;
[ -- SP ] = P1;
[ -- SP ] = RETS;
[ -- SP ] = R1;
[ -- SP ] = R2;
[ -- SP ] = P0;
[ -- SP ] = P2;
[ -- SP ] = ASTAT;
R1 = RETI; /* IPEND[4] is currently set, globally disabling interrupts */
/* IPEND[4] will stay set when RETI is saved through R1 */
[ -- SP ] = R1;
[ -- SP ] = (R7:3, P5:3);
[ -- SP ] = FP;
[ -- SP ] = I0;
[ -- SP ] = I1;
[ -- SP ] = I2;
[ -- SP ] = I3;
[ -- SP ] = B0;
[ -- SP ] = B1;
[ -- SP ] = B2;
[ -- SP ] = B3;
[ -- SP ] = L0;
[ -- SP ] = L1;
[ -- SP ] = L2;
[ -- SP ] = L3;
[ -- SP ] = M0;
[ -- SP ] = M1;
[ -- SP ] = M2;
[ -- SP ] = M3;
R1.L = A0.x;
[ -- SP ] = R1;
R1 = A0.w;
[ -- SP ] = R1;
R1.L = A1.x;
[ -- SP ] = R1;
R1 = A1.w;
[ -- SP ] = R1;
[ -- SP ] = LC0;
R3 = 0;
LC0 = R3;
[ -- SP ] = LC1;
R3 = 0;
LC1 = R3;
[ -- SP ] = LT0;
[ -- SP ] = LT1;
[ -- SP ] = LB0;
[ -- SP ] = LB1;
/* Context save done so save SP in the TCB */
P1.h = _rt_interrupt_from_thread;
P1.l = _rt_interrupt_from_thread;
P2 = [ P1 ];
[ P2 ] = SP;
/* clear rt_thread_switch_interrupt_flag to 0 */
P1.h = _rt_thread_switch_interrupt_flag;
P1.l = _rt_thread_switch_interrupt_flag;
R0 = 0;
[ P1 ] = R0;
/* Get a pointer to the high ready task's TCB */
P1.h = _rt_interrupt_to_thread;
P1.l = _rt_interrupt_to_thread;
P2 = [ P1 ];
SP = [ P2 ];
/* Restoring CPU context and return to task */
LB1 = [ SP ++ ];
LB0 = [ SP ++ ];
LT1 = [ SP ++ ];
LT0 = [ SP ++ ];
LC1 = [ SP ++ ];
LC0 = [ SP ++ ];
R0 = [ SP ++ ];
A1 = R0;
R0 = [ SP ++ ];
A1.x = R0.L;
R0 = [ SP ++ ];
A0 = R0;
R0 = [ SP ++ ];
A0.x = R0.L;
M3 = [ SP ++ ];
M2 = [ SP ++ ];
M1 = [ SP ++ ];
M0 = [ SP ++ ];
L3 = [ SP ++ ];
L2 = [ SP ++ ];
L1 = [ SP ++ ];
L0 = [ SP ++ ];
B3 = [ SP ++ ];
B2 = [ SP ++ ];
B1 = [ SP ++ ];
B0 = [ SP ++ ];
I3 = [ SP ++ ];
I2 = [ SP ++ ];
I1 = [ SP ++ ];
I0 = [ SP ++ ];
FP = [ SP ++ ];
(R7:3, P5:3) = [ SP ++ ];
RETI = [ SP ++ ]; /* IPEND[4] will stay set when RETI popped from stack */
ASTAT = [ SP ++ ];
P2 = [ SP ++ ];
P0 = [ SP ++ ];
R2 = [ SP ++ ];
R1 = [ SP ++ ];
RETS = [ SP ++ ];
P1 = [ SP ++ ];
R0 = [ SP ++ ];
_interrupt_thread_switch.end:
RTI;

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-02-13 mojingxian first version
*/
#include <rtthread.h>
/* flag in interrupt handling */
rt_uint32_t rt_interrupt_from_thread;
rt_uint32_t rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
/**
* initializes stack of thread
*/
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
rt_uint8_t *stack_addr, void *texit)
{
unsigned char i;
unsigned long *stk;
stk = (unsigned long *)stack_addr; /* Load stack pointer */
/* Simulate a function call to the task with an argument */
stk -= 3; /* 3 words assigned for incoming args (R0, R1, R2) */
/* Now simulating vectoring to an ISR */
*--stk = (unsigned long)parameter; /* R0 value - caller's incoming argument #1 */
*--stk = (unsigned long)0; /* P1 value - value irrelevant */
*--stk = (unsigned long)texit; /* RETS value - NO task should return with RTS. */
/* however OS_CPU_Invalid_Task_Return is a safety */
/* catch-allfor tasks that return with an RTS */
*--stk = (unsigned long)parameter; /* R1 value - caller's incoming argument #2 */
/* (not relevant in current test example) */
*--stk = (unsigned long)parameter; /* R2 value - caller's incoming argument #3 */
/* (not relevant in current test example) */
*--stk = (unsigned long)0; /* P0 value - value irrelevant */
*--stk = (unsigned long)0; /* P2 value - value irrelevant */
*--stk = (unsigned long)0; /* ASTAT value - caller's ASTAT value - value */
/* irrelevant */
*--stk = (unsigned long)tentry; /* RETI value- pushing the start address of the task */
for (i = 0; i < 35; i++) /* remaining reg values - R7:3, P5:3, */
{ /* 4 words of A1:0(.W,.X), LT0, LT1, */
*--stk = (unsigned long)0; /* LC0, LC1, LB0, LB1,I3:0, M3:0, L3:0, B3:0, */
} /* All values irrelevant */
return (rt_uint8_t *)stk; /* Return top-of-stack */
}
void rt_hw_context_switch(rt_uint32_t from, rt_uint32_t to)
{
if (rt_thread_switch_interrupt_flag != 1)
{
rt_thread_switch_interrupt_flag = 1;
rt_interrupt_from_thread = from;
}
rt_interrupt_to_thread = to;
asm("raise 14;"); // Raise Interrupt 14 (trap)
}
void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to)
{
if (rt_thread_switch_interrupt_flag != 1)
{
rt_thread_switch_interrupt_flag = 1;
rt_interrupt_from_thread = from;
}
rt_interrupt_to_thread = to;
asm("raise 14;"); // Raise Interrupt 14 (trap)
}
void rt_hw_context_switch_to(rt_uint32_t to)
{
rt_thread_switch_interrupt_flag = 1;
rt_interrupt_from_thread = 0;
rt_interrupt_to_thread = to;
asm("raise 14;"); // Raise Interrupt 14 (trap)
}

View File

@ -0,0 +1,284 @@
/*
* File : serial.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2006-03-13 Bernard first version
* 2009-04-20 yi.qiu modified according bernard's stm32 version
* 2012-02-17 mojingxian modified for bf53x
*/
#include <rtthread.h>
#include "serial.h"
/**
* @addtogroup BF53X
*/
/*@{*/
/* RT-Thread Device Interface */
/**
* This function initializes serial
*/
static rt_err_t rt_serial_init (rt_device_t dev)
{
struct serial_device* uart = (struct serial_device*) dev->user_data;
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
{
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
rt_memset(uart->int_rx->rx_buffer, 0,
sizeof(uart->int_rx->rx_buffer));
uart->int_rx->read_index = uart->int_rx->save_index = 0;
}
if (dev->flag & RT_DEVICE_FLAG_INT_TX)
{
rt_memset(uart->int_tx->tx_buffer, 0,
sizeof(uart->int_tx->tx_buffer));
uart->int_tx->write_index = uart->int_tx->save_index = 0;
}
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
}
return RT_EOK;
}
/* save a char to serial buffer */
static void rt_serial_savechar(struct serial_device* uart, char ch)
{
rt_base_t level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
uart->int_rx->save_index ++;
if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
uart->int_rx->save_index = 0;
/* if the next position is read index, discard this 'read char' */
if (uart->int_rx->save_index == uart->int_rx->read_index)
{
uart->int_rx->read_index ++;
if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
uart->int_rx->read_index = 0;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_err_t rt_serial_close(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_ssize_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
rt_err_t err_code;
struct serial_device* uart;
ptr = buffer;
err_code = RT_EOK;
uart = (struct serial_device*)dev->user_data;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
rt_base_t level;
/* interrupt mode Rx */
while (size)
{
if (uart->int_rx->read_index != uart->int_rx->save_index)
{
*ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
size --;
/* disable interrupt */
level = rt_hw_interrupt_disable();
uart->int_rx->read_index ++;
if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
uart->int_rx->read_index = 0;
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
else
{
/* set error code */
err_code = -RT_EEMPTY;
break;
}
}
}
else
{
/* polling mode */
while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
{
//while (uart->uart_device->ustat & USTAT_RCV_READY)
{
*ptr = uart->uart_device->rbr_thr & 0xff;
ptr ++;
}
}
}
/* set error code */
rt_set_errno(err_code);
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
static rt_ssize_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
rt_err_t err_code;
struct serial_device* uart;
err_code = RT_EOK;
ptr = (rt_uint8_t*)buffer;
uart = (struct serial_device*)dev->user_data;
if (dev->flag & RT_DEVICE_FLAG_INT_TX)
{
/* interrupt mode Tx */
while (uart->int_tx->save_index != uart->int_tx->write_index)
{
/* save on tx buffer */
uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
-- size;
/* move to next position */
uart->int_tx->save_index ++;
/* wrap save index */
if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
uart->int_tx->save_index = 0;
}
/* set error code */
if (size > 0)
err_code = -RT_EFULL;
}
else
{
/* polling mode */
while (size)
{
/*
* to be polite with serial console add a line feed
* to the carriage return character
*/
if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM))
{
while (!(uart->uart_device->lsr & 0x20));
uart->uart_device->rbr_thr = '\r';
}
while (!(uart->uart_device->lsr & 0x20));
uart->uart_device->rbr_thr = (*ptr & 0xFF);
++ptr; --size;
}
}
/* set error code */
rt_set_errno(err_code);
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
static rt_err_t rt_serial_control (rt_device_t dev, int cmd, void *args)
{
RT_ASSERT(dev != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_SUSPEND:
/* suspend device */
dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
break;
case RT_DEVICE_CTRL_RESUME:
/* resume device */
dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
break;
}
return RT_EOK;
}
/*
* serial register
*/
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial)
{
RT_ASSERT(device != RT_NULL);
device->type = RT_Device_Class_Char;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
device->init = rt_serial_init;
device->open = rt_serial_open;
device->close = rt_serial_close;
device->read = rt_serial_read;
device->write = rt_serial_write;
device->control = rt_serial_control;
device->user_data = serial;
/* register a character device */
return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
}
/* ISR for serial interrupt */
void rt_hw_serial_isr(rt_device_t device)
{
struct serial_device* uart = (struct serial_device*) device->user_data;
/* interrupt mode receive */
RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
/* save on rx buffer */
//while (uart->uart_device->ustat & USTAT_RCV_READY)
{
rt_serial_savechar(uart, uart->uart_device->rbr_thr & 0xff);
}
/* invoke callback */
if (device->rx_indicate != RT_NULL)
{
rt_size_t rx_length;
/* get rx length */
rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
uart->int_rx->save_index - uart->int_rx->read_index;
device->rx_indicate(device, rx_length);
}
}
/*@}*/

View File

@ -0,0 +1,56 @@
#ifndef __RT_HW_SERIAL_H__
#define __RT_HW_SERIAL_H__
#include <rthw.h>
#include <rtthread.h>
#define USTAT_RCV_READY 0x01 /* receive data ready */
#define USTAT_TXB_EMPTY 0x02 /* tx buffer empty */
#define BPS 115200 /* serial baudrate */
#define UART_RX_BUFFER_SIZE 64
#define UART_TX_BUFFER_SIZE 64
struct serial_int_rx
{
rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
rt_uint32_t read_index, save_index;
};
struct serial_int_tx
{
rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE];
rt_uint32_t write_index, save_index;
};
typedef struct uartport
{
volatile rt_uint16_t rbr_thr; //receive buffer register and transmit hold register
volatile rt_uint16_t reserved0;
volatile rt_uint16_t reserved1;
volatile rt_uint16_t reserved2;
volatile rt_uint16_t reserved3;
volatile rt_uint16_t reserved4;
volatile rt_uint16_t reserved5;
volatile rt_uint16_t reserved6;
volatile rt_uint16_t reserved7;
volatile rt_uint16_t reserved8;
volatile rt_uint16_t lsr; //line status register
}uartport;
struct serial_device
{
uartport* uart_device;
/* rx structure */
struct serial_int_rx* int_rx;
/* tx structure */
struct serial_int_tx* int_tx;
};
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial);
void rt_hw_serial_isr(rt_device_t device);
#endif