未验证 提交 bf62a7ff 编写于 作者: B Bernard Xiong 提交者: GitHub

Merge pull request #2088 from RT-Thread/bsp_k210

[libcpu] Add k210 BSP.
#
# Automatically generated file; DO NOT EDIT.
# RT-Thread Project Configuration
#
#
# RT-Thread Kernel
#
CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=8
# CONFIG_RT_THREAD_PRIORITY_8 is not set
CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
CONFIG_RT_TICK_PER_SECOND=100
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y
CONFIG_RT_USING_IDLE_HOOK=y
CONFIG_RT_IDEL_HOOK_LIST_SIZE=4
CONFIG_IDLE_THREAD_STACK_SIZE=1024
# CONFIG_RT_USING_TIMER_SOFT is not set
CONFIG_RT_DEBUG=y
CONFIG_RT_DEBUG_INIT_CONFIG=y
CONFIG_RT_DEBUG_INIT=1
# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
# CONFIG_RT_DEBUG_IPC_CONFIG is not set
# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
# CONFIG_RT_DEBUG_MEM_CONFIG is not set
# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
#
# Inter-Thread communication
#
CONFIG_RT_USING_SEMAPHORE=y
CONFIG_RT_USING_MUTEX=y
CONFIG_RT_USING_EVENT=y
CONFIG_RT_USING_MAILBOX=y
CONFIG_RT_USING_MESSAGEQUEUE=y
# CONFIG_RT_USING_SIGNALS is not set
#
# Memory Management
#
CONFIG_RT_USING_MEMPOOL=y
# CONFIG_RT_USING_MEMHEAP is not set
# CONFIG_RT_USING_NOHEAP is not set
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_MEMTRACE is not set
CONFIG_RT_USING_HEAP=y
#
# Kernel Device Object
#
CONFIG_RT_USING_DEVICE=y
# CONFIG_RT_USING_DEVICE_OPS is not set
# CONFIG_RT_USING_INTERRUPT_INFO is not set
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="uarths"
CONFIG_RT_VER_NUM=0x40000
CONFIG_ARCH_CPU_64BIT=y
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_RISCV64=y
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
#
# RT-Thread Components
#
CONFIG_RT_USING_COMPONENTS_INIT=y
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192
CONFIG_RT_MAIN_THREAD_PRIORITY=10
#
# C++ features
#
# CONFIG_RT_USING_CPLUSPLUS is not set
#
# Command shell
#
CONFIG_RT_USING_FINSH=y
CONFIG_FINSH_THREAD_NAME="tshell"
CONFIG_FINSH_USING_HISTORY=y
CONFIG_FINSH_HISTORY_LINES=5
CONFIG_FINSH_USING_SYMTAB=y
CONFIG_FINSH_USING_DESCRIPTION=y
# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
CONFIG_FINSH_THREAD_PRIORITY=20
CONFIG_FINSH_THREAD_STACK_SIZE=4096
CONFIG_FINSH_CMD_SIZE=80
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_USING_MSH=y
CONFIG_FINSH_USING_MSH_DEFAULT=y
CONFIG_FINSH_USING_MSH_ONLY=y
CONFIG_FINSH_ARG_MAX=10
#
# Device virtual file system
#
CONFIG_RT_USING_DFS=y
CONFIG_DFS_USING_WORKDIR=y
CONFIG_DFS_FILESYSTEMS_MAX=4
CONFIG_DFS_FILESYSTEM_TYPES_MAX=4
CONFIG_DFS_FD_MAX=16
# CONFIG_RT_USING_DFS_MNTTABLE is not set
# CONFIG_RT_USING_DFS_ELMFAT is not set
CONFIG_RT_USING_DFS_DEVFS=y
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
# CONFIG_RT_USING_DFS_UFFS is not set
# CONFIG_RT_USING_DFS_JFFS2 is not set
#
# Device Drivers
#
CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_PIPE_BUFSZ=512
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_SERIAL_USING_DMA=y
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_PWM is not set
# CONFIG_RT_USING_MTD_NOR is not set
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_MTD is not set
# CONFIG_RT_USING_PM is not set
# CONFIG_RT_USING_RTC is not set
# CONFIG_RT_USING_SDIO is not set
# CONFIG_RT_USING_SPI is not set
# CONFIG_RT_USING_WDT is not set
# CONFIG_RT_USING_AUDIO is not set
#
# Using WiFi
#
# CONFIG_RT_USING_WIFI is not set
#
# Using USB
#
# CONFIG_RT_USING_USB_HOST is not set
# CONFIG_RT_USING_USB_DEVICE is not set
#
# POSIX layer and C standard library
#
CONFIG_RT_USING_LIBC=y
# CONFIG_RT_USING_PTHREADS is not set
CONFIG_RT_USING_POSIX=y
# CONFIG_RT_USING_POSIX_MMAP is not set
# CONFIG_RT_USING_POSIX_TERMIOS is not set
# CONFIG_RT_USING_POSIX_AIO is not set
# CONFIG_RT_USING_MODULE is not set
#
# Network
#
#
# Socket abstraction layer
#
# CONFIG_RT_USING_SAL is not set
#
# light weight TCP/IP stack
#
# CONFIG_RT_USING_LWIP is not set
#
# Modbus master and slave stack
#
# CONFIG_RT_USING_MODBUS is not set
#
# AT commands
#
# CONFIG_RT_USING_AT is not set
#
# VBUS(Virtual Software BUS)
#
# CONFIG_RT_USING_VBUS is not set
#
# Utilities
#
# CONFIG_RT_USING_LOGTRACE is not set
# CONFIG_RT_USING_RYM is not set
# CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set
#
# RT-Thread online packages
#
#
# IoT - internet of things
#
# CONFIG_PKG_USING_PAHOMQTT is not set
# CONFIG_PKG_USING_WEBCLIENT is not set
# CONFIG_PKG_USING_WEBNET is not set
# CONFIG_PKG_USING_MONGOOSE is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_JSMN is not set
# CONFIG_PKG_USING_LJSON is not set
# CONFIG_PKG_USING_EZXML is not set
# CONFIG_PKG_USING_NANOPB is not set
#
# Wi-Fi
#
#
# Marvell WiFi
#
# CONFIG_PKG_USING_WLANMARVELL is not set
#
# Wiced WiFi
#
# CONFIG_PKG_USING_WLAN_WICED is not set
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
# CONFIG_PKG_USING_AT_DEVICE is not set
# CONFIG_PKG_USING_WIZNET is not set
#
# IoT Cloud
#
# CONFIG_PKG_USING_ONENET is not set
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
# CONFIG_PKG_USING_TENCENT_IOTKIT is not set
#
# security packages
#
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_libsodium is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
#
# language packages
#
# CONFIG_PKG_USING_LUA is not set
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
#
# multimedia packages
#
# CONFIG_PKG_USING_OPENMV is not set
# CONFIG_PKG_USING_MUPDF is not set
#
# tools packages
#
# CONFIG_PKG_USING_CMBACKTRACE is not set
# CONFIG_PKG_USING_EASYFLASH is not set
# CONFIG_PKG_USING_EASYLOGGER is not set
# CONFIG_PKG_USING_SYSTEMVIEW is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_QRCODE is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
#
# system packages
#
# CONFIG_PKG_USING_GUIENGINE is not set
# CONFIG_PKG_USING_CAIRO is not set
# CONFIG_PKG_USING_PIXMAN is not set
# CONFIG_PKG_USING_LWEXT4 is not set
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_FAL is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_CMSIS is not set
# CONFIG_PKG_USING_DFS_YAFFS is not set
# CONFIG_PKG_USING_LITTLEFS is not set
#
# peripheral libraries and drivers
#
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_AHT10 is not set
# CONFIG_PKG_USING_AP3216C is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_U8G2 is not set
# CONFIG_PKG_USING_BUTTON is not set
# CONFIG_PKG_USING_MPU6XXX is not set
# CONFIG_PKG_USING_PCF8574 is not set
CONFIG_PKG_USING_KENDRYTE_SDK=y
CONFIG_PKG_KENDRYTE_SDK_PATH="/packages/peripherals/kendryte-sdk"
CONFIG_PKG_USING_KENDRYTE_SDK_V052=y
# CONFIG_PKG_USING_KENDRYTE_SDK_LATEST_VERSION is not set
CONFIG_PKG_KENDRYTE_SDK_VER="v0.5.2"
#
# miscellaneous packages
#
# CONFIG_PKG_USING_LIBCSV is not set
# CONFIG_PKG_USING_OPTPARSE is not set
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
# CONFIG_PKG_USING_QUICKLZ is not set
# CONFIG_PKG_USING_MULTIBUTTON is not set
# CONFIG_PKG_USING_CANFESTIVAL is not set
# CONFIG_PKG_USING_ZLIB is not set
# CONFIG_PKG_USING_DSTR is not set
# CONFIG_PKG_USING_TINYFRAME is not set
#
# sample package
#
#
# samples: kernel and components samples
#
# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
#
# example package: hello
#
# CONFIG_PKG_USING_HELLO is not set
#
# Privated Packages of RealThread
#
# CONFIG_PKG_USING_CODEC is not set
# CONFIG_PKG_USING_PLAYER is not set
# CONFIG_PKG_USING_PERSIMMON_SRC is not set
# CONFIG_PKG_USING_JS_PERSIMMON is not set
# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
#
# Network Utilities
#
# CONFIG_PKG_USING_WICED is not set
# CONFIG_PKG_USING_CLOUDSDK is not set
# CONFIG_PKG_USING_COREMARK is not set
# CONFIG_PKG_USING_POWER_MANAGER is not set
# CONFIG_PKG_USING_RT_OTA is not set
# CONFIG_PKG_USING_RDBD_SRC is not set
# CONFIG_PKG_USING_RTINSIGHT is not set
# CONFIG_PKG_USING_SMARTCONFIG is not set
# CONFIG_PKG_USING_RTX is not set
CONFIG_BOARD_K210_EVB=y
CONFIG_BSP_USING_UART_HS=y
# CONFIG_BSP_USING_UART1 is not set
# CONFIG_BSP_USING_UART2 is not set
# CONFIG_BSP_USING_UART3 is not set
# CONFIG_BSP_USING_I2C1 is not set
# CONFIG_BSP_USING_SPI1 is not set
CONFIG___STACKSIZE__=4096
mainmenu "RT-Thread Project Configuration"
config $BSP_DIR
string
option env="BSP_ROOT"
default "."
config $RTT_DIR
string
option env="RTT_ROOT"
default: "../.."
config $PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
config BOARD_K210_EVB
bool
select ARCH_RISCV64
select PKG_USING_KENDRYTE_SDK
default y
source "driver/Kconfig"
config __STACKSIZE__
int "stack size for interrupt"
default 4096
# Kendryte K210板级支持包说明
## 1. 简介
Kendryte K210 是集成机器视觉与机器听觉能力的系统级芯片(SoC)。使用台积电 (TSMC) 超低功耗的 28 纳米先进制程,具有双核64位处理器,拥有较好的功耗性能,稳定性与可靠性。该方案力求零门槛开发,可在最短时效部署于用户的产品中,赋予产品人工智能。
Kendryte K210 定位于AI与IoT市场的SoC,同时是使用非常方便的MCU。
Kendryte中文含义为勘智,而勘智取自勘物探智。这颗芯片主要应用领域为物联网领域,在物联网领域进行开发,因此为勘物;这颗芯片主要提供的是人工智能解决方案,在人工智能领域探索,因此为探智。
* 具备机器视觉能力
* 具备机器听觉能力
* 更好的低功耗视觉处理速度与准确率
* 具备卷积人工神经网络硬件加速器KPU,可高性能进行卷积人工神经网络运算
* TSMC 28nm先进制程,温度范围-40°C到125°C,稳定可靠
* 支持固件加密,难以使用普通方法破解
* 独特的可编程IO阵列,使产品设计更加灵活
* 低电压,与相同处理能力的系统相比具有更低功耗
* 3.3V/1.8V双电压支持,无需电平转换,节约成本
芯片规格包括如下:
| 硬件 | 描述 |
| -- | -- |
|芯片型号| K210 |
|CPU| 双核RV64GC |
|主频| 400MHz |
|片内SRAM| 8MB |
| 外设 | 内嵌AES与SHA256算法加速器 |
| | DVP、JTAG、OTP、FPIOA、GPIO、UART、SPI、RTC、I²S、I²C、WDT、Timer与PWM |
## 2. 编译说明
编译K210,需要先下载K210 BSP以及RT-Thread代码:
git clone https://github.com/BernardXiong/K210.git
cd K210
git submodule init
git submodule update
git clone https://github.com/RT-Thread/rt-thread.git
cd rt-thread
git checkout -b dev-4.0.x origin/dev-4.0.x
注意,因为RT-Thread整体代码太庞大,所以并未把RT-Thread git repo以一个submodule方式加入到K210 BSP git repo中,
而是需要把RT-Thread代码克隆到K210目录下,并切换到dev-4.0.x分支。
编译推荐使用[env工具][1],可以在console下进入到`K210`目录中,运行以下命令:
set RTT_EXEC_PATH=your_toolchains
scons
来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。其中rtthread.bin需要烧写到设备中进行运行。
## 3. 烧写及执行
连接好串口,然后使用[K-Flash](https://kendryte.com/downloads/)工具进行烧写bin文件。
![K-Flash](images/flash.png)
### 3.1 运行结果
如果编译 & 烧写无误,当复位设备后,会在串口上看到RT-Thread的启动logo信息:
![terminal](images/k210.png)
## 4. 驱动支持情况及计划
| 驱动 | 支持情况 | 备注 |
| ------ | ---- | :------: |
| UART | 支持 | 高速UART,用于shell |
## 5. 联系人信息
维护人:[bernard](https://github.com/BernardXiong)
## 6. 注意事项
在进行系统menuconfig配置时,以下项是必选的
| 配置项 | 强制配置值 |
| ----- | --------- |
| Alignment size for CPU architecture data access | 8 |
| The stack size of idle thread | > 1024 |
| the device name for console | "uarths" |
| Set main thread stack size | 4096 |
## 7. 参考
* 芯片[datasheet][2]
[1]: https://www.rt-thread.org/page/download.html
[2]: https://s3.cn-north-1.amazonaws.com.cn/dl.kendryte.com/documents/kendryte_datasheet_20180919020633.pdf
# for module compiling
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')
import os
import sys
import rtconfig
from rtconfig import RTT_ROOT
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
env['ASCOM'] = env['ASPPCOM']
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
stack_size = 4096
stack_lds = open('link_stacksize.lds', 'w')
if GetDepend('__STACKSIZE__'): stack_size = GetDepend('__STACKSIZE__')
stack_lds.write('__STACKSIZE__ = %d;' % stack_size)
stack_lds.close()
# make a building
DoBuilding(TARGET, objs)
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/09/30 Bernard The first version
*/
#include <rtthread.h>
#include <stdio.h>
int main(void)
{
rt_kprintf("Hello, world\n");
return 0;
}
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
int mnt_init(void)
{
return 0;
}
config BSP_USING_UART_HS
bool "Enable High Speed UART"
default y
config BSP_USING_UART1
bool "Enable UART1 (GPIO0/1)"
default n
config BSP_USING_UART2
bool "Enable UART2 (GPIO0/1)"
default n
config BSP_USING_UART3
bool "Enable UART3 (GPIO0/1)"
default n
config BSP_USING_I2C1
bool "Enable I2C1 (GPIO0/1)"
select RT_USING_I2C
default n
config BSP_USING_SPI1
bool "Enable SPI1 (GPIO0/1)"
select RT_USING_SPI
default n
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Split('''
board.c
drv_uart.c
''')
CPPPATH = [cwd]
if GetDepend('RT_USING_PIN'):
src += ['drv_gpio.c']
if GetDepend('RT_USING_HWTIMER'):
src += ['drv_hw_timer.c']
if GetDepend('RT_USING_CPUTIME'):
src += ['drv_cputime.c']
if GetDepend('RT_USING_I2C'):
src += ['drv_i2c.c']
if GetDepend('RT_USING_SPI'):
src += ['drv_spi.c']
if GetDepend('RT_USING_PWM'):
src += ['drv_pwm.c']
if GetDepend('RT_USING_RTC'):
src += ['drv_rtc.c']
if GetDepend('RT_USING_WDT'):
src += ['drv_wdt.c']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "tick.h"
#include "drv_uart.h"
#include "encoding.h"
#include "fpioa.h"
#include "dmac.h"
#include "uarths.h"
void rt_hw_console_output(const char *str)
{
uarths_puts(str);
return ;
}
void init_bss(void)
{
unsigned int *dst;
dst = &__bss_start;
while (dst < &__bss_end)
{
*dst++ = 0;
}
}
void cpu_entry(int cpuid)
{
extern void entry(void);
/* disable global interrupt */
rt_hw_interrupt_disable();
if (cpuid == 0)
{
init_bss();
entry();
}
else
{
while (1) ;
}
}
#include <clint.h>
#include <sysctl.h>
int freq(void)
{
rt_uint64_t value = 0;
value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL0);
rt_kprintf("PLL0: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL1);
rt_kprintf("PLL1: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL2);
rt_kprintf("PLL2: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_CPU);
rt_kprintf("CPU : %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
rt_kprintf("APB0: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB1);
rt_kprintf("APB1: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB2);
rt_kprintf("APB2: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_HCLK);
rt_kprintf("HCLK: %d\n", value);
value = clint_get_time();
rt_kprintf("mtime: %d\n", value);
return 0;
}
MSH_CMD_EXPORT(freq, show freq info);
void rt_hw_board_init(void)
{
/* Init FPIOA */
fpioa_init();
/* Dmac init */
dmac_init();
/* initalize interrupt */
rt_hw_interrupt_init();
/* initialize hardware interrupt */
rt_hw_uart_init();
rt_hw_tick_init();
#ifdef RT_USING_CONSOLE
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif /* RT_USING_CONSOLE */
#ifdef RT_USING_HEAP
rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t) RT_HW_HEAP_BEGIN, (rt_ubase_t) RT_HW_HEAP_END);
/* initialize memory system */
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
#endif
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-5-30 Bernard the first version
*/
#ifndef BOARD_H__
#define BOARD_H__
extern unsigned int __bss_start;
extern unsigned int __bss_end;
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
#define RT_HW_HEAP_END (void*)(0x80000000 + 6 * 1024 * 1024)
void rt_hw_board_init(void);
#endif
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#include "drv_uart.h"
#include <stdio.h>
// #include "uart.h"
#include "uarths.h"
#include "plic.h"
struct device_uart
{
rt_uint32_t hw_base;
rt_uint32_t irqno;
};
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg);
static int drv_uart_putc(struct rt_serial_device *serial, char c);
static int drv_uart_getc(struct rt_serial_device *serial);
static void uart_irq_handler(int irqno, void *param);
const struct rt_uart_ops _uart_ops =
{
uart_configure,
uart_control,
drv_uart_putc,
drv_uart_getc,
RT_NULL
};
/*
* UART Initiation
*/
int rt_hw_uart_init(void)
{
struct rt_serial_device *serial;
struct device_uart *uart;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#ifdef BSP_USING_UART_HS
{
static struct rt_serial_device serial_hs;
static struct device_uart uart_hs;
serial = &serial_hs;
uart = &uart_hs;
serial->ops = &_uart_ops;
serial->config = config;
serial->config.baud_rate = 115200;
uart->hw_base = UARTHS_BASE_ADDR;
uart->irqno = IRQN_UARTHS_INTERRUPT;
/* initialize UART HS */
uarths_init();
rt_hw_serial_register(serial,
"uarths",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart);
}
#endif
#ifdef BSP_USING_UART1
{
static struct rt_serial_device serial1;
static struct device_uart uart1;
serial = &serial1;
uart = &uart1;
serial->ops = &_uart_ops;
serial->config = config;
serial->config.baud_rate = 115200;
uart->hw_base = UART1_BASE_ADDR;
uart->irqno = IRQN_UART1_INTERRUPT;
rt_hw_serial_register(serial,
"uarths",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart);
}
#endif
#ifdef BSP_USING_UART2
#endif
#ifdef BSP_USING_UART3
#endif
return 0;
}
/*
* UART interface
*/
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
rt_uint32_t baud_div;
struct device_uart *uart;
RT_ASSERT(serial != RT_NULL);
serial->config = *cfg;
uart = serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
/* Init UART Hardware */
/* Enable UART clock */
/* Set both receiver and transmitter in UART mode (not SIR) */
/* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
/* set baudrate */
return (RT_EOK);
}
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
struct device_uart *uart;
uart = serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* Disable the UART Interrupt */
rt_hw_interrupt_mask(uart->irqno);
break;
case RT_DEVICE_CTRL_SET_INT:
/* install interrupt */
rt_hw_interrupt_install(uart->irqno, uart_irq_handler,
serial, serial->parent.parent.name);
rt_hw_interrupt_umask(uart->irqno);
break;
}
return (RT_EOK);
}
static int drv_uart_putc(struct rt_serial_device *serial, char c)
{
struct device_uart *uart;
uart = serial->parent.user_data;
if (uart->hw_base == UARTHS_BASE_ADDR)
{
uarths_putchar(c);
}
else
{
/* other uart */
}
return (1);
}
static int drv_uart_getc(struct rt_serial_device *serial)
{
int ret = -1;
struct device_uart *uart = serial->parent.user_data;
if (uart->hw_base == UARTHS_BASE_ADDR)
{
ret = uarths_getc();
if (ret != EOF) return ret;
}
/* Receive Data Available */
return (-1);
}
/* UART ISR */
static void uart_irq_handler(int irqno, void *param)
{
rt_ubase_t isr;
struct rt_serial_device *serial = (struct rt_serial_device *)param;
struct device_uart *uart = serial->parent.user_data;
/* read interrupt status and clear it */
if (uart->hw_base == UARTHS_BASE_ADDR)
{
if (uarths->ip.rxwm)
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
}
}
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/01 Bernard The first version
*/
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
int rt_hw_uart_init(void);
#endif /* __DRV_UART_H__ */
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
INCLUDE "link_stacksize.lds"
/*
* The OUTPUT_ARCH command specifies the machine architecture where the
* argument is one of the names used in the Kendryte library.
*/
OUTPUT_ARCH( "riscv" )
MEMORY
{
/* 6M SRAM */
SRAM : ORIGIN = 0x80000000, LENGTH = 0x600000
}
ENTRY(_start)
SECTIONS
{
. = 0x80000000 ;
/* __STACKSIZE__ = 4096; */
.start :
{
*(.start);
} > SRAM
. = ALIGN(4);
.text :
{
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
. = ALIGN(4);
_etext = .;
} > SRAM
.eh_frame_hdr :
{
*(.eh_frame_hdr)
*(.eh_frame_entry)
} > SRAM
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > SRAM
. = ALIGN(4);
.data :
{
*(.data)
*(.data.*)
*(.data1)
*(.data1.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata)
*(.sdata.*)
} > SRAM
/* stack for dual core */
.stack :
{
. = ALIGN(64);
__stack_start__ = .;
. += __STACKSIZE__;
__stack_cpu0 = .;
. += __STACKSIZE__;
__stack_cpu1 = .;
} > SRAM
.sbss :
{
__bss_start = .;
*(.sbss)
*(.sbss.*)
*(.dynsbss)
*(.scommon)
} > SRAM
.bss :
{
*(.bss)
*(.bss.*)
*(.dynbss)
*(COMMON)
__bss_end = .;
} > SRAM
_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
__STACKSIZE__ = 4096;
\ No newline at end of file
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
/* Automatically generated file; DO NOT EDIT. */
/* RT-Thread Project Configuration */
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 8
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 100
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_USING_IDLE_HOOK
#define RT_IDEL_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 1024
#define RT_DEBUG
#define RT_DEBUG_INIT_CONFIG
#define RT_DEBUG_INIT 1
/* Inter-Thread communication */
#define RT_USING_SEMAPHORE
#define RT_USING_MUTEX
#define RT_USING_EVENT
#define RT_USING_MAILBOX
#define RT_USING_MESSAGEQUEUE
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_HEAP
/* Kernel Device Object */
#define RT_USING_DEVICE
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uarths"
#define RT_VER_NUM 0x40000
#define ARCH_CPU_64BIT
#define ARCH_RISCV
#define ARCH_RISCV64
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 8192
#define RT_MAIN_THREAD_PRIORITY 10
/* C++ features */
/* Command shell */
#define RT_USING_FINSH
#define FINSH_THREAD_NAME "tshell"
#define FINSH_USING_HISTORY
#define FINSH_HISTORY_LINES 5
#define FINSH_USING_SYMTAB
#define FINSH_USING_DESCRIPTION
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_STACK_SIZE 4096
#define FINSH_CMD_SIZE 80
#define FINSH_USING_MSH
#define FINSH_USING_MSH_DEFAULT
#define FINSH_USING_MSH_ONLY
#define FINSH_ARG_MAX 10
/* Device virtual file system */
#define RT_USING_DFS
#define DFS_USING_WORKDIR
#define DFS_FILESYSTEMS_MAX 4
#define DFS_FILESYSTEM_TYPES_MAX 4
#define DFS_FD_MAX 16
#define RT_USING_DFS_DEVFS
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_PIPE_BUFSZ 512
#define RT_USING_SERIAL
#define RT_SERIAL_USING_DMA
#define RT_USING_PIN
/* Using WiFi */
/* Using USB */
/* POSIX layer and C standard library */
#define RT_USING_LIBC
#define RT_USING_POSIX
/* Network */
/* Socket abstraction layer */
/* light weight TCP/IP stack */
/* Modbus master and slave stack */
/* AT commands */
/* VBUS(Virtual Software BUS) */
/* Utilities */
/* RT-Thread online packages */
/* IoT - internet of things */
/* Wi-Fi */
/* Marvell WiFi */
/* Wiced WiFi */
/* IoT Cloud */
/* security packages */
/* language packages */
/* multimedia packages */
/* tools packages */
/* system packages */
/* peripheral libraries and drivers */
#define PKG_USING_KENDRYTE_SDK
#define PKG_USING_KENDRYTE_SDK_V052
/* miscellaneous packages */
/* sample package */
/* samples: kernel and components samples */
/* example package: hello */
/* Privated Packages of RealThread */
/* Network Utilities */
#define BOARD_K210_EVB
#define BSP_USING_UART_HS
#define __STACKSIZE__ 4096
#endif
import os
# toolchains options
ARCH ='risc-v'
CPU ='k210'
CROSS_TOOL ='gcc'
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = r'rt-thread'
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'/opt/riscv64-unknown-elf-gcc-2018.07.0-x86_64-linux-ubuntu14/bin'
else:
print('Please make sure your toolchains is GNU GCC!')
exit(0)
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'release'
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'riscv-none-embed-'
# PREFIX = 'riscv64-unknown-elf-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcmodel=medany'
CFLAGS = DEVICE + ' -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields '
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -ggdb'
AFLAGS += ' -ggdb'
else:
CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/01 Bernard The first version
*/
#include <rthw.h>
#include "tick.h"
#include <plic.h>
#include <clint.h>
#include <interrupt.h>
#define CPU_NUM 2
#define MAX_HANDLERS IRQN_MAX
static struct rt_irq_desc irq_desc[CPU_NUM][MAX_HANDLERS];
static rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
{
rt_kprintf("UN-handled interrupt %d occurred!!!\n", vector);
return RT_NULL;
}
/**
* This function will initialize hardware interrupt
*/
void rt_hw_interrupt_init(void)
{
int idx;
int cpuid;
cpuid = current_coreid();
/* Disable all interrupts for the current core. */
for (idx = 0; idx < ((PLIC_NUM_SOURCES + 32u) / 32u); idx ++)
plic->target_enables.target[cpuid].enable[idx] = 0;
/* Set priorities to zero. */
for (idx = 0; idx < PLIC_NUM_SOURCES; idx++)
plic->source_priorities.priority[idx] = 0;
/* Set the threshold to zero. */
plic->targets.target[cpuid].priority_threshold = 0;
/* init exceptions table */
for (idx = 0; idx < MAX_HANDLERS; idx++)
{
rt_hw_interrupt_mask(idx);
irq_desc[cpuid][idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
irq_desc[cpuid][idx].param = RT_NULL;
#ifdef RT_USING_INTERRUPT_INFO
rt_snprintf(irq_desc[cpuid][idx].name, RT_NAME_MAX - 1, "default");
irq_desc[idx][cpuid].counter = 0;
#endif
}
/* Enable machine external interrupts. */
set_csr(mie, MIP_MEIP);
}
/**
* This function will mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_mask(int vector)
{
plic_irq_disable(vector);
}
/**
* This function will un-mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_umask(int vector)
{
plic_set_priority(vector, 1);
plic_irq_enable(vector);
}
/**
* This function will install a interrupt service routine to a interrupt.
* @param vector the interrupt number
* @param new_handler the interrupt service routine to be installed
* @param old_handler the old interrupt service routine
*/
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
void *param, const char *name)
{
int cpuid;
rt_isr_handler_t old_handler = RT_NULL;
cpuid = current_coreid();
if(vector < MAX_HANDLERS)
{
old_handler = irq_desc[cpuid][vector].handler;
if (handler != RT_NULL)
{
irq_desc[cpuid][vector].handler = (rt_isr_handler_t)handler;
irq_desc[cpuid][vector].param = param;
#ifdef RT_USING_INTERRUPT_INFO
rt_snprintf(irq_desc[cpuid][vector].name, RT_NAME_MAX - 1, "%s", name);
irq_desc[cpuid][vector].counter = 0;
#endif
}
}
return old_handler;
}
uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc)
{
/*
* After the highest-priority pending interrupt is claimed by a target
* and the corresponding IP bit is cleared, other lower-priority
* pending interrupts might then become visible to the target, and so
* the PLIC EIP bit might not be cleared after a claim. The interrupt
* handler can check the local meip/heip/seip/ueip bits before exiting
* the handler, to allow more efficient service of other interrupts
* without first restoring the interrupted context and taking another
* interrupt trap.
*/
if (read_csr(mip) & MIP_MEIP)
{
/* Get current core id */
uint64_t core_id = current_coreid();
/* Get primitive interrupt enable flag */
uint64_t ie_flag = read_csr(mie);
/* Get current IRQ num */
uint32_t int_num = plic->targets.target[core_id].claim_complete;
/* Get primitive IRQ threshold */
uint32_t int_threshold = plic->targets.target[core_id].priority_threshold;
/* Set new IRQ threshold = current IRQ threshold */
plic->targets.target[core_id].priority_threshold = plic->source_priorities.priority[int_num];
/* Disable software interrupt and timer interrupt */
clear_csr(mie, MIP_MTIP | MIP_MSIP);
if (irq_desc[core_id][int_num].handler)
{
irq_desc[core_id][int_num].handler(int_num, irq_desc[core_id][int_num].param);
}
/* Perform IRQ complete */
plic->targets.target[core_id].claim_complete = int_num;
/* Set MPIE and MPP flag used to MRET instructions restore MIE flag */
set_csr(mstatus, MSTATUS_MPIE | MSTATUS_MPP);
/* Restore primitive interrupt enable flag */
write_csr(mie, ie_flag);
/* Restore primitive IRQ threshold */
plic->targets.target[core_id].priority_threshold = int_threshold;
}
else
{
rt_kprintf("unhandled trap!\n");
}
return epc;
}
uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc)
{
int cause = mcause & CAUSE_MACHINE_IRQ_REASON_MASK;
if (mcause & (1UL << 63))
{
switch (cause)
{
case IRQ_M_SOFT:
break;
case IRQ_M_EXT:
handle_irq_m_ext(mcause, epc);
break;
case IRQ_M_TIMER:
tick_isr();
break;
}
}
else
{
rt_thread_t tid;
extern long list_thread();
rt_hw_interrupt_disable();
tid = rt_thread_self();
rt_kprintf("\n");
rt_kprintf("unhandled trap, epc => 0x%08x, INT[%d]\n", epc, rt_interrupt_get_nest());
rt_kprintf("current thread: %.*s\n", RT_NAME_MAX, tid->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
while(1);
}
return epc;
}
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/02 Bernard The first version
*/
#include "cpuport.h"
.section .text.entry
.align 2
.global trap_entry
trap_entry:
/* save thread context to thread stack */
addi sp, sp, -32 * REGBYTES
STORE x1, 1 * REGBYTES(sp)
li t0, 0x80
STORE t0, 2 * REGBYTES(sp)
STORE x4, 4 * REGBYTES(sp)
STORE x5, 5 * REGBYTES(sp)
STORE x6, 6 * REGBYTES(sp)
STORE x7, 7 * REGBYTES(sp)
STORE x8, 8 * REGBYTES(sp)
STORE x9, 9 * REGBYTES(sp)
STORE x10, 10 * REGBYTES(sp)
STORE x11, 11 * REGBYTES(sp)
STORE x12, 12 * REGBYTES(sp)
STORE x13, 13 * REGBYTES(sp)
STORE x14, 14 * REGBYTES(sp)
STORE x15, 15 * REGBYTES(sp)
STORE x16, 16 * REGBYTES(sp)
STORE x17, 17 * REGBYTES(sp)
STORE x18, 18 * REGBYTES(sp)
STORE x19, 19 * REGBYTES(sp)
STORE x20, 20 * REGBYTES(sp)
STORE x21, 21 * REGBYTES(sp)
STORE x22, 22 * REGBYTES(sp)
STORE x23, 23 * REGBYTES(sp)
STORE x24, 24 * REGBYTES(sp)
STORE x25, 25 * REGBYTES(sp)
STORE x26, 26 * REGBYTES(sp)
STORE x27, 27 * REGBYTES(sp)
STORE x28, 28 * REGBYTES(sp)
STORE x29, 29 * REGBYTES(sp)
STORE x30, 30 * REGBYTES(sp)
STORE x31, 31 * REGBYTES(sp)
/* switch to interrupt stack */
move s0, sp
/* get cpu id */
csrr t0, mhartid
/* switch interrupt stack of current cpu */
la sp, __stack_start__
addi t1, t0, 1
li t2, __STACKSIZE__
mul t1, t1, t2
add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */
/* handle interrupt */
call rt_interrupt_enter
csrr a0, mcause
csrr a1, mepc
mv a2, sp
call handle_trap
call rt_interrupt_leave
/* switch to from_thread stack */
move sp, s0
/* need to switch new thread */
la s0, rt_thread_switch_interrupt_flag
lw s2, 0(s0)
beqz s2, spurious_interrupt
sw zero, 0(s0)
csrr a0, mepc
STORE a0, 0 * REGBYTES(sp)
la s0, rt_interrupt_from_thread
LOAD s1, 0(s0)
STORE sp, 0(s1)
la s0, rt_interrupt_to_thread
LOAD s1, 0(s0)
LOAD sp, 0(s1)
LOAD a0, 0 * REGBYTES(sp)
csrw mepc, a0
spurious_interrupt:
LOAD x1, 1 * REGBYTES(sp)
/* Remain in M-mode after mret */
li t0, 0x00001800
csrs mstatus, t0
LOAD t0, 2 * REGBYTES(sp)
csrs mstatus, t0
LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
mret
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/01 Bernard The first version
*/
#define MSTATUS_FS 0x00006000U /* initial state of FPU */
#include <cpuport.h>
.global _start
.section ".start", "ax"
_start:
j 1f
.word 0xdeadbeef
1:
csrw mideleg, 0
csrw medeleg, 0
csrw mie, 0
csrw mip, 0
la t0, trap_entry
csrw mtvec, t0
li x1, 0
li x2, 0
li x3, 0
li x4, 0
li x5, 0
li x6, 0
li x7, 0
li x8, 0
li x9, 0
li x10,0
li x11,0
li x12,0
li x13,0
li x14,0
li x15,0
li x16,0
li x17,0
li x18,0
li x19,0
li x20,0
li x21,0
li x22,0
li x23,0
li x24,0
li x25,0
li x26,0
li x27,0
li x28,0
li x29,0
li x30,0
li x31,0
/* set to initial state of FPU and disable interrupt */
li t0, MSTATUS_FS
csrs mstatus, t0
fssr x0
fmv.d.x f0, x0
fmv.d.x f1, x0
fmv.d.x f2, x0
fmv.d.x f3, x0
fmv.d.x f4, x0
fmv.d.x f5, x0
fmv.d.x f6, x0
fmv.d.x f7, x0
fmv.d.x f8, x0
fmv.d.x f9, x0
fmv.d.x f10,x0
fmv.d.x f11,x0
fmv.d.x f12,x0
fmv.d.x f13,x0
fmv.d.x f14,x0
fmv.d.x f15,x0
fmv.d.x f16,x0
fmv.d.x f17,x0
fmv.d.x f18,x0
fmv.d.x f19,x0
fmv.d.x f20,x0
fmv.d.x f21,x0
fmv.d.x f22,x0
fmv.d.x f23,x0
fmv.d.x f24,x0
fmv.d.x f25,x0
fmv.d.x f26,x0
fmv.d.x f27,x0
fmv.d.x f28,x0
fmv.d.x f29,x0
fmv.d.x f30,x0
fmv.d.x f31,x0
.option push
.option norelax
la gp, __global_pointer$
.option pop
/* get cpu id */
csrr a0, mhartid
la sp, __stack_start__
addi t1, a0, 1
li t2, __STACKSIZE__
mul t1, t1, t2
add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */
/* other cpu core, jump to cpu entry directly */
bnez a0, _cpu_entry
#if 0
/* clear bss section */
la a0, __bss_start
la a1, __bss_end
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, REGBYTES
bltu a0, a1, 1b
2:
#endif
_cpu_entry:
csrr a0, mhartid
j cpu_entry
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/28 Bernard The unify RISC-V porting code.
*/
#include <rthw.h>
#include <rtthread.h>
#include <encoding.h>
#include <clint.h>
#include <sysctl.h>
static volatile unsigned long tick_cycles = 0;
int tick_isr(void)
{
uint64_t core_id = current_coreid();
clint->mtimecmp[core_id] += tick_cycles;
rt_tick_increase();
return 0;
}
/* Sets and enable the timer interrupt */
int rt_hw_tick_init(void)
{
/* Read core id */
unsigned long core_id = current_coreid();
unsigned long interval = 1000/RT_TICK_PER_SECOND;
/* Clear the Machine-Timer bit in MIE */
clear_csr(mie, MIP_MTIP);
/* calculate the tick cycles */
tick_cycles = interval * sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / CLINT_CLOCK_DIV / 1000ULL - 1;
/* Set mtimecmp by core id */
clint->mtimecmp[core_id] = clint->mtime + tick_cycles;
/* Enable the Machine-Timer bit in MIE */
set_csr(mie, MIP_MTIP);
return 0;
}
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/28 Bernard The unify RISC-V porting code.
*/
#ifndef TICK_H__
#define TICK_H__
int tick_isr(void);
int rt_hw_tick_init(void);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册