From 13927be259c9bf42a6a36407212003d6caf02246 Mon Sep 17 00:00:00 2001 From: null <2584456014@qq.com> Date: Mon, 18 Jan 2021 18:54:00 +0800 Subject: [PATCH 01/13] [fix] miss arguments when invoke dist_handle Use this command: `scons --dist-strip` to detach project. but it aborted with error: "TypeError: dist_handle() takes exactly 2 arguments (1 given):" --- tools/mkdist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mkdist.py b/tools/mkdist.py index a1dafd25cb..7765873baa 100644 --- a/tools/mkdist.py +++ b/tools/mkdist.py @@ -218,7 +218,7 @@ def MkDist_Strip(program, BSP_ROOT, RTT_ROOT, Env): if 'dist_handle' in Env: print("=> start dist handle") dist_handle = Env['dist_handle'] - dist_handle(BSP_ROOT) + dist_handle(BSP_ROOT, dist_dir) # get all source files from program for item in program: From 5b7dac8c8e47b12561edbbf0ea8b3b437befa115 Mon Sep 17 00:00:00 2001 From: wanghaijing Date: Fri, 23 Apr 2021 09:52:17 +0800 Subject: [PATCH 02/13] [add] spi config increases irq_type --- bsp/stm32/libraries/HAL_Drivers/config/f0/spi_config.h | 2 ++ bsp/stm32/libraries/HAL_Drivers/config/f1/spi_config.h | 3 +++ bsp/stm32/libraries/HAL_Drivers/config/f2/spi_config.h | 3 +++ bsp/stm32/libraries/HAL_Drivers/config/f4/spi_config.h | 5 +++++ bsp/stm32/libraries/HAL_Drivers/config/f7/spi_config.h | 5 +++++ bsp/stm32/libraries/HAL_Drivers/config/g0/spi_config.h | 2 ++ bsp/stm32/libraries/HAL_Drivers/config/g4/spi_config.h | 5 +++++ bsp/stm32/libraries/HAL_Drivers/config/h7/spi_config.h | 5 +++++ bsp/stm32/libraries/HAL_Drivers/config/l1/spi_config.h | 3 +++ bsp/stm32/libraries/HAL_Drivers/config/l4/spi_config.h | 3 +++ bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h | 5 +++++ bsp/stm32/libraries/HAL_Drivers/config/wb/spi_config.h | 3 +++ bsp/stm32/libraries/HAL_Drivers/config/wl/spi_config.h | 3 +++ bsp/stm32/libraries/HAL_Drivers/drv_spi.c | 6 ++++++ bsp/stm32/libraries/HAL_Drivers/drv_spi.h | 1 + 15 files changed, 54 insertions(+) diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f0/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f0/spi_config.h index 79523e704d..39cda3c5dd 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f0/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f0/spi_config.h @@ -24,6 +24,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -56,6 +57,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f1/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f1/spi_config.h index bf28c2fc72..fb44c6145c 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f1/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f1/spi_config.h @@ -24,6 +24,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -56,6 +57,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -88,6 +90,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f2/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f2/spi_config.h index b3e9507b19..cfe1e252eb 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f2/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f2/spi_config.h @@ -24,6 +24,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -58,6 +59,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -92,6 +94,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f4/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f4/spi_config.h index d03b31ce8a..da3e05d8bd 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f4/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f4/spi_config.h @@ -24,6 +24,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -58,6 +59,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -92,6 +94,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ @@ -126,6 +129,7 @@ extern "C" { { \ .Instance = SPI4, \ .bus_name = "spi4", \ + .irq_type = SPI4_IRQn, \ } #endif /* SPI4_BUS_CONFIG */ #endif /* BSP_USING_SPI4 */ @@ -160,6 +164,7 @@ extern "C" { { \ .Instance = SPI5, \ .bus_name = "spi5", \ + .irq_type = SPI5_IRQn, \ } #endif /* SPI5_BUS_CONFIG */ #endif /* BSP_USING_SPI5 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f7/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f7/spi_config.h index 26f230d9b1..aab36015b9 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f7/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f7/spi_config.h @@ -23,6 +23,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -57,6 +58,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -91,6 +93,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ @@ -125,6 +128,7 @@ extern "C" { { \ .Instance = SPI4, \ .bus_name = "spi4", \ + .irq_type = SPI4_IRQn, \ } #endif /* SPI4_BUS_CONFIG */ #endif /* BSP_USING_SPI4 */ @@ -159,6 +163,7 @@ extern "C" { { \ .Instance = SPI5, \ .bus_name = "spi5", \ + .irq_type = SPI5_IRQn, \ } #endif /* SPI5_BUS_CONFIG */ #endif /* BSP_USING_SPI5 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/g0/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/g0/spi_config.h index a33777977a..a8f60fddbf 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/g0/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/g0/spi_config.h @@ -24,6 +24,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -58,6 +59,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/g4/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/g4/spi_config.h index d03b31ce8a..da3e05d8bd 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/g4/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/g4/spi_config.h @@ -24,6 +24,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -58,6 +59,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -92,6 +94,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ @@ -126,6 +129,7 @@ extern "C" { { \ .Instance = SPI4, \ .bus_name = "spi4", \ + .irq_type = SPI4_IRQn, \ } #endif /* SPI4_BUS_CONFIG */ #endif /* BSP_USING_SPI4 */ @@ -160,6 +164,7 @@ extern "C" { { \ .Instance = SPI5, \ .bus_name = "spi5", \ + .irq_type = SPI5_IRQn, \ } #endif /* SPI5_BUS_CONFIG */ #endif /* BSP_USING_SPI5 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/h7/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/h7/spi_config.h index 26f230d9b1..aab36015b9 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/h7/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/h7/spi_config.h @@ -23,6 +23,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -57,6 +58,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -91,6 +93,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ @@ -125,6 +128,7 @@ extern "C" { { \ .Instance = SPI4, \ .bus_name = "spi4", \ + .irq_type = SPI4_IRQn, \ } #endif /* SPI4_BUS_CONFIG */ #endif /* BSP_USING_SPI4 */ @@ -159,6 +163,7 @@ extern "C" { { \ .Instance = SPI5, \ .bus_name = "spi5", \ + .irq_type = SPI5_IRQn, \ } #endif /* SPI5_BUS_CONFIG */ #endif /* BSP_USING_SPI5 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/l1/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/l1/spi_config.h index bf28c2fc72..fb44c6145c 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/l1/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/l1/spi_config.h @@ -24,6 +24,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -56,6 +57,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -88,6 +90,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/l4/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/l4/spi_config.h index d510ca379d..16fab826d0 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/l4/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/l4/spi_config.h @@ -23,6 +23,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -57,6 +58,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -91,6 +93,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h index 3236751624..d1c6c44cc3 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h @@ -23,6 +23,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -57,6 +58,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -91,6 +93,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ @@ -125,6 +128,7 @@ extern "C" { { \ .Instance = SPI4, \ .bus_name = "spi4", \ + .irq_type = SPI4_IRQn, \ } #endif /* SPI4_BUS_CONFIG */ #endif /* BSP_USING_SPI4 */ @@ -159,6 +163,7 @@ extern "C" { { \ .Instance = SPI5, \ .bus_name = "spi5", \ + .irq_type = SPI5_IRQn, \ } #endif /* SPI5_BUS_CONFIG */ #endif /* BSP_USING_SPI5 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/wb/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/wb/spi_config.h index 0f37cfe2af..1704fcdfe1 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/wb/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/wb/spi_config.h @@ -23,6 +23,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -57,6 +58,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -91,6 +93,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/wl/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/wl/spi_config.h index d510ca379d..64c8e23f07 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/wl/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/wl/spi_config.h @@ -23,6 +23,7 @@ extern "C" { { \ .Instance = SPI1, \ .bus_name = "spi1", \ + .irq_type = SPI1_IRQn, \ } #endif /* SPI1_BUS_CONFIG */ #endif /* BSP_USING_SPI1 */ @@ -57,6 +58,7 @@ extern "C" { { \ .Instance = SPI2, \ .bus_name = "spi2", \ + .irq_type = SPI2_IRQn, \ } #endif /* SPI2_BUS_CONFIG */ #endif /* BSP_USING_SPI2 */ @@ -91,6 +93,7 @@ extern "C" { { \ .Instance = SPI3, \ .bus_name = "spi3", \ + .irq_type = SPI3_IRQn, \ } #endif /* SPI3_BUS_CONFIG */ #endif /* BSP_USING_SPI3 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drv_spi.c index a521e4bb83..44d2d0e418 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_spi.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_spi.c @@ -263,6 +263,12 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur HAL_NVIC_SetPriority(spi_drv->config->dma_tx->dma_irq, 0, 1); HAL_NVIC_EnableIRQ(spi_drv->config->dma_tx->dma_irq); } + + if(spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG || spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) + { + HAL_NVIC_SetPriority(spi_drv->config->irq_type, 2, 0); + HAL_NVIC_EnableIRQ(spi_drv->config->irq_type); + } LOG_D("%s init done", spi_drv->config->bus_name); return RT_EOK; diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_spi.h b/bsp/stm32/libraries/HAL_Drivers/drv_spi.h index f30d97f777..65f752fc8a 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_spi.h +++ b/bsp/stm32/libraries/HAL_Drivers/drv_spi.h @@ -37,6 +37,7 @@ struct stm32_spi_config { SPI_TypeDef *Instance; char *bus_name; + IRQn_Type irq_type; struct dma_config *dma_rx, *dma_tx; }; From 7c074c07171a342ff953b531af4d52b88fd9358e Mon Sep 17 00:00:00 2001 From: wanghaijing Date: Sun, 25 Apr 2021 14:23:05 +0800 Subject: [PATCH 03/13] [remove] incorrect SPI IIC information --- bsp/stm32/stm32f072-st-nucleo/board/Kconfig | 42 +-------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/bsp/stm32/stm32f072-st-nucleo/board/Kconfig b/bsp/stm32/stm32f072-st-nucleo/board/Kconfig index d86ed868ed..d6b07e5bd3 100644 --- a/bsp/stm32/stm32f072-st-nucleo/board/Kconfig +++ b/bsp/stm32/stm32f072-st-nucleo/board/Kconfig @@ -31,8 +31,8 @@ menu "On-chip Peripheral Drivers" bool "Enable UART1 RX DMA" depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA default n - - config BSP_USING_UART2 + + config BSP_USING_UART2 bool "Enable UART2" default y @@ -41,44 +41,6 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA default n endif - - menuconfig BSP_USING_SPI - bool "Enable SPI BUS" - default n - select RT_USING_SPI - if BSP_USING_SPI - config BSP_USING_SPI1 - bool "Enable SPI1 BUS" - default n - - config BSP_SPI1_TX_USING_DMA - bool "Enable SPI1 TX DMA" - depends on BSP_USING_SPI1 - default n - - config BSP_SPI1_RX_USING_DMA - bool "Enable SPI1 RX DMA" - depends on BSP_USING_SPI1 - select BSP_SPI1_TX_USING_DMA - default n - endif - - menuconfig BSP_USING_I2C1 - bool "Enable I2C1 BUS (software simulation)" - default n - select RT_USING_I2C - select RT_USING_I2C_BITOPS - select RT_USING_PIN - if BSP_USING_I2C1 - config BSP_I2C1_SCL_PIN - int "i2c1 scl pin number" - range 1 216 - default 15 - config BSP_I2C1_SDA_PIN - int "I2C1 sda pin number" - range 1 216 - default 16 - endif source "../libraries/HAL_Drivers/Kconfig" endmenu From 1bc204722d7cb0f7b9e2352829f8dd2e59451f73 Mon Sep 17 00:00:00 2001 From: xiaoxiaohuixxh Date: Mon, 26 Apr 2021 13:46:19 +0800 Subject: [PATCH 04/13] [libcpu] Add JuiceVm SUPPORT. --- libcpu/risc-v/juicevm/SConscript | 14 +++++ libcpu/risc-v/juicevm/interrupt.c | 33 ++++++++++ libcpu/risc-v/juicevm/interrupt_gcc.S | 88 +++++++++++++++++++++++++++ libcpu/risc-v/juicevm/startup_gcc.S | 65 ++++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100755 libcpu/risc-v/juicevm/SConscript create mode 100755 libcpu/risc-v/juicevm/interrupt.c create mode 100755 libcpu/risc-v/juicevm/interrupt_gcc.S create mode 100755 libcpu/risc-v/juicevm/startup_gcc.S diff --git a/libcpu/risc-v/juicevm/SConscript b/libcpu/risc-v/juicevm/SConscript new file mode 100755 index 0000000000..20f325b692 --- /dev/null +++ b/libcpu/risc-v/juicevm/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/risc-v/juicevm/interrupt.c b/libcpu/risc-v/juicevm/interrupt.c new file mode 100755 index 0000000000..24b8be7f0c --- /dev/null +++ b/libcpu/risc-v/juicevm/interrupt.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/24 Juice The first version + */ + +#include + +#include + +typedef void (*irq_handler_t)(void); +extern const irq_handler_t isrTable[]; + +uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc, uintptr_t *sp) +{ + uint32_t intNum; + if (mcause & 0x80000000) /* For external interrupt. */ + { + } + else + { + intNum = mcause & 0x1FUL; + /* Now call the real irq handler for intNum */ + if (intNum <= 24) + { + if (isrTable[intNum])isrTable[intNum](); + } + } +} diff --git a/libcpu/risc-v/juicevm/interrupt_gcc.S b/libcpu/risc-v/juicevm/interrupt_gcc.S new file mode 100755 index 0000000000..8406926b5f --- /dev/null +++ b/libcpu/risc-v/juicevm/interrupt_gcc.S @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/24 Juice 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) + +csrr x1, mstatus +STORE x1, 2 * REGBYTES(sp) + +csrr x1, mepc +STORE x1, 0 * 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 + +/* handle interrupt */ +call rt_interrupt_enter +csrr a0, mcause +csrr a1, mepc +mv a2, s0 +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) + +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) + +spurious_interrupt: +tail rt_hw_context_switch_exit diff --git a/libcpu/risc-v/juicevm/startup_gcc.S b/libcpu/risc-v/juicevm/startup_gcc.S new file mode 100755 index 0000000000..1a41c731fb --- /dev/null +++ b/libcpu/risc-v/juicevm/startup_gcc.S @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/24 Juice The first version + */ + + +.global _start +.section ".start", "ax" +_start: +.align 3 +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, 0 +csrs mstatus, t0 + +.option push +.option norelax +la gp, __global_pointer$ +la sp, __stack +call entry +call exit +.option pop From d64a11bb1ebe97623af0e0e170b3061e744d3377 Mon Sep 17 00:00:00 2001 From: xiaoxiaohuixxh Date: Mon, 26 Apr 2021 13:46:22 +0800 Subject: [PATCH 05/13] [bsp/juicevm] Add JuiceVm BSP. --- bsp/juicevm/.config | 441 +++++++++++++++++++++++++ bsp/juicevm/Kconfig | 32 ++ bsp/juicevm/SConscript | 14 + bsp/juicevm/SConstruct | 36 ++ bsp/juicevm/applications/SConscript | 9 + bsp/juicevm/applications/main.c | 20 ++ bsp/juicevm/board/SConscript | 13 + bsp/juicevm/board/board.c | 38 +++ bsp/juicevm/board/board.h | 24 ++ bsp/juicevm/driver/Kconfig | 3 + bsp/juicevm/driver/SConscript | 13 + bsp/juicevm/driver/drv_uart.c | 137 ++++++++ bsp/juicevm/driver/drv_uart.h | 15 + bsp/juicevm/juicevm_sdk/SConscript | 22 ++ bsp/juicevm/juicevm_sdk/rv_config.h | 106 ++++++ bsp/juicevm/juicevm_sdk/rv_mtvec_map.h | 131 ++++++++ bsp/juicevm/juicevm_sdk/system.c | 47 +++ bsp/juicevm/link.lds | 161 +++++++++ bsp/juicevm/link_stacksize.lds | 1 + bsp/juicevm/rtconfig.h | 218 ++++++++++++ bsp/juicevm/rtconfig.py | 59 ++++ 21 files changed, 1540 insertions(+) create mode 100755 bsp/juicevm/.config create mode 100755 bsp/juicevm/Kconfig create mode 100755 bsp/juicevm/SConscript create mode 100755 bsp/juicevm/SConstruct create mode 100755 bsp/juicevm/applications/SConscript create mode 100755 bsp/juicevm/applications/main.c create mode 100755 bsp/juicevm/board/SConscript create mode 100755 bsp/juicevm/board/board.c create mode 100755 bsp/juicevm/board/board.h create mode 100755 bsp/juicevm/driver/Kconfig create mode 100755 bsp/juicevm/driver/SConscript create mode 100755 bsp/juicevm/driver/drv_uart.c create mode 100755 bsp/juicevm/driver/drv_uart.h create mode 100755 bsp/juicevm/juicevm_sdk/SConscript create mode 100755 bsp/juicevm/juicevm_sdk/rv_config.h create mode 100755 bsp/juicevm/juicevm_sdk/rv_mtvec_map.h create mode 100755 bsp/juicevm/juicevm_sdk/system.c create mode 100755 bsp/juicevm/link.lds create mode 100755 bsp/juicevm/link_stacksize.lds create mode 100755 bsp/juicevm/rtconfig.h create mode 100755 bsp/juicevm/rtconfig.py diff --git a/bsp/juicevm/.config b/bsp/juicevm/.config new file mode 100755 index 0000000000..84669e0349 --- /dev/null +++ b/bsp/juicevm/.config @@ -0,0 +1,441 @@ +# +# 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=4 +# 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_IDLE_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_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# 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="uart0" +CONFIG_RT_VER_NUM=0x40000 +CONFIG_ARCH_RISCV=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=2048 +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 is not set +# CONFIG_DFS_USING_WORKDIR is not set +# CONFIG_DFS_FILESYSTEMS_MAX is not set +# CONFIG_DFS_FILESYSTEM_TYPES_MAX is not set +# CONFIG_DFS_FD_MAX is not set +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set + +# +# elm-chan's FatFs, Generic FAT Filesystem Module +# +# CONFIG_RT_DFS_ELM_CODE_PAGE is not set +# CONFIG_RT_DFS_ELM_WORD_ACCESS is not set +# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_3=y +# CONFIG_RT_DFS_ELM_USE_LFN=3 +# CONFIG_RT_DFS_ELM_MAX_LFN=255 +# CONFIG_RT_DFS_ELM_DRIVES=2 +# CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512 +# CONFIG_RT_DFS_ELM_USE_ERASE is not set +# CONFIG_RT_DFS_ELM_REENTRANT=y +# 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 is not set +# 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_SOFT_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=y +# CONFIG_ULOG_OUTPUT_LVL_A is not set +# CONFIG_ULOG_OUTPUT_LVL_E is not set +# CONFIG_ULOG_OUTPUT_LVL_W is not set +# CONFIG_ULOG_OUTPUT_LVL_I is not set +CONFIG_ULOG_OUTPUT_LVL_D=y +CONFIG_ULOG_OUTPUT_LVL=7 +CONFIG_ULOG_USING_ISR_LOG=y +CONFIG_ULOG_ASSERT_ENABLE=y +CONFIG_ULOG_LINE_BUF_SIZE=128 +# CONFIG_ULOG_USING_ASYNC_OUTPUT is not set + +# +# log format +# +# CONFIG_ULOG_OUTPUT_FLOAT is not set +CONFIG_ULOG_USING_COLOR=y +CONFIG_ULOG_OUTPUT_TIME=y +# CONFIG_ULOG_TIME_USING_TIMESTAMP is not set +CONFIG_ULOG_OUTPUT_LEVEL=y +CONFIG_ULOG_OUTPUT_TAG=y +# CONFIG_ULOG_OUTPUT_THREAD_NAME is not set +CONFIG_ULOG_BACKEND_USING_CONSOLE=y +# CONFIG_ULOG_USING_FILTER is not set +# CONFIG_ULOG_USING_SYSLOG is not set +CONFIG_ULOG_SW_VERSION_NUM=0x00101 + +# +# 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=y +CONFIG_PKG_MICROPYTHON_PATH="/packages/language/micropython" + +# +# Hardware Module +# +# CONFIG_MICROPYTHON_USING_MACHINE_I2C is not set +# CONFIG_MICROPYTHON_USING_MACHINE_SPI is not set +CONFIG_MICROPYTHON_USING_MACHINE_UART=y + +# +# System Module +# +CONFIG_MICROPYTHON_USING_UOS=y +CONFIG_MICROPYTHON_USING_THREAD=y +# CONFIG_MICROPYTHON_USING_USELECT is not set +# CONFIG_MICROPYTHON_USING_UCTYPES is not set +# CONFIG_MICROPYTHON_USING_UERRNO is not set + +# +# Tools Module +# +# CONFIG_MICROPYTHON_USING_CMATH is not set +# CONFIG_MICROPYTHON_USING_UBINASCII is not set +# CONFIG_MICROPYTHON_USING_UHASHLIB is not set +# CONFIG_MICROPYTHON_USING_UHEAPQ is not set +CONFIG_MICROPYTHON_USING_UJSON=y +# CONFIG_MICROPYTHON_USING_URE is not set +# CONFIG_MICROPYTHON_USING_UZLIB is not set +# CONFIG_MICROPYTHON_USING_URANDOM is not set + +# +# Network Module +# +# CONFIG_MICROPYTHON_USING_USOCKET is not set +# CONFIG_MICROPYTHON_USING_USSL is not set +CONFIG_PKG_MICROPYTHON_HEAP_SIZE=8192 +CONFIG_PKG_USING_MICROPYTHON_LATEST_VERSION=y +# CONFIG_PKG_USING_MICROPYTHON_V10903 is not set +CONFIG_PKG_MICROPYTHON_VER="latest" + +# +# 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 is not set + +# +# 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 + diff --git a/bsp/juicevm/Kconfig b/bsp/juicevm/Kconfig new file mode 100755 index 0000000000..6e9d5f66cb --- /dev/null +++ b/bsp/juicevm/Kconfig @@ -0,0 +1,32 @@ +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 SOC_JUICEVM_RV64 + bool + select ARCH_RISCV + +config BOARD_RV64_FRDM_JUICEVM + bool + select SOC_JUICEVM_RV64 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +source "driver/Kconfig" diff --git a/bsp/juicevm/SConscript b/bsp/juicevm/SConscript new file mode 100755 index 0000000000..c7ef7659ec --- /dev/null +++ b/bsp/juicevm/SConscript @@ -0,0 +1,14 @@ +# 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') diff --git a/bsp/juicevm/SConstruct b/bsp/juicevm/SConstruct new file mode 100755 index 0000000000..20bae7eee9 --- /dev/null +++ b/bsp/juicevm/SConstruct @@ -0,0 +1,36 @@ +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 + +DefaultEnvironment(tools=[]) +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) diff --git a/bsp/juicevm/applications/SConscript b/bsp/juicevm/applications/SConscript new file mode 100755 index 0000000000..c583d3016e --- /dev/null +++ b/bsp/juicevm/applications/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/juicevm/applications/main.c b/bsp/juicevm/applications/main.c new file mode 100755 index 0000000000..3763ffc133 --- /dev/null +++ b/bsp/juicevm/applications/main.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/26 Juice The first version + */ + +#include +#include +#include + +int main(int argc, char **argv) +{ + rt_kprintf("Hello RT-Thread!\n"); + + return 0; +} diff --git a/bsp/juicevm/board/SConscript b/bsp/juicevm/board/SConscript new file mode 100755 index 0000000000..687045e84c --- /dev/null +++ b/bsp/juicevm/board/SConscript @@ -0,0 +1,13 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Split(''' +board.c +''') +CPPPATH = [cwd] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/juicevm/board/board.c b/bsp/juicevm/board/board.c new file mode 100755 index 0000000000..d2a63a0fc2 --- /dev/null +++ b/bsp/juicevm/board/board.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/22 Juice the first version + */ + +#include +#include + +#include "board.h" +#include "drv_uart.h" + +void rt_hw_board_init(void) +{ + + /* initialize hardware interrupt */ + rt_hw_uart_init(); + // rt_hw_systick_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 +} diff --git a/bsp/juicevm/board/board.h b/bsp/juicevm/board/board.h new file mode 100755 index 0000000000..604dbfc1b6 --- /dev/null +++ b/bsp/juicevm/board/board.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-04-24 Juice the first version + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +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 + 300 * 1024 * 1024) + +void rt_hw_board_init(void); + +#endif diff --git a/bsp/juicevm/driver/Kconfig b/bsp/juicevm/driver/Kconfig new file mode 100755 index 0000000000..dcef494242 --- /dev/null +++ b/bsp/juicevm/driver/Kconfig @@ -0,0 +1,3 @@ +config BSP_USING_UART0 + bool "Enable UART0" + default y \ No newline at end of file diff --git a/bsp/juicevm/driver/SConscript b/bsp/juicevm/driver/SConscript new file mode 100755 index 0000000000..e98c42b6c9 --- /dev/null +++ b/bsp/juicevm/driver/SConscript @@ -0,0 +1,13 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Split(''' +drv_uart.c +''') +CPPPATH = [cwd] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/juicevm/driver/drv_uart.c b/bsp/juicevm/driver/drv_uart.c new file mode 100755 index 0000000000..b4fc7abab9 --- /dev/null +++ b/bsp/juicevm/driver/drv_uart.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/22 Juice Add UART0 support for JuiceVm. + */ + +#include +#include +#include + +#include "board.h" +#include "drv_uart.h" + +#include "rv_mtvec_map.h" + +struct rt_serial_device *serial; +char *device_name = "uart0"; + +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 uart_putc(struct rt_serial_device *serial, char c); +static int uart_getc(struct rt_serial_device *serial); +static rt_size_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction); + +void UART0_DriverIRQHandler(void); + +const struct rt_uart_ops _uart_ops = +{ + uart_configure, + uart_control, + uart_putc, + uart_getc, + uart_dma_transmit +}; + +static void uart_isr(struct rt_serial_device *serial); + +#if defined(BSP_USING_UART0) +struct rt_serial_device serial0; + +void UART0_DriverIRQHandler(void) +{ + uart_isr(&serial0); +} +#endif + + + +/* + * UART Initiation + */ +int rt_hw_uart_init(void) +{ + int i; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + serial = &serial0; + serial->ops = &_uart_ops; + serial->config = config; + + /* register UART device */ + rt_hw_serial_register(serial, + device_name, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + (void *)0); + + return 0; +} + +/* + * UART interface + */ +static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + return RT_EOK; +} + +static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + RT_ASSERT(serial != RT_NULL); + + return RT_EOK; +} + +static int uart_putc(struct rt_serial_device *serial, char c) +{ + + RT_ASSERT(serial != RT_NULL); + + *((char *)(pdev_uart0_write_addr)) = c; + + return (1); +} + +static int uart_getc(struct rt_serial_device *serial) +{ + int ch; + + RT_ASSERT(serial != RT_NULL); + + ch = -1; + + if (*(char *)(pdev_uart0_state_addr) == pdev_uart0_readbusy_state) + { + ch = *(char *)(pdev_uart0_read_addr); + *(char *)(pdev_uart0_state_addr) = pdev_uart0_free_state; + } + return ch; +} + +static rt_size_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction) +{ + return (0); +} + +/* UART ISR */ +/** + * Uart common interrupt process. This need add to uart ISR. + * + * @param serial serial device + */ +static void uart_isr(struct rt_serial_device *serial) +{ + RT_ASSERT(serial != RT_NULL); + + if (*(char *)(pdev_uart0_state_addr) == pdev_uart0_readbusy_state) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + } +} diff --git a/bsp/juicevm/driver/drv_uart.h b/bsp/juicevm/driver/drv_uart.h new file mode 100755 index 0000000000..d0f72a33f0 --- /dev/null +++ b/bsp/juicevm/driver/drv_uart.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#ifndef __DRV_UART_H__ +#define __DRV_UART_H__ + +int rt_hw_uart_init(void); + +#endif /* __DRV_UART_H__ */ diff --git a/bsp/juicevm/juicevm_sdk/SConscript b/bsp/juicevm/juicevm_sdk/SConscript new file mode 100755 index 0000000000..a75c73524a --- /dev/null +++ b/bsp/juicevm/juicevm_sdk/SConscript @@ -0,0 +1,22 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Split(''' +system.c +''') +CPPPATH = [cwd] + + +group = DefineGroup('JuiceVm_sdk', src, depend = [''], CPPPATH = CPPPATH) + +objs = [group] + +list = os.listdir(cwd) + +for item in list: + if os.path.isfile(os.path.join(cwd, item, 'SConscript')): + objs = objs + SConscript(os.path.join(item, 'SConscript')) + +Return('objs') diff --git a/bsp/juicevm/juicevm_sdk/rv_config.h b/bsp/juicevm/juicevm_sdk/rv_config.h new file mode 100755 index 0000000000..a827963388 --- /dev/null +++ b/bsp/juicevm/juicevm_sdk/rv_config.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2006-2021, JuiceVm Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/22 Juice the first version + */ + + +#ifndef __RV_CONFIG_H__ +#define __RV_CONFIG_H__ + +#define RV64I_SUPPORT_ENBALE +#define RV64_MMU_ENBALE 1 + +#define RV_ENDLESS_LOOP_CHECK_ENBALE 1 +#if defined(RV_ENDLESS_LOOP_CHECK_ENBALE) && RV_ENDLESS_LOOP_CHECK_ENBALE == 1 + #define RV_ENDLESS_LOOP_CHECK_BUF_SIZE (30) + #define RV_ENDLESS_LOOP_CHECK_EXIT_CNT (3) + #define RV_ENDLESS_LOOP_CHECK_MD5_HASH 1 +#endif + +// #define RISCV_ANGEL_ONLY +#define Machine_Mode_SUPPORT +#define Supervisor_Mode_SUPPORT +// #define User_Mode_SUPPORT +// #define Hypervisor_Mode_SUPPORT + +#define ATOMIC_Module_SUPPORT + +#define RV_CPU_CSR_DEF_Vendor_ID 0 +#define RV_CPU_CSR_DEF_March_ID 0 +#define RV_CPU_CSR_DEF_Mimp_ID 0 +#define RV_CPU_CSR_DEF_Mhart_ID 0 + +#define JUICE_VM_LOG_MAX_NUM (600) + +#define JUICE_VM_INC_CHANGELOG 0 + +#define RAM_SIZE_KB (1024) +#define RAM_SIZE_MB (1024*RAM_SIZE_KB) + +#define RV_CPU_SIM_RAM_START_ADDR (0x80000000) +#define RV_CPU_SIM_RAM_SIZE (300 * RAM_SIZE_MB) + +#define RV_CPU_SIM_CAUSETABLE_MAX_NUM 100//MXLEN-1 bit + +#define RV_CPU_SIM_PERDEV_NUM 50 +#define rv_peripheral_device_add_check_dev 1 + +// | MXLEN-1 MXLEN-2 | MXLEN-3 26| 25 0 | +// | MXL[1:0](WARL) | WLRL | Extensions[25:0] (WARL) | +// | 2 | MXLEN-28 | 26 | +// Figure 3.1: Machine ISA register (misa). + + + +// Bit | Character | Description +// 0 | A | Atomic extension +// 1 | B | Tentatively reserved for Bit-Manipulation extension +// 2 | C | Compressed extension +// 3 | D | Double-precision floating-point extension +// 4 | E | RV32E base ISA +// 5 | F | Single-precision floating-point extension +// 6 | G | Reserved +// 7 | H | Hypervisor extension +// 8 | I | RV32I/64I/128I base ISA +// 9 | J | Tentatively reserved for Dynamically Translated Languages extension +// 10 | K | Reserved +// 11 | L | Tentatively reserved for Decimal Floating-Point extension +// 12 | M | Integer Multiply/Divide extension +// 13 | N | User-level interrupts supported +// 14 | O | Reserved +// 15 | P | Tentatively reserved for Packed-SIMD extension +// 16 | Q | Quad-precision floating-point extension +// 17 | R | Reserved +// 18 | S | Supervisor mode implemented +// 19 | T | Tentatively reserved for Transactional Memory extension +// 20 | U | User mode implemented +// 21 | V | Tentatively reserved for Vector extension +// 22 | W | Reserved +// 23 | X | Non-standard extensions present +// 24 | Y | Reserved +// 25 | Z | Reserved +#define RV_MISA_ATOMIC_EXT (1<<0) +#define RV_MISA_INTEGER_EXT (1<<8) +#define RV_MISA_UMODE_INT_EXT (1<<13) +#define RV_MISA_SMODE_IMP_EXT (1<<18) +#define RV_MISA_UMODE_IMP_EXT (1<<20) + +// | MXL | XLEN | +// | 1 | 32 | +// | 2 | 64 | +// | 3 | 128 | +#define RV_MISA_XLEN_32 (1<<(32-2)) +#define RV_MISA_XLEN_64 (uint64_t)((uint64_t)(2)<<(64-2)) +// #define RV_MISA_XLEN_128 ((uint128_t)(3)<<(128-2)) + + + +#define RV_MISA_CSR_REGISTER ((uint64_t)(RV_MISA_XLEN_64 | RV_MISA_ATOMIC_EXT | RV_MISA_INTEGER_EXT /*| RV_MISA_UMODE_INT_EXT*/ | RV_MISA_SMODE_IMP_EXT /*| RV_MISA_UMODE_IMP_EXT*/)) + + +#endif // __RV_CONFIG_H__ diff --git a/bsp/juicevm/juicevm_sdk/rv_mtvec_map.h b/bsp/juicevm/juicevm_sdk/rv_mtvec_map.h new file mode 100755 index 0000000000..a4f3ef65cd --- /dev/null +++ b/bsp/juicevm/juicevm_sdk/rv_mtvec_map.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2006-2021, JuiceVm Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/22 Juice the first version + */ +#ifndef __RV_MTVEC_MAP_H__ +#define __RV_MTVEC_MAP_H__ +#include "rv_config.h" + +#define rv_sim_pdev_base_addr (RV_CPU_SIM_RAM_START_ADDR+RV_CPU_SIM_RAM_SIZE) +#define rv_sim_pdev_uart0_base_addr (rv_sim_pdev_base_addr) +#define pdev_uart0_write_addr (rv_sim_pdev_uart0_base_addr) +#define pdev_uart0_read_addr (rv_sim_pdev_uart0_base_addr+1) +#define pdev_uart0_free_state 0x00 +#define pdev_uart0_readbusy_state 0x01 +#define pdev_uart0_state_addr (rv_sim_pdev_uart0_base_addr+2) + +#define rv_sim_pdev_mtime_base_addr (rv_sim_pdev_base_addr+3) +#define pdev_mtime_mtime_addr (rv_sim_pdev_mtime_base_addr) +#define pdev_mtime_mtimecmp_addr (rv_sim_pdev_mtime_base_addr+4) + +#define uart0_irq_flag 0 +#define uart0_irq_ecode 24 + +#define RV_exception_Instruction_address_misaligned_IFLAG 0 +#define RV_exception_Instruction_address_misaligned_ECODE 0 +#define RV_exception_Instruction_access_fault_IFLAG 0 +#define RV_exception_Instruction_access_fault_ECODE 1 +#define RV_exception_Illegal_Instruction_IFLAG 0 +#define RV_exception_Illegal_Instruction_ECODE 2 +#define RV_exception_Breakpoint_IFLAG 0 +#define RV_exception_Breakpoint_ECODE 3 +#define RV_exception_LoadAddress_Misaligned_IFLAG 0 +#define RV_exception_LoadAddress_Misaligned_ECODE 4 +#define RV_exception_Load_access_fault_IFLAG 0 +#define RV_exception_Load_access_fault_ECODE 5 + +#define RV_exception_Store_or_AMO_Address_Misaligned_IFLAG 0 +#define RV_exception_Store_or_AMO_Address_Misaligned_ECODE 6 + +#define RV_exception_Store_or_AMO_access_fault_IFLAG 0 +#define RV_exception_Store_or_AMO_access_fault_ECODE 7 + +#define RV_exception_Environment_call_from_Umode_IFLAG 0 +#define RV_exception_Environment_call_from_Umode_ECODE 8 + +#define RV_exception_Environment_call_from_Smode_IFLAG 0 +#define RV_exception_Environment_call_from_Smode_ECODE 9 + +#define RV_exception_Environment_Call_FromMachine_IFLAG 0 +#define RV_exception_Environment_Call_FromMachine_ECODE 11 + +#define RV_exception_FloatingPoint_Disabled_IFLAG +#define RV_exception_FloatingPoint_Disabled_ECODE + +#define RV_exception_Instruction_page_fault_IFLAG 0 +#define RV_exception_Instruction_page_fault_ECODE 12 +#define RV_exception_Load_page_fault_IFLAG 0 +#define RV_exception_Load_page_fault_ECODE 13 + +#define RV_exception_Store_or_AMO_page_fault_IFLAG 0 +#define RV_exception_Store_or_AMO_page_fault_ECODE 15 + + +// Interrupt Exception Code Description +// 1 0 Reserved +// 1 1 Supervisor software interrupt not support +// 1 2 Reserved +// 1 3 Machine software interrupt not support +// 1 4 Reserved +// 1 5 Supervisor timer interrupt not support +// 1 6 Reserved +// 1 7 Machine timer interrupt support +// 1 8 Reserved +// 1 9 Supervisor external interrupt not support +// 1 10 Reserved +// 1 11 Machine external interrupt not support +// 1 12 Reserved +// 1 13 Reserved +// 1 14 Reserved +// 1 15 Reserved +// // 1 ≥16 Designated for platform use +// 0 0 Instruction address misaligned not support +// 0 1 Instruction access fault not support +// 0 2 Illegal instruction support +// 0 3 Breakpoint support +// 0 4 Load address misaligned support +// 0 5 Load access fault not support +// 0 6 Store/AMO address misaligned support +// 0 7 Store/AMO access fault not support +// 0 8 Environment call from U-mode not support +// 0 9 Environment call from S-mode not support +// 0 10 Reserved +// 0 11 Environment call from M-mode support +// 0 12 Instruction page fault not support +// 0 13 Load page fault not support +// 0 14 Reserved +// 0 15 Store/AMO page fault not support +// 0 16-23 Reserved +// // 0 24–31 Designated for custom use +// 0 32-47 Reserved +// // 0 48–63 Designated for custom use +// 0 ≥64 Reserved + + +// #define mtime_irq_flag 1 +// #define mtime_irq_ecode 7 + +#define RV_Supervisor_software_interrupt_IFLAG 1 +#define RV_Supervisor_software_interrupt_ECODE 1 + +#define RV_Machine_software_interrupt_IFLAG 1 +#define RV_Machine_software_interrupt_ECODE 3 + +#define RV_Supervisor_timer_interrupt_IFLAG 1 +#define RV_Supervisor_timer_interrupt_ECODE 5 + +#define RV_Machine_timer_interrupt_IFLAG 1 +#define RV_Machine_timer_interrupt_ECODE 7 + +#define RV_Supervisor_external_interrupt_IFLAG 1 +#define RV_Supervisor_external_interrupt_ECODE 9 + +#define RV_Machine_external_interrupt_IFLAG 1 +#define RV_Machine_external_interrupt_ECODE 10 + +#endif // __RV_MTVEC_MAP_H__ diff --git a/bsp/juicevm/juicevm_sdk/system.c b/bsp/juicevm/juicevm_sdk/system.c new file mode 100755 index 0000000000..8cb1ac667b --- /dev/null +++ b/bsp/juicevm/juicevm_sdk/system.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/22 Juice Add isrtable for JuiceVm. + */ +typedef void (*irq_handler_t)(void); +// #define DEFINE_IRQ_HANDLER(irq_handler, driver_irq_handler) \ +// void __attribute__((weak)) irq_handler(void) { driver_irq_handler();} + +// #define DEFINE_DEFAULT_IRQ_HANDLER(irq_handler) void irq_handler() __attribute__((weak, alias("DefaultIRQHandler"))) + +// DEFINE_IRQ_HANDLER(UART0_IRQHandler, UART0_DriverIRQHandler); +extern void UART0_DriverIRQHandler(void); + +const irq_handler_t isrTable[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + UART0_DriverIRQHandler, // uart0_irq_ecode = 24 + +}; diff --git a/bsp/juicevm/link.lds b/bsp/juicevm/link.lds new file mode 100755 index 0000000000..b96558d7cd --- /dev/null +++ b/bsp/juicevm/link.lds @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2006-2021, 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 +{ + /* 300M SRAM */ + SRAM : ORIGIN = 0x80000000, LENGTH = 0x12c00000 +} + +ENTRY(_start) +SECTIONS +{ + . = 0x80000000 ; + + /* __STACKSIZE__ = 4096; */ + + .start : + { + *(.start); + } > SRAM + + . = ALIGN(8); + + .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(8); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(8); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(8); + + /* section information for initial. */ + . = ALIGN(8); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(8); + + __rt_utest_tc_tab_start = .; + KEEP(*(UtestTcTab)) + __rt_utest_tc_tab_end = .; + + . = ALIGN(8); + _etext = .; + } > SRAM + + .eh_frame_hdr : + { + *(.eh_frame_hdr) + *(.eh_frame_entry) + } > SRAM + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > SRAM + + . = ALIGN(8); + + .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 = .; + } > 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) } +} diff --git a/bsp/juicevm/link_stacksize.lds b/bsp/juicevm/link_stacksize.lds new file mode 100755 index 0000000000..1dd893422c --- /dev/null +++ b/bsp/juicevm/link_stacksize.lds @@ -0,0 +1 @@ +__STACKSIZE__ = 4096; \ No newline at end of file diff --git a/bsp/juicevm/rtconfig.h b/bsp/juicevm/rtconfig.h new file mode 100755 index 0000000000..b2f2cfde3d --- /dev/null +++ b/bsp/juicevm/rtconfig.h @@ -0,0 +1,218 @@ +#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 4 +#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_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 1024 +#define RT_DEBUG +#define RT_DEBUG_COLOR + +/* 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 "uart0" +#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 2048 +#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_ELMFAT + +/* elm-chan's FatFs, Generic FAT Filesystem Module */ + +// #define RT_DFS_ELM_CODE_PAGE 437 +// #define RT_DFS_ELM_WORD_ACCESS +// #define RT_DFS_ELM_USE_LFN_3 +// #define RT_DFS_ELM_USE_LFN 3 +// #define RT_DFS_ELM_MAX_LFN 255 +// #define RT_DFS_ELM_DRIVES 2 +// #define RT_DFS_ELM_MAX_SECTOR_SIZE 512 +// #define RT_DFS_ELM_REENTRANT +// #define RT_USING_DFS_DEVFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SERIAL + +/* 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 */ + +#define RT_USING_ULOG +#define ULOG_OUTPUT_LVL_D +#define ULOG_OUTPUT_LVL 7 +#define ULOG_USING_ISR_LOG +#define ULOG_ASSERT_ENABLE +#define ULOG_LINE_BUF_SIZE 128 + +/* log format */ + +#define ULOG_USING_COLOR +#define ULOG_OUTPUT_TIME +#define ULOG_OUTPUT_LEVEL +#define ULOG_OUTPUT_TAG +#define ULOG_BACKEND_USING_CONSOLE +#define ULOG_SW_VERSION_NUM 0x00101 + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +#define PKG_USING_MICROPYTHON + +/* Hardware Module */ + +#define MICROPYTHON_USING_MACHINE_UART + +/* System Module */ + +#define MICROPYTHON_USING_UOS +#define MICROPYTHON_USING_THREAD + +/* Tools Module */ + +#define MICROPYTHON_USING_UJSON + +/* Network Module */ + +#define PKG_MICROPYTHON_HEAP_SIZE 8192 +#define PKG_USING_MICROPYTHON_LATEST_VERSION + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* sample package */ + +/* samples: kernel and components samples */ + + +/* example package: hello */ + + +/* Privated Packages of RealThread */ + + +/* Network Utilities */ + +#define BSP_USING_UART0 +#define __STACKSIZE__ 4096 + +#endif diff --git a/bsp/juicevm/rtconfig.py b/bsp/juicevm/rtconfig.py new file mode 100755 index 0000000000..9f0307cba1 --- /dev/null +++ b/bsp/juicevm/rtconfig.py @@ -0,0 +1,59 @@ +import os + +# toolchains options +ARCH ='risc-v' +CPU ='juicevm' +CROSS_TOOL ='gcc' + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = r'../..' + +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-8.3.0-2020.04.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 = 'debug' + +if PLATFORM == 'gcc': + # toolchains + 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 = ' -march=rv64ima -mabi=lp64 -mcmodel=medany' + CFLAGS = DEVICE + ' -fno-builtin -fno-exceptions -ffunction-sections -static' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T link.lds' + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O2 -Os -g' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2 -Os' + + CXXFLAGS = CFLAGS + +DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' +POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' +POST_ACTION += DUMP_ACTION +# POST_ACTION = SIZE + ' $TARGET \n' From 19347ed454621161caf4186f1a52ec656c3dc58f Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Mon, 26 Apr 2021 14:31:31 +0800 Subject: [PATCH 06/13] =?UTF-8?q?[libc][unistd]=20=E5=AE=8C=E5=96=84isatty?= =?UTF-8?q?()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/libc/compilers/common/unistd.c | 26 +++++++++++++++++---- components/libc/compilers/newlib/syscalls.c | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/components/libc/compilers/common/unistd.c b/components/libc/compilers/common/unistd.c index 20130cbb8a..6c81fc7662 100644 --- a/components/libc/compilers/common/unistd.c +++ b/components/libc/compilers/common/unistd.c @@ -15,18 +15,29 @@ #ifdef RT_USING_POSIX_TERMIOS #include "termios.h" - int isatty(int fd) { struct termios ts; - return(tcgetattr(fd,&ts) != -1);/*true if no error (is a tty)*/ + return(tcgetattr(fd, &ts) != -1); /*true if no error (is a tty)*/ +} +#else +int isatty(int fd) +{ + if (fd >=0 && fd < 3) + { + return 1; + } + else + { + return 0; + } } -RTM_EXPORT(isatty); #endif +RTM_EXPORT(isatty); char *ttyname(int fd) { - return "/dev/tty0"; /*TODO: need to add more specific*/ + return "/dev/tty"; /*TODO: need to add more specific*/ } RTM_EXPORT(ttyname); @@ -50,11 +61,16 @@ int usleep(useconds_t usec) } RTM_EXPORT(usleep); -pid_t getpid(void) +pid_t gettid(void) { /*TODO*/ return 0; } + +pid_t getpid(void) +{ + return gettid(); +} RTM_EXPORT(getpid); pid_t getppid(void) diff --git a/components/libc/compilers/newlib/syscalls.c b/components/libc/compilers/newlib/syscalls.c index 6cbc11fd6a..7c5d51eca6 100644 --- a/components/libc/compilers/newlib/syscalls.c +++ b/components/libc/compilers/newlib/syscalls.c @@ -98,6 +98,7 @@ _isatty_r(struct _reent *ptr, int fd) return 0; } } + int _kill_r(struct _reent *ptr, int pid, int sig) { From cb7fa8fceaf5b9e2aacaee132ce5bb0ad49c92aa Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Mon, 26 Apr 2021 14:34:26 +0800 Subject: [PATCH 07/13] implement pid_t gettid(void) --- components/libc/compilers/common/none-gcc/sys/unistd.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/components/libc/compilers/common/none-gcc/sys/unistd.h b/components/libc/compilers/common/none-gcc/sys/unistd.h index 7752a1caf7..2f01f660b3 100644 --- a/components/libc/compilers/common/none-gcc/sys/unistd.h +++ b/components/libc/compilers/common/none-gcc/sys/unistd.h @@ -66,13 +66,11 @@ #endif - int isatty (int fd); char * ttyname (int desc); - unsigned int sleep(unsigned int seconds); int usleep(useconds_t usec); - +pid_t gettid(void); pid_t getpid(void); pid_t getppid(void); uid_t getuid(void); From a87e33db3f9fcfb12baabd57499431bf817a74ab Mon Sep 17 00:00:00 2001 From: xiaoxiaohuixxh Date: Mon, 26 Apr 2021 14:48:20 +0800 Subject: [PATCH 08/13] [bsp/juicevm] ADD README.md --- bsp/juicevm/README.md | 162 +++++++++++++++++++++++++++++ bsp/juicevm/rtconfig.py | 4 +- bsp/juicevm/static/juicevm_rtt.jpg | Bin 0 -> 158676 bytes 3 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 bsp/juicevm/README.md create mode 100644 bsp/juicevm/static/juicevm_rtt.jpg diff --git a/bsp/juicevm/README.md b/bsp/juicevm/README.md new file mode 100644 index 0000000000..f791720fdb --- /dev/null +++ b/bsp/juicevm/README.md @@ -0,0 +1,162 @@ +# JuiceVm 虚拟机 BSP 说明 + +标签: Risc-V 64bit ima、JuiceVm + +--- + +## 简介 + +本文档为 JuiceVm 开发团队为 JuiceVm 虚拟机提供的 BSP (板级支持包) 说明。 + +主要内容如下: + +- 开发板资源介绍 +- BSP 快速上手 +- 进阶使用方法 + +通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。在进阶使用指南章节,将会介绍更多高级功能,帮助开发者利用 RT-Thread 驱动更多板载资源。 + +## 虚拟机介绍 + +JuiceVm 虚拟机是 juice 开发的一款 Risc-V 64bit ima 虚拟机,Risc-V 64bit 虚拟机界面如下图所示: + +![开发板外观](static/juicevm_rtt.jpg) + +该虚拟机常用**资源**如下: + +- MCU:Risc-V 64bit ima,300MB RAM,支持M-MODE,S-MODE, +- 常用外设 + - UART0 +- 常用接口:UART +- 调试接口: 标准 GDB 【TODO】 + +更多详细信息请参考【Juice】[JuiceVm 虚拟机](https://whycan.com/t_5844.html)。 + +## 外设支持 + +本 BSP 目前对外设的支持情况如下: + +|**片上外设** |**支持情况**|**备注** | +| :----------------- | :----------: | :-----------------------------------| +| GPIO | 暂不支持 | 即将支持 | +| MMU(SV39) | 暂不支持 | 即将支持 | +| UART | 支持 | UART0 | +| SDIO | 暂不支持 | 即将支持 | +| RTC | 暂不支持 | 即将支持 | +| PWM | 暂不支持 | 即将支持 | +| USB Device | 暂不支持 | 即将支持 | +| USB Host | 暂不支持 | 即将支持 | + +## 使用说明 + +使用说明分为如下两个章节: + +- 快速上手 + + 本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。 + +- 进阶使用 + + 本章节是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。 + +### 快速上手 + +本 BSP 为开发者提供 GCC 开发环境。下面以 GCC 开发环境为例,介绍如何将系统运行起来。 + +#### 编译下载 +##### toolchain 下载 +- 到 xpack-dev-tools 下载 [点击跳转](https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/tag/v8.3.0-2.1) + ``` + wget https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v8.3.0-2.1/xpack-riscv-none-embed-gcc-8.3.0-2.1-linux-x64.tar.gz + ``` +- 解压到/opt目录下 + ``` + tar vxf xpack-riscv-none-embed-gcc-8.3.0-2.1-linux-x64.tar.gz -C /opt + ``` +- 到rt-thread/bsp/juicevm目录下执行 + ``` + scons + ``` +- 下载 JuiceVm +浏览器打开: +https://whycan.com/files/members/1390/juice_vm_release_for_Linux_57ba985a.zip + +- 运行固件 + ./juice_vm_for_Linux.out -a -g ./rtthread.bin + +#### 运行结果 + +在console可以看到 RT-Thread 的输出信息: + +```c +global_vm_log_init output_mode_sel: 0 JUICE_VM_LOG_MAX_NUM:600 + gg ,ggg, gg ,a8a, ,gggg, ,ggggggg, ,ggg, ,g,ggg, ,ggg,_,ggg, + dP8dP Y8a 88 ,8 8, ,88 Y8b,dP Y8dP Y8a ,8dP Y8dP Y88P Y8b + dP YYb, `88 88 d8 8b d8 `Yd8' a YYb, `88 d8Yb, `88' `88' `88 + ,8 `8` 88 88 88 88d8' 8b d88 Y8P'` 88 88 ` 88 88 88 + I8 Yb 88 88 88 8,8I Y88P`8baaaa 88 88 88 88 88 + `8b, `8, 88 88 Y8 8I8' ,d8P I8 8I 88 88 88 + ` Y88888 88 88 `8, ,8d8 d8 `8, ,8' 88 88 88 + Y8 88 888888 8,8 Y8, Y8, Y8, ,8P 88 88 88 + ,88,Y8b,____,d88`8b, ,d8b,`Yba,,_____`Yba,,_____, Yb,_,dP 88 88 Y8, + ,ad88888 Y888888P Y8 Y88P Y8 ` Y8888888 ` Y8888888 Y8P 88 88 `Y8 + ,dP ' Yb + ,8' I8 + ,8' I8 + I8, ,8' + `Y8,___,d8' + Y888P + email: juicemail@163.com +version:57ba985a 57ba985a Fri, 23 Apr 2021 17:22:20 +0800 xiaoxiaohuixxh feat(Rt-thread): uart port pass +firm_addr:./rtthread.bin +fd = 3 +file_size = 44872 +interrupt_vertor_register_mag_init +rv_csr_register_init +csr_addr_misa 8000000000040101 +csr_addr_mvendorid 0000000000000000 +csr_addr_marchid 0000000000000000 +csr_addr_mimpid 0000000000000000 +csr_addr_mhartid 0000000000000000 +rv_peripheral_device_init +[rv64_sim][dev][mmu]rv.c(5593):rv_peripheral_device_mmu_init,Sv39 mode support only +[rv64_sim][dev][mtime]rv.c(5252):rv_peripheral_device_mtime_init +[rv64_sim][dev][mtime]rv.c(5271):pdev_mtime_irq_info 0x7f334d2d0910 92c00003 92c00007 +[rv64_sim][dev][mtime]rv.c(5277):pdev_mtime_irq_info_smode 0x7f334d2d0900 92c00003 92c00007 +[rv64_sim][dev][uart0]rv.c(5061):rv_peripheral_device_uart0_init +[rv64_sim][dev][uart0]rv.c(5077):pdev_uart0_irq_info 0x7f334d2d08f0 +rv sim start...loading +cpu run... +heap: [0x8000cb60 - 0x92c00000] + + \ | / +- RT - Thread Operating System + / | \ 4.0.3 build Apr 26 2021 + 2006 - 2021 Copyright by rt-thread team +Hello RT-Thread! +msh > +``` + +### 进阶使用 + +此 BSP 默认只开启了 UART0 的功能和直接运行功能 +如果需使用更多功能,可以执行 +``` +./juice_vm_for_Linux.out +``` +查看相关帮助信息开启调试和实时汇编输出功能 +## 注意事项 + +编译参数请使用rv64ima,暂不支持Risc-V的c模块 + +## 维护人信息 + +- [Juice](https://github.com/xiaoxiaohuixxh) +- [邮箱](juicemail@163.com) + +## 参考资料 + +* [RT-Thread 文档中心](https://www.rt-thread.org/document/site/) + +* [JuiceVm 虚拟机更新发布页](https://whycan.com/t_5844.html) + diff --git a/bsp/juicevm/rtconfig.py b/bsp/juicevm/rtconfig.py index 9f0307cba1..3091df663f 100755 --- a/bsp/juicevm/rtconfig.py +++ b/bsp/juicevm/rtconfig.py @@ -15,7 +15,7 @@ if os.getenv('RTT_CC'): if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - EXEC_PATH = r'/opt/riscv64-unknown-elf-gcc-8.3.0-2020.04.0-x86_64-linux-ubuntu14/bin' + EXEC_PATH = r'/opt/xpack-riscv-none-embed-gcc-8.3.0-2.1/bin' else: print('Please make sure your toolchains is GNU GCC!') exit(0) @@ -27,7 +27,7 @@ BUILD = 'debug' if PLATFORM == 'gcc': # toolchains - PREFIX = 'riscv64-unknown-elf-' + PREFIX = 'riscv-none-embed-' CC = PREFIX + 'gcc' CXX = PREFIX + 'g++' AS = PREFIX + 'gcc' diff --git a/bsp/juicevm/static/juicevm_rtt.jpg b/bsp/juicevm/static/juicevm_rtt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aa721c70c4563ec0e0864b847e06e102fc15cad5 GIT binary patch literal 158676 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≺UsoKJa9n+?oUrq-(rAhBR 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%0D* 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�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 %SaSkEicpGtL(AsbP#2P_2T;YdG*C`Da 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 Date: Mon, 26 Apr 2021 14:57:26 +0800 Subject: [PATCH 09/13] [bsp][simulator]delete tap_netif.c --- bsp/simulator/drivers/SConscript | 4 +- bsp/simulator/drivers/tap_netif.c | 791 ------------------------------ 2 files changed, 1 insertion(+), 794 deletions(-) delete mode 100644 bsp/simulator/drivers/tap_netif.c diff --git a/bsp/simulator/drivers/SConscript b/bsp/simulator/drivers/SConscript index 593a3fdfdc..2fd17ddf80 100644 --- a/bsp/simulator/drivers/SConscript +++ b/bsp/simulator/drivers/SConscript @@ -26,10 +26,8 @@ if GetDepend('RT_USING_DFS') == False or GetDepend('RT_USING_DFS_WINSHAREDIR') = SrcRemove(src, 'dfs_win32.c') if GetDepend('RT_USING_DFS') == False or GetDepend('RT_USING_MODULE') == False: SrcRemove(src, ['module_win32.c']) -if GetDepend('RT_USING_TAPNETIF') == False: - SrcRemove(src, ['tap_netif.c']) if sys.platform[0:5]=="linux": #check whether under linux - SrcRemove(src, ['module_win32.c', 'dfs_win32.c', 'tap_netif.c']) + SrcRemove(src, ['module_win32.c', 'dfs_win32.c']) group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, LIBS=LIBS, LIBPATH=LIBPATH) diff --git a/bsp/simulator/drivers/tap_netif.c b/bsp/simulator/drivers/tap_netif.c deleted file mode 100644 index 8bac666cc0..0000000000 --- a/bsp/simulator/drivers/tap_netif.c +++ /dev/null @@ -1,791 +0,0 @@ -/* - * TAP-Win32 -- A kernel driver to provide virtual tap device functionality - * on Windows. Originally derived from the CIPE-Win32 - * project by Damion K. Wilson, with extensive modifications by - * James Yonan. - * - * All source code which derives from the CIPE-Win32 project is - * Copyright (C) Damion K. Wilson, 2003, and is released under the - * GPL version 2 (see below). - * - * All other source code is Copyright (C) James Yonan, 2003-2004, - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, see . - */ - -#include -#include -#include -#include -#include - -#define MAX_ADDR_LEN 6 -#define TAP_IFNAME "RT-net" - -//============= -// TAP IOCTLs -//============= - -#define TAP_CONTROL_CODE(request,method) \ - CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) - -#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) -#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) -#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) -#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) -#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) -#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) -#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) - -//================= -// Registry keys -//================= - -#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" - -#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" - -//====================== -// Filesystem prefixes -//====================== - -#define USERMODEDEVICEDIR "\\\\.\\Global\\" -#define TAPSUFFIX ".tap" - -//====================== -// Compile time configuration -//====================== - -//#define DEBUG_TAP_WIN32 - -#define TUN_ASYNCHRONOUS_WRITES 1 - -#define TUN_BUFFER_SIZE 1560 -#define TUN_MAX_BUFFER_COUNT 32 - -/* - * The data member "buffer" must be the first element in the tun_buffer - * structure. See the function, tap_win32_free_buffer. - */ -typedef struct tun_buffer_s { - unsigned char buffer [TUN_BUFFER_SIZE]; - unsigned long read_size; - struct tun_buffer_s* next; -} tun_buffer_t; - -typedef struct tap_win32_overlapped { - HANDLE handle; - HANDLE read_event; - HANDLE write_event; - HANDLE output_queue_semaphore; - HANDLE free_list_semaphore; - HANDLE tap_semaphore; - CRITICAL_SECTION output_queue_cs; - CRITICAL_SECTION free_list_cs; - OVERLAPPED read_overlapped; - OVERLAPPED write_overlapped; - tun_buffer_t buffers[TUN_MAX_BUFFER_COUNT]; - tun_buffer_t* free_list; - tun_buffer_t* output_queue_front; - tun_buffer_t* output_queue_back; -} tap_win32_overlapped_t; - -static tap_win32_overlapped_t tap_overlapped; - -/************************************************************************/ -/* RT-Thread Network Interface */ -/************************************************************************/ -struct tap_netif -{ - /* inherit from ethernet device */ - struct eth_device parent; - - tap_win32_overlapped_t *handle; - - /* interface address info. */ - rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ -}; -#define NETIF_DEVICE(netif) ((struct tap_netif*)(netif)) -#define NETIF_TAP(netif) (NETIF_DEVICE(netif)->handle) - -static struct tap_netif tap_netif_device; -static struct rt_semaphore sem_lock; - -static tun_buffer_t* get_buffer_from_free_list(tap_win32_overlapped_t* const overlapped) -{ - tun_buffer_t* buffer = NULL; - WaitForSingleObject(overlapped->free_list_semaphore, INFINITE); - EnterCriticalSection(&overlapped->free_list_cs); - buffer = overlapped->free_list; - overlapped->free_list = buffer->next; - LeaveCriticalSection(&overlapped->free_list_cs); - buffer->next = NULL; - return buffer; -} - -static void put_buffer_on_free_list(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer) -{ - EnterCriticalSection(&overlapped->free_list_cs); - buffer->next = overlapped->free_list; - overlapped->free_list = buffer; - LeaveCriticalSection(&overlapped->free_list_cs); - ReleaseSemaphore(overlapped->free_list_semaphore, 1, NULL); -} - -static tun_buffer_t* get_buffer_from_output_queue(tap_win32_overlapped_t* const overlapped, const int block) -{ - tun_buffer_t* buffer = NULL; - DWORD result, timeout = block ? INFINITE : 0L; - - // Non-blocking call - result = WaitForSingleObject(overlapped->output_queue_semaphore, timeout); - - switch (result) - { - // The semaphore object was signaled. - case WAIT_OBJECT_0: - EnterCriticalSection(&overlapped->output_queue_cs); - - buffer = overlapped->output_queue_front; - overlapped->output_queue_front = buffer->next; - - if(overlapped->output_queue_front == NULL) { - overlapped->output_queue_back = NULL; - } - - LeaveCriticalSection(&overlapped->output_queue_cs); - break; - - // Semaphore was nonsignaled, so a time-out occurred. - case WAIT_TIMEOUT: - // Cannot open another window. - break; - } - - return buffer; -} - -static tun_buffer_t* get_buffer_from_output_queue_immediate (tap_win32_overlapped_t* const overlapped) -{ - return get_buffer_from_output_queue(overlapped, 0); -} - -static void put_buffer_on_output_queue(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer) -{ - EnterCriticalSection(&overlapped->output_queue_cs); - - if(overlapped->output_queue_front == NULL && overlapped->output_queue_back == NULL) { - overlapped->output_queue_front = overlapped->output_queue_back = buffer; - } else { - buffer->next = NULL; - overlapped->output_queue_back->next = buffer; - overlapped->output_queue_back = buffer; - } - - LeaveCriticalSection(&overlapped->output_queue_cs); - - ReleaseSemaphore(overlapped->output_queue_semaphore, 1, NULL); -} - - -static int is_tap_win32_dev(const char *guid) -{ - HKEY netcard_key; - LONG status; - DWORD len; - int i = 0; - - status = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - ADAPTER_KEY, - 0, - KEY_READ, - &netcard_key); - - if (status != ERROR_SUCCESS) { - return FALSE; - } - - for (;;) { - char enum_name[256]; - char unit_string[256]; - HKEY unit_key; - char component_id_string[] = "ComponentId"; - char component_id[256]; - char net_cfg_instance_id_string[] = "NetCfgInstanceId"; - char net_cfg_instance_id[256]; - DWORD data_type; - - len = sizeof (enum_name); - status = RegEnumKeyEx( - netcard_key, - i, - enum_name, - &len, - NULL, - NULL, - NULL, - NULL); - - if (status == ERROR_NO_MORE_ITEMS) - break; - else if (status != ERROR_SUCCESS) { - return FALSE; - } - - rt_snprintf (unit_string, sizeof(unit_string), "%s\\%s", - ADAPTER_KEY, enum_name); - - status = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - unit_string, - 0, - KEY_READ, - &unit_key); - - if (status != ERROR_SUCCESS) { - return FALSE; - } else { - len = sizeof (component_id); - status = RegQueryValueEx( - unit_key, - component_id_string, - NULL, - &data_type, - (LPBYTE)component_id, - &len); - - if (!(status != ERROR_SUCCESS || data_type != REG_SZ)) { - len = sizeof (net_cfg_instance_id); - status = RegQueryValueEx( - unit_key, - net_cfg_instance_id_string, - NULL, - &data_type, - (LPBYTE)net_cfg_instance_id, - &len); - - if (status == ERROR_SUCCESS && data_type == REG_SZ) { - if (/* !strcmp (component_id, TAP_COMPONENT_ID) &&*/ - !strcmp (net_cfg_instance_id, guid)) { - RegCloseKey (unit_key); - RegCloseKey (netcard_key); - return TRUE; - } - } - } - RegCloseKey (unit_key); - } - ++i; - } - - RegCloseKey (netcard_key); - return FALSE; -} - -static int get_device_guid( - char *name, - int name_size, - char *actual_name, - int actual_name_size) -{ - LONG status; - HKEY control_net_key; - DWORD len; - int i = 0; - int stop = 0; - - status = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - NETWORK_CONNECTIONS_KEY, - 0, - KEY_READ, - &control_net_key); - - if (status != ERROR_SUCCESS) { - return -1; - } - - while (!stop) - { - char enum_name[256]; - char connection_string[256]; - HKEY connection_key; - char name_data[256]; - DWORD name_type; - const char name_string[] = "Name"; - - len = sizeof (enum_name); - status = RegEnumKeyEx( - control_net_key, - i, - enum_name, - &len, - NULL, - NULL, - NULL, - NULL); - - if (status == ERROR_NO_MORE_ITEMS) - break; - else if (status != ERROR_SUCCESS) { - return -1; - } - - rt_snprintf(connection_string, - sizeof(connection_string), - "%s\\%s\\Connection", - NETWORK_CONNECTIONS_KEY, enum_name); - - status = RegOpenKeyEx( - HKEY_LOCAL_MACHINE, - connection_string, - 0, - KEY_READ, - &connection_key); - - if (status == ERROR_SUCCESS) { - len = sizeof (name_data); - status = RegQueryValueEx( - connection_key, - name_string, - NULL, - &name_type, - (LPBYTE)name_data, - &len); - - if (status != ERROR_SUCCESS || name_type != REG_SZ) { - return -1; - } - else { - if (is_tap_win32_dev(enum_name)) { - rt_snprintf(name, name_size, "%s", enum_name); - if (actual_name) { - if (strcmp(actual_name, "") != 0) { - if (strcmp(name_data, actual_name) != 0) { - RegCloseKey (connection_key); - ++i; - continue; - } - } - else { - rt_snprintf(actual_name, actual_name_size, "%s", name_data); - } - } - stop = 1; - } - } - - RegCloseKey (connection_key); - } - ++i; - } - - RegCloseKey (control_net_key); - - if (stop == 0) - return -1; - - return 0; -} - -static int tap_win32_set_status(HANDLE handle, int status) -{ - unsigned long len = 0; - - return DeviceIoControl(handle, TAP_IOCTL_SET_MEDIA_STATUS, - &status, sizeof (status), - &status, sizeof (status), &len, NULL); -} - -static void tap_win32_overlapped_init(tap_win32_overlapped_t* const overlapped, const HANDLE handle) -{ - overlapped->handle = handle; - - overlapped->read_event = CreateEvent(NULL, FALSE, FALSE, NULL); - overlapped->write_event = CreateEvent(NULL, FALSE, FALSE, NULL); - - overlapped->read_overlapped.Offset = 0; - overlapped->read_overlapped.OffsetHigh = 0; - overlapped->read_overlapped.hEvent = overlapped->read_event; - - overlapped->write_overlapped.Offset = 0; - overlapped->write_overlapped.OffsetHigh = 0; - overlapped->write_overlapped.hEvent = overlapped->write_event; - - InitializeCriticalSection(&overlapped->output_queue_cs); - InitializeCriticalSection(&overlapped->free_list_cs); - - overlapped->output_queue_semaphore = CreateSemaphore( - NULL, // default security attributes - 0, // initial count - TUN_MAX_BUFFER_COUNT, // maximum count - NULL); // unnamed semaphore - - if(!overlapped->output_queue_semaphore) { - fprintf(stderr, "error creating output queue semaphore!\n"); - } - - overlapped->free_list_semaphore = CreateSemaphore( - NULL, // default security attributes - TUN_MAX_BUFFER_COUNT, // initial count - TUN_MAX_BUFFER_COUNT, // maximum count - NULL); // unnamed semaphore - - if(!overlapped->free_list_semaphore) { - fprintf(stderr, "error creating free list semaphore!\n"); - } - - overlapped->free_list = overlapped->output_queue_front = overlapped->output_queue_back = NULL; - - { - unsigned index; - for(index = 0; index < TUN_MAX_BUFFER_COUNT; index++) { - tun_buffer_t* element = &overlapped->buffers[index]; - element->next = overlapped->free_list; - overlapped->free_list = element; - } - } - /* To count buffers, initially no-signal. */ - overlapped->tap_semaphore = CreateSemaphore(NULL, 0, TUN_MAX_BUFFER_COUNT, NULL); - if(!overlapped->tap_semaphore) - fprintf(stderr, "error creating tap_semaphore.\n"); -} - -static int tap_win32_write(tap_win32_overlapped_t *overlapped, - const void *buffer, unsigned long size) -{ - unsigned long write_size; - BOOL result; - DWORD error; - - result = GetOverlappedResult( overlapped->handle, &overlapped->write_overlapped, - &write_size, FALSE); - - if (!result && GetLastError() == ERROR_IO_INCOMPLETE) - WaitForSingleObject(overlapped->write_event, INFINITE); - - result = WriteFile(overlapped->handle, buffer, size, - &write_size, &overlapped->write_overlapped); - - if (!result) { - switch (error = GetLastError()) - { - case ERROR_IO_PENDING: -#ifndef TUN_ASYNCHRONOUS_WRITES - WaitForSingleObject(overlapped->write_event, INFINITE); -#endif - break; - default: - return -1; - } - } - - return write_size; -} - -static void tap_win32_thread_entry(void* param) -{ - tap_win32_overlapped_t *overlapped; - unsigned long read_size; - BOOL result; - DWORD dwError; - tun_buffer_t* buffer; - struct eth_device* eth; - - eth = (struct eth_device*) &tap_netif_device; - overlapped = NETIF_TAP(&tap_netif_device); - buffer = get_buffer_from_free_list(overlapped); - - for (;;) { - result = ReadFile(overlapped->handle, - buffer->buffer, - sizeof(buffer->buffer), - &read_size, - &overlapped->read_overlapped); - if (!result) { - dwError = GetLastError(); - if (dwError == ERROR_IO_PENDING) { - WaitForSingleObject(overlapped->read_event, INFINITE); - result = GetOverlappedResult( overlapped->handle, &overlapped->read_overlapped, - &read_size, FALSE); - if (!result) { -#ifdef DEBUG_TAP_WIN32 - LPVOID lpBuffer; - dwError = GetLastError(); - FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) & lpBuffer, 0, NULL ); - fprintf(stderr, "Tap-Win32: Error GetOverlappedResult %d - %s\n", dwError, lpBuffer); - LocalFree( lpBuffer ); -#endif - } - } else { -#ifdef DEBUG_TAP_WIN32 - LPVOID lpBuffer; - FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) & lpBuffer, 0, NULL ); - fprintf(stderr, "Tap-Win32: Error ReadFile %d - %s\n", dwError, lpBuffer); - LocalFree( lpBuffer ); -#endif - } - } - - if(read_size > 0) { - // rt_kprintf("rx packet, length=%d\n", read_size); - - buffer->read_size = read_size; - put_buffer_on_output_queue(overlapped, buffer); - - /* notify eth rx thread to receive packet */ - eth_device_ready(eth); - - buffer = get_buffer_from_free_list(overlapped); - } - } -} - -static int tap_win32_read(tap_win32_overlapped_t *overlapped, - rt_uint8_t **pbuf, int max_size) -{ - int size = 0; - - tun_buffer_t* buffer = get_buffer_from_output_queue_immediate(overlapped); - - if(buffer != NULL) { - *pbuf = buffer->buffer; - size = (int)buffer->read_size; - if(size > max_size) { - size = max_size; - } - } - - return size; -} - -static void tap_win32_free_buffer(tap_win32_overlapped_t *overlapped, - rt_uint8_t *pbuf) -{ - tun_buffer_t* buffer = (tun_buffer_t*)pbuf; - put_buffer_on_free_list(overlapped, buffer); -} - -static int tap_win32_open(tap_win32_overlapped_t **phandle, - const char *preferred_name) -{ - char device_path[256]; - char device_guid[0x100]; - int rc; - HANDLE handle; - BOOL bret; - char name_buffer[0x100] = {0, }; - struct { - unsigned long major; - unsigned long minor; - unsigned long debug; - } version; - DWORD version_len; - - if (preferred_name != NULL) { - rt_snprintf(name_buffer, sizeof(name_buffer), "%s", preferred_name); - } - - rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer)); - if (rc) - return -1; - - rt_snprintf (device_path, sizeof(device_path), "%s%s%s", - USERMODEDEVICEDIR, - device_guid, - TAPSUFFIX); - - handle = CreateFile ( - device_path, - GENERIC_READ | GENERIC_WRITE, - 0, - 0, - OPEN_EXISTING, - FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, - 0 ); - - if (handle == INVALID_HANDLE_VALUE) { - return -1; - } - - bret = DeviceIoControl(handle, TAP_IOCTL_GET_VERSION, - &version, sizeof (version), - &version, sizeof (version), &version_len, NULL); - - if (bret == FALSE) { - CloseHandle(handle); - return -1; - } - - if (!tap_win32_set_status(handle, TRUE)) { - return -1; - } - - tap_win32_overlapped_init(&tap_overlapped, handle); - - *phandle = &tap_overlapped; - return 0; -} - -static rt_err_t tap_netif_init(rt_device_t dev) -{ - rt_thread_t tid; - tap_win32_overlapped_t *handle; - - if (tap_win32_open(&handle, TAP_IFNAME) < 0) { - printf("tap: Could not open '%s'\n", TAP_IFNAME); - return -RT_ERROR; - } - - tap_netif_device.handle = handle; - - /* create recv thread */ - tid = rt_thread_create("tap", tap_win32_thread_entry, RT_NULL, - 2048, RT_THREAD_PRIORITY_MAX - 1, 10); - if (tid != RT_NULL) - { - rt_thread_startup(tid); - } - - rt_thread_sleep(RT_TICK_PER_SECOND); - - return RT_EOK; -} - -static rt_err_t tap_netif_open(rt_device_t dev, rt_uint16_t oflag) -{ - return RT_EOK; -} - -static rt_err_t tap_netif_close(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_size_t tap_netif_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -static rt_size_t tap_netif_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -static rt_err_t tap_netif_control(rt_device_t dev, int cmd, void *args) -{ - switch (cmd) - { - case NIOCTL_GADDR: - /* get mac address */ - if (args) rt_memcpy(args, tap_netif_device.dev_addr, 6); - else return -RT_ERROR; - break; - - default : - break; - } - - return RT_EOK; -} - -rt_err_t tap_netif_tx( rt_device_t dev, struct pbuf* p) -{ - struct pbuf *q; - char buffer[2048]; - int length; - tap_win32_overlapped_t *handle; - unsigned char* ptr; - - handle = NETIF_TAP(dev); - - /* lock EMAC device */ - rt_sem_take(&sem_lock, RT_WAITING_FOREVER); - - /* copy data to tx buffer */ - q = p; - ptr = (rt_uint8_t*)buffer; - while (q) - { - memcpy(ptr, q->payload, q->len); - ptr += q->len; - q = q->next; - } - length = p->tot_len; - - tap_win32_write(handle, buffer, length); - - /* unlock EMAC device */ - rt_sem_release(&sem_lock); - - return RT_EOK; -} - -struct pbuf *tap_netif_rx(rt_device_t dev) -{ - struct pbuf* p = RT_NULL; - tap_win32_overlapped_t *handle; - rt_uint8_t *buf; - int max_size = 4096; - int size; - - handle = NETIF_TAP(dev); - - size = tap_win32_read(handle, &buf, max_size); - if (size > 0) { - p = pbuf_alloc(PBUF_LINK, size, PBUF_RAM); - pbuf_take(p, buf, size); - - tap_win32_free_buffer(handle, buf); - } - - return p; -} - -void tap_netif_hw_init(void) -{ - rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO); - - tap_netif_device.dev_addr[0] = 0x00; - tap_netif_device.dev_addr[1] = 0x60; - tap_netif_device.dev_addr[2] = 0x37; - /* set mac address: (only for test) */ - tap_netif_device.dev_addr[3] = 0x12; - tap_netif_device.dev_addr[4] = 0x34; - tap_netif_device.dev_addr[5] = 0x56; - - tap_netif_device.parent.parent.init = tap_netif_init; - tap_netif_device.parent.parent.open = tap_netif_open; - tap_netif_device.parent.parent.close = tap_netif_close; - tap_netif_device.parent.parent.read = tap_netif_read; - tap_netif_device.parent.parent.write = tap_netif_write; - tap_netif_device.parent.parent.control = tap_netif_control; - tap_netif_device.parent.parent.user_data= RT_NULL; - - tap_netif_device.parent.eth_rx = tap_netif_rx; - tap_netif_device.parent.eth_tx = tap_netif_tx; - - eth_device_init(&(tap_netif_device.parent), "e0"); -} From 5ea61fca5ad8f90ce6059a6400b5eb13bb019997 Mon Sep 17 00:00:00 2001 From: yangjie Date: Mon, 26 Apr 2021 14:59:31 +0800 Subject: [PATCH 10/13] [bsp][realview-a8] delete realview-a8 bsp --- bsp/realview-a8/.gitignore | 26 -- bsp/realview-a8/README.md | 11 - bsp/realview-a8/SConscript | 14 - bsp/realview-a8/SConstruct | 44 --- bsp/realview-a8/applications/SConscript | 11 - bsp/realview-a8/applications/application.c | 28 -- bsp/realview-a8/applications/startup.c | 68 ----- bsp/realview-a8/boot.sh | 3 - bsp/realview-a8/drivers/SConscript | 13 - bsp/realview-a8/drivers/board.c | 99 ------- bsp/realview-a8/drivers/board.h | 28 -- bsp/realview-a8/drivers/realview.h | 324 --------------------- bsp/realview-a8/drivers/serial.c | 185 ------------ bsp/realview-a8/drivers/serial.h | 20 -- bsp/realview-a8/linux_vmm/.gitignore | 10 - bsp/realview-a8/linux_vmm/Makefile | 6 - bsp/realview-a8/linux_vmm/build.sh | 22 -- bsp/realview-a8/linux_vmm/vmm_linux.c | 257 ---------------- bsp/realview-a8/linux_vmm/vmm_linux.h | 8 - bsp/realview-a8/mk.sh | 19 -- bsp/realview-a8/qemu.sh | 1 - bsp/realview-a8/realview.lds | 91 ------ bsp/realview-a8/realview_vmm.lds.S | 140 --------- bsp/realview-a8/rtconfig.h | 153 ---------- bsp/realview-a8/rtconfig.py | 55 ---- bsp/realview-a8/rtt_api.h | 164 ----------- 26 files changed, 1800 deletions(-) delete mode 100644 bsp/realview-a8/.gitignore delete mode 100644 bsp/realview-a8/README.md delete mode 100644 bsp/realview-a8/SConscript delete mode 100644 bsp/realview-a8/SConstruct delete mode 100644 bsp/realview-a8/applications/SConscript delete mode 100644 bsp/realview-a8/applications/application.c delete mode 100644 bsp/realview-a8/applications/startup.c delete mode 100644 bsp/realview-a8/boot.sh delete mode 100644 bsp/realview-a8/drivers/SConscript delete mode 100644 bsp/realview-a8/drivers/board.c delete mode 100644 bsp/realview-a8/drivers/board.h delete mode 100644 bsp/realview-a8/drivers/realview.h delete mode 100644 bsp/realview-a8/drivers/serial.c delete mode 100644 bsp/realview-a8/drivers/serial.h delete mode 100644 bsp/realview-a8/linux_vmm/.gitignore delete mode 100644 bsp/realview-a8/linux_vmm/Makefile delete mode 100644 bsp/realview-a8/linux_vmm/build.sh delete mode 100644 bsp/realview-a8/linux_vmm/vmm_linux.c delete mode 100644 bsp/realview-a8/linux_vmm/vmm_linux.h delete mode 100644 bsp/realview-a8/mk.sh delete mode 100644 bsp/realview-a8/qemu.sh delete mode 100644 bsp/realview-a8/realview.lds delete mode 100644 bsp/realview-a8/realview_vmm.lds.S delete mode 100644 bsp/realview-a8/rtconfig.h delete mode 100644 bsp/realview-a8/rtconfig.py delete mode 100644 bsp/realview-a8/rtt_api.h diff --git a/bsp/realview-a8/.gitignore b/bsp/realview-a8/.gitignore deleted file mode 100644 index f0bbbc4965..0000000000 --- a/bsp/realview-a8/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Object files -*.o -*.bin -*.pyc -*.map -*.elf - -# Libraries -*.lib -*.a - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app - -.scons* - -# directory -build/* diff --git a/bsp/realview-a8/README.md b/bsp/realview-a8/README.md deleted file mode 100644 index b9ee2d06d3..0000000000 --- a/bsp/realview-a8/README.md +++ /dev/null @@ -1,11 +0,0 @@ -VMM BSP on realview-pb-a8 - -This is a demo program that run RT-Thread VMM(Virtual Machine Module) on -the single core RealView-PB-A8. - -To compile it, you need buildroot and a linux 3.8.x source tree. You should -build the patched Linux kernel and builroot before building the VMM. This -directory has a "mk.sh" helper script to build both the RT-Thread, Linux kernel -module and the ramdisk. - -Linux console is serial0 and RT-Thread console is serial1. diff --git a/bsp/realview-a8/SConscript b/bsp/realview-a8/SConscript deleted file mode 100644 index fe0ae941ae..0000000000 --- a/bsp/realview-a8/SConscript +++ /dev/null @@ -1,14 +0,0 @@ -# for module compiling -import os -Import('RTT_ROOT') - -cwd = str(Dir('#')) -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') diff --git a/bsp/realview-a8/SConstruct b/bsp/realview-a8/SConstruct deleted file mode 100644 index 2ba0e9f457..0000000000 --- a/bsp/realview-a8/SConstruct +++ /dev/null @@ -1,44 +0,0 @@ -import os -import sys -import rtconfig - -if os.getenv('RTT_ROOT'): - RTT_ROOT = os.getenv('RTT_ROOT') -else: - RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') - -sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] -from building import * - -TARGET = 'rtthread-realview.' + rtconfig.TARGET_EXT - -DefaultEnvironment(tools=[]) -env = Environment(tools = ['mingw'], - AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, - CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, - 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) - -if GetDepend('RT_USING_VMM'): - if os.system('{cppcmd} -P -C -E -I. -D__ASSEMBLY__ {ldfile}.S -o {ldfile}'.format( - cppcmd = os.path.join(rtconfig.EXEC_PATH, 'arm-none-eabi-gcc'), - ldfile = rtconfig.LINK_SCRIPT)) != 0: - print('failed to generate linker script %s' % rtconfig.LINK_SCRIPT) - sys.exit(255) - # if the linker script changed, relink the target - Depends(TARGET, rtconfig.LINK_SCRIPT) -else: - # we should use none-vmm link script - link_flags = str(env['LINKFLAGS']) - env['LINKFLAGS'] = link_flags.replace('_vmm.lds', '.lds') - -# make a building -DoBuilding(TARGET, objs) diff --git a/bsp/realview-a8/applications/SConscript b/bsp/realview-a8/applications/SConscript deleted file mode 100644 index 01eb940dfb..0000000000 --- a/bsp/realview-a8/applications/SConscript +++ /dev/null @@ -1,11 +0,0 @@ -Import('RTT_ROOT') -Import('rtconfig') -from building import * - -cwd = os.path.join(str(Dir('#')), 'applications') -src = Glob('*.c') -CPPPATH = [cwd, str(Dir('#'))] - -group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/bsp/realview-a8/applications/application.c b/bsp/realview-a8/applications/application.c deleted file mode 100644 index 0b8f14b1db..0000000000 --- a/bsp/realview-a8/applications/application.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-11-20 Bernard the first version - */ - -#include - -void init_thread(void* parameter) -{ - rt_components_init(); -} - -int rt_application_init() -{ - rt_thread_t tid; - - tid = rt_thread_create("init", init_thread, RT_NULL, - 1024, RT_THREAD_PRIORITY_MAX/3, 10); - if (tid != RT_NULL) rt_thread_startup(tid); - - return 0; -} - diff --git a/bsp/realview-a8/applications/startup.c b/bsp/realview-a8/applications/startup.c deleted file mode 100644 index 2c37bb4726..0000000000 --- a/bsp/realview-a8/applications/startup.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-12-05 Bernard the first version - */ - -#include -#include - -#include - -extern int rt_application_init(void); -extern void rt_hw_board_init(void); - -/** - * This function will startup RT-Thread RTOS. - */ -void rtthread_startup(void) -{ - /* initialzie hardware interrupt */ - rt_hw_interrupt_init(); - - /* initialize board */ - rt_hw_board_init(); - - /* show RT-Thread version */ - rt_show_version(); - - /* initialize memory system */ -#ifdef RT_USING_HEAP - rt_system_heap_init(HEAP_BEGIN, HEAP_END); -#endif - - /* initialize scheduler system */ - rt_system_scheduler_init(); - - /* initialize timer and soft timer thread */ - rt_system_timer_init(); - rt_system_timer_thread_init(); - - /* initialize application */ - rt_application_init(); - - /* initialize idle thread */ - rt_thread_idle_init(); - - /* start scheduler */ - rt_system_scheduler_start(); - - /* never reach here */ - return ; -} - -int main(void) -{ - /* disable interrupt first */ - rt_hw_interrupt_disable(); - - /* invoke rtthread_startup */ - rtthread_startup(); - - return 0; -} - diff --git a/bsp/realview-a8/boot.sh b/bsp/realview-a8/boot.sh deleted file mode 100644 index eaafa6524c..0000000000 --- a/bsp/realview-a8/boot.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e -scons -j12 -qemu-system-arm -M realview-pb-a8 -kernel rtthread-realview.elf -serial vc -serial stdio diff --git a/bsp/realview-a8/drivers/SConscript b/bsp/realview-a8/drivers/SConscript deleted file mode 100644 index 9987f53e4b..0000000000 --- a/bsp/realview-a8/drivers/SConscript +++ /dev/null @@ -1,13 +0,0 @@ -import copy -Import('RTT_ROOT') -Import('rtconfig') -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') - -CPPPATH = [cwd] - -group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/bsp/realview-a8/drivers/board.c b/bsp/realview-a8/drivers/board.c deleted file mode 100644 index 013603b684..0000000000 --- a/bsp/realview-a8/drivers/board.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-11-20 Bernard the first version - */ - -#include -#include - -#include "board.h" - -#define TIMER_LOAD(hw_base) __REG32(hw_base + 0x00) -#define TIMER_VALUE(hw_base) __REG32(hw_base + 0x04) -#define TIMER_CTRL(hw_base) __REG32(hw_base + 0x08) -#define TIMER_CTRL_ONESHOT (1 << 0) -#define TIMER_CTRL_32BIT (1 << 1) -#define TIMER_CTRL_DIV1 (0 << 2) -#define TIMER_CTRL_DIV16 (1 << 2) -#define TIMER_CTRL_DIV256 (2 << 2) -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ -#define TIMER_CTRL_PERIODIC (1 << 6) -#define TIMER_CTRL_ENABLE (1 << 7) - -#define TIMER_INTCLR(hw_base) __REG32(hw_base + 0x0c) -#define TIMER_RIS(hw_base) __REG32(hw_base + 0x10) -#define TIMER_MIS(hw_base) __REG32(hw_base + 0x14) -#define TIMER_BGLOAD(hw_base) __REG32(hw_base + 0x18) - -#define SYS_CTRL __REG32(REALVIEW_SCTL_BASE) - -#ifdef RT_USING_VMM -#include -static rt_uint32_t timer_hw_base = 0; -#define TIMER_HW_BASE (timer_hw_base) -#else -#define TIMER_HW_BASE REALVIEW_TIMER2_3_BASE -#endif - -void rt_hw_timer_ack(void) -{ - /* clear interrupt */ - TIMER_INTCLR(TIMER_HW_BASE) = 0x01; -} - -static void rt_hw_timer_isr(int vector, void *param) -{ - rt_tick_increase(); - - rt_hw_timer_ack(); -} - -int rt_hw_timer_init(void) -{ - rt_uint32_t val; - -#ifdef RT_USING_VMM - { - rt_uint32_t sys_ctrl; - sys_ctrl = vmm_find_iomap("SYS_CTRL"); - __REG32(sys_ctrl) |= REALVIEW_REFCLK; - } - - timer_hw_base = vmm_find_iomap("TIMER"); -#else - SYS_CTRL |= REALVIEW_REFCLK; -#endif - - /* Setup Timer0 for generating irq */ - val = TIMER_CTRL(TIMER_HW_BASE); - val &= ~TIMER_CTRL_ENABLE; - val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); - TIMER_CTRL(TIMER_HW_BASE) = val; - - TIMER_LOAD(TIMER_HW_BASE) = 1000; - - /* enable timer */ - TIMER_CTRL(TIMER_HW_BASE) |= TIMER_CTRL_ENABLE; - - rt_hw_interrupt_install(IRQ_PBA8_TIMER2_3, rt_hw_timer_isr, RT_NULL, "tick"); - rt_hw_interrupt_umask(IRQ_PBA8_TIMER2_3); - - return 0; -} -INIT_BOARD_EXPORT(rt_hw_timer_init); - -/** - * This function will initialize beaglebone board - */ -void rt_hw_board_init(void) -{ - rt_components_board_init(); - rt_console_set_device(RT_CONSOLE_DEVICE_NAME); -} - -/*@}*/ diff --git a/bsp/realview-a8/drivers/board.h b/bsp/realview-a8/drivers/board.h deleted file mode 100644 index f1d30314ba..0000000000 --- a/bsp/realview-a8/drivers/board.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-06 Bernard the first version - */ - -#ifndef __BOARD_H__ -#define __BOARD_H__ - -#include - -#if defined(__CC_ARM) -extern int Image$$RW_IRAM1$$ZI$$Limit; -#define HEAP_BEGIN ((void*)&Image$$RW_IRAM1$$ZI$$Limit) -#elif defined(__GNUC__) -extern int __bss_end; -#define HEAP_BEGIN ((void*)&__bss_end) -#endif - -#define HEAP_END (void*)(0x70000000 + 8 * 1024 * 1024) - -void rt_hw_board_init(void); - -#endif diff --git a/bsp/realview-a8/drivers/realview.h b/bsp/realview-a8/drivers/realview.h deleted file mode 100644 index 159f2244ea..0000000000 --- a/bsp/realview-a8/drivers/realview.h +++ /dev/null @@ -1,324 +0,0 @@ -#ifndef __AM33XX_H__ -#define __AM33XX_H__ - -#define __REG32(x) (*((volatile unsigned int *)(x))) -#define __REG16(x) (*((volatile unsigned short *)(x))) - -/* - * Peripheral addresses - */ -#define REALVIEW_UART0_BASE 0x10009000 /* UART 0 */ -#define REALVIEW_UART1_BASE 0x1000A000 /* UART 1 */ -#define REALVIEW_UART2_BASE 0x1000B000 /* UART 2 */ -#define REALVIEW_UART3_BASE 0x1000C000 /* UART 3 */ -#define REALVIEW_SSP_BASE 0x1000D000 /* Synchronous Serial Port */ -#define REALVIEW_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */ -#define REALVIEW_WATCHDOG_BASE 0x10010000 /* watchdog interface */ -#define REALVIEW_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */ -#define REALVIEW_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */ -#define REALVIEW_GPIO0_BASE 0x10013000 /* GPIO port 0 */ -#define REALVIEW_RTC_BASE 0x10017000 /* Real Time Clock */ -#define REALVIEW_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */ -#define REALVIEW_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */ -#define REALVIEW_SCTL_BASE 0x1001A000 /* System Controller */ -#define REALVIEW_CLCD_BASE 0x10020000 /* CLCD */ -#define REALVIEW_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */ -#define REALVIEW_DMC_BASE 0x100E0000 /* DMC configuration */ -#define REALVIEW_SMC_BASE 0x100E1000 /* SMC configuration */ -#define REALVIEW_CAN_BASE 0x100E2000 /* CAN bus */ -#define REALVIEW_GIC_CPU_BASE 0x1E000000 /* Generic interrupt controller CPU interface */ -#define REALVIEW_FLASH0_BASE 0x40000000 -#define REALVIEW_FLASH0_SIZE SZ_64M -#define REALVIEW_FLASH1_BASE 0x44000000 -#define REALVIEW_FLASH1_SIZE SZ_64M -#define REALVIEW_ETH_BASE 0x4E000000 /* Ethernet */ -#define REALVIEW_USB_BASE 0x4F000000 /* USB */ -#define REALVIEW_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */ -#define REALVIEW_LT_BASE 0xC0000000 /* Logic Tile expansion */ -#define REALVIEW_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */ -#define REALVIEW_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */ - -#define REALVIEW_SYS_PLD_CTRL1 0x74 - -/* - * PCI regions - */ -#define REALVIEW_PCI_BASE 0x90040000 /* PCI-X Unit base */ -#define REALVIEW_PCI_IO_BASE 0x90050000 /* IO Region on AHB */ -#define REALVIEW_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */ - -#define REALVIEW_PCI_BASE_SIZE 0x10000 /* 16 Kb */ -#define REALVIEW_PCI_IO_SIZE 0x1000 /* 4 Kb */ -#define REALVIEW_PCI_MEM_SIZE 0x20000000 /* 512 MB */ - -/* - * Memory definitions - */ -#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)... */ -#define REALVIEW_BOOT_ROM_HI 0x30000000 -#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */ -#define REALVIEW_BOOT_ROM_SIZE SZ_64M - -#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */ -#define REALVIEW_SSRAM_SIZE SZ_2M - -/* - * SDRAM - */ -#define REALVIEW_SDRAM_BASE 0x00000000 - -/* - * Logic expansion modules - * - */ -#define IRQ_PBA8_GIC_START 32 - -/* - * PB-A8 on-board gic irq sources - */ -#define IRQ_PBA8_WATCHDOG (IRQ_PBA8_GIC_START + 0) /* Watchdog timer */ -#define IRQ_PBA8_SOFT (IRQ_PBA8_GIC_START + 1) /* Software interrupt */ -#define IRQ_PBA8_COMMRx (IRQ_PBA8_GIC_START + 2) /* Debug Comm Rx interrupt */ -#define IRQ_PBA8_COMMTx (IRQ_PBA8_GIC_START + 3) /* Debug Comm Tx interrupt */ -#define IRQ_PBA8_TIMER0_1 (IRQ_PBA8_GIC_START + 4) /* Timer 0/1 (default timer) */ -#define IRQ_PBA8_TIMER2_3 (IRQ_PBA8_GIC_START + 5) /* Timer 2/3 */ -#define IRQ_PBA8_GPIO0 (IRQ_PBA8_GIC_START + 6) /* GPIO 0 */ -#define IRQ_PBA8_GPIO1 (IRQ_PBA8_GIC_START + 7) /* GPIO 1 */ -#define IRQ_PBA8_GPIO2 (IRQ_PBA8_GIC_START + 8) /* GPIO 2 */ -/* 9 reserved */ -#define IRQ_PBA8_RTC (IRQ_PBA8_GIC_START + 10) /* Real Time Clock */ -#define IRQ_PBA8_SSP (IRQ_PBA8_GIC_START + 11) /* Synchronous Serial Port */ -#define IRQ_PBA8_UART0 (IRQ_PBA8_GIC_START + 12) /* UART 0 on development chip */ -#define IRQ_PBA8_UART1 (IRQ_PBA8_GIC_START + 13) /* UART 1 on development chip */ -#define IRQ_PBA8_UART2 (IRQ_PBA8_GIC_START + 14) /* UART 2 on development chip */ -#define IRQ_PBA8_UART3 (IRQ_PBA8_GIC_START + 15) /* UART 3 on development chip */ -#define IRQ_PBA8_SCI (IRQ_PBA8_GIC_START + 16) /* Smart Card Interface */ -#define IRQ_PBA8_MMCI0A (IRQ_PBA8_GIC_START + 17) /* Multimedia Card 0A */ -#define IRQ_PBA8_MMCI0B (IRQ_PBA8_GIC_START + 18) /* Multimedia Card 0B */ -#define IRQ_PBA8_AACI (IRQ_PBA8_GIC_START + 19) /* Audio Codec */ -#define IRQ_PBA8_KMI0 (IRQ_PBA8_GIC_START + 20) /* Keyboard/Mouse port 0 */ -#define IRQ_PBA8_KMI1 (IRQ_PBA8_GIC_START + 21) /* Keyboard/Mouse port 1 */ -#define IRQ_PBA8_CHARLCD (IRQ_PBA8_GIC_START + 22) /* Character LCD */ -#define IRQ_PBA8_CLCD (IRQ_PBA8_GIC_START + 23) /* CLCD controller */ -#define IRQ_PBA8_DMAC (IRQ_PBA8_GIC_START + 24) /* DMA controller */ -#define IRQ_PBA8_PWRFAIL (IRQ_PBA8_GIC_START + 25) /* Power failure */ -#define IRQ_PBA8_PISMO (IRQ_PBA8_GIC_START + 26) /* PISMO interface */ -#define IRQ_PBA8_DoC (IRQ_PBA8_GIC_START + 27) /* Disk on Chip memory controller */ -#define IRQ_PBA8_ETH (IRQ_PBA8_GIC_START + 28) /* Ethernet controller */ -#define IRQ_PBA8_USB (IRQ_PBA8_GIC_START + 29) /* USB controller */ -#define IRQ_PBA8_TSPEN (IRQ_PBA8_GIC_START + 30) /* Touchscreen pen */ -#define IRQ_PBA8_TSKPAD (IRQ_PBA8_GIC_START + 31) /* Touchscreen keypad */ - -#define IRQ_PBA8_PMU (IRQ_PBA8_GIC_START + 47) /* Cortex-A8 PMU */ - -/* ... */ -#define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50) -#define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51) -#define IRQ_PBA8_PCI2 (IRQ_PBA8_GIC_START + 52) -#define IRQ_PBA8_PCI3 (IRQ_PBA8_GIC_START + 53) - -#define IRQ_PBA8_SMC -1 -#define IRQ_PBA8_SCTL -1 - -#define NR_GIC_PBA8 1 - -/* - * Only define NR_IRQS if less than NR_IRQS_PBA8 - */ -#define NR_IRQS_PBA8 (IRQ_PBA8_GIC_START + 64) - -/* ------------------------------------------------------------------------ - * RealView Registers - * ------------------------------------------------------------------------ - * - */ -#define REALVIEW_SYS_ID_OFFSET 0x00 -#define REALVIEW_SYS_SW_OFFSET 0x04 -#define REALVIEW_SYS_LED_OFFSET 0x08 -#define REALVIEW_SYS_OSC0_OFFSET 0x0C - -#define REALVIEW_SYS_OSC1_OFFSET 0x10 -#define REALVIEW_SYS_OSC2_OFFSET 0x14 -#define REALVIEW_SYS_OSC3_OFFSET 0x18 -#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */ - -#define REALVIEW_SYS_LOCK_OFFSET 0x20 -#define REALVIEW_SYS_100HZ_OFFSET 0x24 -#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28 -#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C -#define REALVIEW_SYS_FLAGS_OFFSET 0x30 -#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30 -#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34 -#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38 -#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38 -#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C -#define REALVIEW_SYS_RESETCTL_OFFSET 0x40 -#define REALVIEW_SYS_PCICTL_OFFSET 0x44 -#define REALVIEW_SYS_MCI_OFFSET 0x48 -#define REALVIEW_SYS_FLASH_OFFSET 0x4C -#define REALVIEW_SYS_CLCD_OFFSET 0x50 -#define REALVIEW_SYS_CLCDSER_OFFSET 0x54 -#define REALVIEW_SYS_BOOTCS_OFFSET 0x58 -#define REALVIEW_SYS_24MHz_OFFSET 0x5C -#define REALVIEW_SYS_MISC_OFFSET 0x60 -#define REALVIEW_SYS_IOSEL_OFFSET 0x70 -#define REALVIEW_SYS_PROCID_OFFSET 0x84 -#define REALVIEW_SYS_TEST_OSC0_OFFSET 0xC0 -#define REALVIEW_SYS_TEST_OSC1_OFFSET 0xC4 -#define REALVIEW_SYS_TEST_OSC2_OFFSET 0xC8 -#define REALVIEW_SYS_TEST_OSC3_OFFSET 0xCC -#define REALVIEW_SYS_TEST_OSC4_OFFSET 0xD0 - -#define REALVIEW_SYS_BASE 0x10000000 -#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET) -#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET) -#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET) -#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET) -#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET) - -#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET) -#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET) -#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET) -#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET) -#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET) -#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET) -#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET) -#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET) -#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET) -#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET) -#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET) -#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET) -#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET) -#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET) -#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET) -#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET) -#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET) -#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET) -#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET) -#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET) -#define REALVIEW_SYS_PROCID (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET) -#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET) -#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET) -#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET) -#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET) -#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET) - -#define REALVIEW_SYS_CTRL_LED (1 << 0) - -/* ------------------------------------------------------------------------ - * RealView control registers - * ------------------------------------------------------------------------ - */ - -/* - * REALVIEW_IDFIELD - * - * 31:24 = manufacturer (0x41 = ARM) - * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus) - * 15:12 = FPGA (0x3 = XVC600 or XVC600E) - * 11:4 = build value - * 3:0 = revision number (0x1 = rev B (AHB)) - */ - -/* - * REALVIEW_SYS_LOCK - * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, - * SYS_CLD, SYS_BOOTCS - */ -#define REALVIEW_SYS_LOCK_LOCKED (1 << 16) -#define REALVIEW_SYS_LOCKVAL 0xA05F -#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */ - -/* - * REALVIEW_SYS_FLASH - */ -#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */ - -/* - * REALVIEW_INTREG - * - used to acknowledge and control MMCI and UART interrupts - */ -#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */ -#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */ -#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */ -/* write 1 to acknowledge and clear */ -#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */ -#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */ - -/* - * LED settings, bits [7:0] - */ -#define REALVIEW_SYS_LED0 (1 << 0) -#define REALVIEW_SYS_LED1 (1 << 1) -#define REALVIEW_SYS_LED2 (1 << 2) -#define REALVIEW_SYS_LED3 (1 << 3) -#define REALVIEW_SYS_LED4 (1 << 4) -#define REALVIEW_SYS_LED5 (1 << 5) -#define REALVIEW_SYS_LED6 (1 << 6) -#define REALVIEW_SYS_LED7 (1 << 7) - -#define ALL_LEDS 0xFF - -#define LED_BANK REALVIEW_SYS_LED - -/* - * Control registers - */ -#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */ -#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */ -#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */ -#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */ - -/* - * Clean base - dummy - * - */ -#define CLEAN_BASE REALVIEW_BOOT_ROM_HI - -/* - * System controller bit assignment - */ -#define REALVIEW_REFCLK 0 -#define REALVIEW_TIMCLK 1 - -#define REALVIEW_TIMER1_EnSel 15 -#define REALVIEW_TIMER2_EnSel 17 -#define REALVIEW_TIMER3_EnSel 19 -#define REALVIEW_TIMER4_EnSel 21 - -/* - *struct rt_hw_register - *{ - * unsigned long r0; - * unsigned long r1; - * unsigned long r2; - * unsigned long r3; - * unsigned long r4; - * unsigned long r5; - * unsigned long r6; - * unsigned long r7; - * unsigned long r8; - * unsigned long r9; - * unsigned long r10; - * unsigned long fp; - * unsigned long ip; - * unsigned long sp; - * unsigned long lr; - * unsigned long pc; - * unsigned long cpsr; - * unsigned long ORIG_r0; - *}; - */ - -#include - -/* Interrupt Control Interface */ -#define ARM_GIC_CPU_BASE 0x1E000000 - -/* number of interrupts on board */ -#define ARM_GIC_NR_IRQS 96 -/* only one GIC available */ -#define ARM_GIC_MAX_NR 1 - -#endif - diff --git a/bsp/realview-a8/drivers/serial.c b/bsp/realview-a8/drivers/serial.c deleted file mode 100644 index 75fca59401..0000000000 --- a/bsp/realview-a8/drivers/serial.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-03-30 Bernard the first verion - */ - -#include -#include - -#include "serial.h" -#ifdef RT_USING_VMM -#include -#endif - -struct hw_uart_device -{ - rt_uint32_t hw_base; - rt_uint32_t irqno; -}; - -#define UART_DR(base) __REG32(base + 0x00) -#define UART_FR(base) __REG32(base + 0x18) -#define UART_CR(base) __REG32(base + 0x30) -#define UART_IMSC(base) __REG32(base + 0x38) -#define UART_ICR(base) __REG32(base + 0x44) - -#define UARTFR_RXFE 0x10 -#define UARTFR_TXFF 0x20 -#define UARTIMSC_RXIM 0x10 -#define UARTIMSC_TXIM 0x20 -#define UARTICR_RXIC 0x10 -#define UARTICR_TXIC 0x20 - -static void rt_hw_uart_isr(int irqno, void *param) -{ - struct rt_serial_device *serial = (struct rt_serial_device *)param; - - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); -} - -static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) -{ - return RT_EOK; -} - -static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) -{ - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - switch (cmd) - { - case RT_DEVICE_CTRL_CLR_INT: - /* disable rx irq */ - UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM; - break; - - case RT_DEVICE_CTRL_SET_INT: - /* enable rx irq */ - UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM; - rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, "uart"); - rt_hw_interrupt_umask(uart->irqno); - break; - } - - return RT_EOK; -} - -static int uart_putc(struct rt_serial_device *serial, char c) -{ - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - while (UART_FR(uart->hw_base) & UARTFR_TXFF); - UART_DR(uart->hw_base) = c; - - return 1; -} - -static int uart_getc(struct rt_serial_device *serial) -{ - int ch; - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - ch = -1; - if (!(UART_FR(uart->hw_base) & UARTFR_RXFE)) - { - ch = UART_DR(uart->hw_base) & 0xff; - } - - return ch; -} - -static const struct rt_uart_ops _uart_ops = -{ - uart_configure, - uart_control, - uart_putc, - uart_getc, -}; - -#ifdef RT_USING_UART0 -/* UART device driver structure */ -static struct hw_uart_device _uart0_device = -{ - REALVIEW_UART0_BASE, - IRQ_PBA8_UART0, -}; -static struct rt_serial_device _serial0; -#endif - -#ifdef RT_USING_UART1 -/* UART1 device driver structure */ -static struct hw_uart_device _uart1_device = -{ - REALVIEW_UART1_BASE, - IRQ_PBA8_UART1, -}; -static struct rt_serial_device _serial1; -#endif - -int uart_isr_test(void) -{ - return uart_getc(&_serial1); -} - -int rt_hw_uart_init(void) -{ - struct hw_uart_device *uart; - struct serial_configure config; - - config.baud_rate = BAUD_RATE_115200; - config.bit_order = BIT_ORDER_LSB; - config.data_bits = DATA_BITS_8; - config.parity = PARITY_NONE; - config.stop_bits = STOP_BITS_1; - config.invert = NRZ_NORMAL; - config.bufsz = RT_SERIAL_RB_BUFSZ; - -#ifdef RT_USING_UART0 - uart = &_uart0_device; -#ifdef RT_USING_VMM - uart->hw_base = vmm_find_iomap("UART0"); -#endif - - _serial0.ops = &_uart_ops; - _serial0.config = config; - - /* register UART1 device */ - rt_hw_serial_register(&_serial0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); - /* enable Rx and Tx of UART */ - UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); -#endif - -#ifdef RT_USING_UART1 - uart = &_uart1_device; -#ifdef RT_USING_VMM - uart->hw_base = vmm_find_iomap("UART1"); -#endif - _serial1.ops = &_uart_ops; - _serial1.config = config; - - /* register UART1 device */ - rt_hw_serial_register(&_serial1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); - /* enable Rx and Tx of UART */ - UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); -#endif - - return 0; -} -INIT_BOARD_EXPORT(rt_hw_uart_init); diff --git a/bsp/realview-a8/drivers/serial.h b/bsp/realview-a8/drivers/serial.h deleted file mode 100644 index dceea68d1f..0000000000 --- a/bsp/realview-a8/drivers/serial.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-03-30 Bernard the first verion - */ - -#ifndef __UART_H__ -#define __UART_H__ - -#include - -int rt_hw_uart_init(void); - -#endif - - diff --git a/bsp/realview-a8/linux_vmm/.gitignore b/bsp/realview-a8/linux_vmm/.gitignore deleted file mode 100644 index f508c5d65e..0000000000 --- a/bsp/realview-a8/linux_vmm/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.o -*.o.cmd -*.ko -*.ko.cmd -*.mod.c - -Module.symvers -modules.order - -.tmp_versions/ diff --git a/bsp/realview-a8/linux_vmm/Makefile b/bsp/realview-a8/linux_vmm/Makefile deleted file mode 100644 index 9520dce92f..0000000000 --- a/bsp/realview-a8/linux_vmm/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -ccflags-y := -I$(VMM_HDR_DIR) - -obj-m += rtvmm.o - -rtvmm-objs := vmm_linux.o - diff --git a/bsp/realview-a8/linux_vmm/build.sh b/bsp/realview-a8/linux_vmm/build.sh deleted file mode 100644 index f385a17f11..0000000000 --- a/bsp/realview-a8/linux_vmm/build.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -set -e - -# local variable -TISDK_DIR=/home/grissiom/ti-sdk-am335x-evm-06.00.00.00/ - -# external variable {{{ -ROOTFS_DIR=${ROOTFS_DIR:-~/remotedir/buildroot-rootfs/} -KDIR=${KDIR:-$PWD/../../bfm-kernel/} - -TOOLCHAIN_DIR=${TOOLCHAIN_DIR:-${TISDK_DIR}/linux-devkit/sysroots/i686-arago-linux/usr/bin} -TOOLCHAIN_PREFIX=${TOOLCHAIN_PREFIX:-"arm-linux-gnueabihf-"} -# }}} - -export PATH="${TOOLCHAIN_DIR}:$PATH" - -make -C $KDIR M=$PWD ARCH=arm CROSS_COMPILE="${TOOLCHAIN_PREFIX}" V=0 - -#sudo PATH="${TOOLCHAIN_DIR}:$PATH" \ - #make -C $KDIR M=$PWD ARCH=arm CROSS_COMPILE=${TOOLCHAIN_PREFIX} \ - #INSTALL_MOD_PATH=${ROOTFS_DIR} modules_install diff --git a/bsp/realview-a8/linux_vmm/vmm_linux.c b/bsp/realview-a8/linux_vmm/vmm_linux.c deleted file mode 100644 index 110a4f40fa..0000000000 --- a/bsp/realview-a8/linux_vmm/vmm_linux.c +++ /dev/null @@ -1,257 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "vmm_linux.h" - -#define IOMAP_NUM 3 -#define BUFF_SZ (4 * 1024) - -struct vmm_iomap *_linux_iomap = NULL; - -const char *uart_name = "uart"; - -/* some exported Linux Kernel patch */ -extern void vmm_set_status(int status); -extern void vmm_context_init(void *context_addr); -extern unsigned long vmm_save_irq(void); -extern void vmm_restore_irq(unsigned long flags); - -static struct vmm_domain domain = -{ - .kernel = DOMAIN_KERNEL, - .user = DOMAIN_USER, - .io = DOMAIN_IO, - .vmm = DOMAIN_RTVMM, - .vmm_share = DOMAIN_RTVMM_SHR, -}; - -static struct vmm_iomap iomap[RT_VMM_IOMAP_MAXNR] = -{ - {.name = "UART1", .pa = 0x1000A000, .size = 4096}, - {.name = "TIMER", .pa = 0x10012000, .size = 4096}, - {.name = "GIC_CPU", .pa = 0x1E000000, .size = 4096}, - {.name = "GIC_DIST", .pa = 0x1E001000, .size = 4096}, - {.name = "SYS_CTRL", .pa = 0x1001A000, .size = 4096}, - {.pa = 0}, -}; - -void vmm_iomap_init(void) -{ - int index; - - _linux_iomap = &iomap[0]; - - BUILD_BUG_ON(ARRAY_SIZE(iomap) > RT_VMM_IOMAP_MAXNR); - - for (index = 0; index < ARRAY_SIZE(iomap); index++) { - if (_linux_iomap[index].pa == 0) - break; - - if (_linux_iomap[index].size != 0) - _linux_iomap[index].va = - ioremap_nocache(_linux_iomap[index].pa, - _linux_iomap[index].size); - - printk("%s: 0x%08lx --> 0x%p, size %u\n", - _linux_iomap[index].name, - _linux_iomap[index].pa, - _linux_iomap[index].va, - _linux_iomap[index].size); - } - - printk("vmm: init iomap done!\n"); -} - -#if 0 -void trap_set_vector(unsigned long start, unsigned int length) -{ - int sctrl; - - /* C12-C0 is only active when SCTLR.V = 0 */ - asm volatile ("mrc p15, #0, %0, c1, c0, #0" - :"=r" (sctrl)); - sctrl &= ~(1 << 13); - asm volatile ("mcr p15, #0, %0, c1, c0, #0" - : - :"r" (sctrl)); - - asm volatile ("mcr p15, #0, %0, c12, c0, #0" - : - :"r" (start)); - rmb(); -} -#else -extern void trap_set_vector(unsigned long start, unsigned int length); -#endif - -static void vmm_open_domain(void) -{ - unsigned long dval; - asm volatile ("mrc p15, 0, %0, c3, c0\n" - : "=r" (dval)); - dval |= (0x1 << (DOMAIN_RTVMM * 2)) | - (0x1 << (DOMAIN_RTVMM_SHR * 2)); - asm volatile ("mcr p15, 0, %0, c3, c0\n" - : : "r" (dval)); -} - -static void vmm_close_domain(void) -{ - unsigned long dval; - asm volatile ("mrc p15, 0, %0, c3, c0\n" - : "=r" (dval)); - /* we still need access tp DOMAIN_RTVMM_SHR because the IRQ stack is - * there. */ - dval &= ~(0x3 << (DOMAIN_RTVMM * 2)); - asm volatile ("mcr p15, 0, %0, c3, c0\n" - : : "r" (dval)); -} - -static DEFINE_SPINLOCK(init_lock); -void vmm_entry(void) -{ - vmm_entry_t entry; - unsigned long flags; - struct vmm_entry_param eparam = { - .iomap = &iomap[0], - .domain = &domain, - }; - - printk("Entry VMM:0x%08x with iomap 0x%p\n", VMM_BEGIN, _linux_iomap); - - spin_lock_irqsave(&init_lock, flags); - - memcpy((void*)(LINUX_VECTOR_POS), (void*)0xFFFF0000, - LINUX_VECTOR_PGSZ); - flush_icache_range(LINUX_VECTOR_POS, - LINUX_VECTOR_POS + LINUX_VECTOR_PGSZ); - - /*dump_vector(0xFFFF0000);*/ - /* set the interrupt vector to RTT */ - trap_set_vector(VMM_BEGIN, 16 * 4); - /*dump_vector(VMM_END-LINUX_VECTOR_PGSZ);*/ - - entry = (vmm_entry_t)VMM_BEGIN; - - vmm_context_init(&RT_VMM_SHARE->ctx); - vmm_set_status(0x01); - - pr_info("Linux domain: kernel: %d, user: %d, io: %d\n", - DOMAIN_KERNEL, DOMAIN_USER, DOMAIN_IO); - - /* switch to RTT and Good Luck */ - entry(&eparam); - - spin_unlock_irqrestore(&init_lock, flags); - - /* we now switched to virtual IRQ but the hardware IRQ is disabled - * before entering RT-Thread. So we have to enabled it by hand. */ - { - asm volatile ("cpsie i":::"memory", "cc"); - } - - printk("come back to Linux.\n"); - -} - -int vmm_load_fw(const char* filename) -{ - mm_segment_t oldfs = {0}; - unsigned long len; - unsigned long file_sz; - loff_t pos = 0; - struct file *flp = NULL; - char *buf_ptr = (char*)VMM_BEGIN; - - printk("loading RT-Thread:%s ....", filename); - /* FIXME: we should not need this actually. But currently Linux would - * hang without this. Let's just proceed and I will go back to handle - * this in the future. */ - memset((void*)VMM_BEGIN, 0, VMM_SIZE); - - flp = filp_open(filename, O_RDONLY, S_IRWXU); - if (IS_ERR(flp)) - { - printk("vmm loader: open file failed. " - "Return 0x%p\n", flp); - return -1; - } - - /* get file size */ - file_sz = vfs_llseek(flp, 0, SEEK_END); - vfs_llseek(flp, 0, SEEK_SET); - - oldfs = get_fs(); - set_fs(get_ds()); - while (file_sz > 0) - { - // len = vfs_read(flp, (void __user __force *)buff, BUFF_SZ, &pos); - len = vfs_read(flp, (void __user __force*)buf_ptr, BUFF_SZ, &pos); - file_sz -= len; - buf_ptr += len; - } - set_fs(oldfs); - - filp_close(flp, NULL); - - printk("done!\n"); - - /* flush RT-Thread memory */ - flush_cache_vmap(VMM_BEGIN, VMM_END); - - return 0; -} - -static int __init vmm_init(void) -{ - printk("VMM started.\n"); - - vmm_iomap_init(); - /* Open the domain permission so we could write firmware to it */ - vmm_open_domain(); - if (vmm_load_fw("/vmm/rtthread.bin") == 0) - vmm_entry(); - - return 0; -} - -static void __exit vmm_exit(void) -{ - int i; - unsigned long flags; - - spin_lock_irqsave(&init_lock, flags); - vmm_set_status(0x00); - trap_set_vector(LINUX_VECTOR_POS, 16 * 4); - spin_unlock_irqrestore(&init_lock, flags); - - for (i = 0; i < ARRAY_SIZE(iomap); i++) - { - if (iomap[i].pa == 0) - break; - - printk("iounmap %s(0x%p)\n", - iomap[i].name, - iomap[i].va); - iounmap(iomap[i].va); - } - - vmm_close_domain(); - - printk("vmm exit\n"); -} - -module_init(vmm_init); -module_exit(vmm_exit); - -MODULE_AUTHOR("bernard.xiong "); -MODULE_DESCRIPTION("RT-VMM"); -MODULE_LICENSE("GPL"); diff --git a/bsp/realview-a8/linux_vmm/vmm_linux.h b/bsp/realview-a8/linux_vmm/vmm_linux.h deleted file mode 100644 index 395a807751..0000000000 --- a/bsp/realview-a8/linux_vmm/vmm_linux.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __VMM_H__ -#define __VMM_H__ - -#include - -#define RT_VMM_ON_AM335X - -#endif diff --git a/bsp/realview-a8/mk.sh b/bsp/realview-a8/mk.sh deleted file mode 100644 index 964009c271..0000000000 --- a/bsp/realview-a8/mk.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -set -e - -KDIR=~/linux-git -BUILD_ROOT_DIR=/temp-build/buildroot-2014.02/ - -scons -j20 -mkdir -p $BUILD_ROOT_DIR/output/target/vmm -cp rtthread.bin $BUILD_ROOT_DIR/output/target/vmm - -( -cd ./linux_vmm/ -export PATH=/opt/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/:"$PATH" -make -C $KDIR M=$PWD VMM_HDR_DIR=$PWD/../ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -cp rtvmm.ko $BUILD_ROOT_DIR/output/target/root/ -) - -make -C $BUILD_ROOT_DIR diff --git a/bsp/realview-a8/qemu.sh b/bsp/realview-a8/qemu.sh deleted file mode 100644 index 539a608c60..0000000000 --- a/bsp/realview-a8/qemu.sh +++ /dev/null @@ -1 +0,0 @@ -qemu-system-arm -M realview-pb-a8 -kernel rtthread-realview.elf -serial vc -serial vc diff --git a/bsp/realview-a8/realview.lds b/bsp/realview-a8/realview.lds deleted file mode 100644 index f586228840..0000000000 --- a/bsp/realview-a8/realview.lds +++ /dev/null @@ -1,91 +0,0 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SECTIONS -{ - . = 0x70000000; - - __text_start = .; - .text : - { - *(.vectors) - *(.text) - *(.text.*) - - /* 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 modules */ - . = ALIGN(4); - __rtmsymtab_start = .; - KEEP(*(RTMSymTab)) - __rtmsymtab_end = .; - - /* section information for initialization */ - . = ALIGN(4); - __rt_init_start = .; - KEEP(*(SORT(.rti_fn*))) - __rt_init_end = .; - } =0 - __text_end = .; - - __rodata_start = .; - .rodata : { *(.rodata) *(.rodata.*) } - __rodata_end = .; - - . = ALIGN(4); - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } - - . = ALIGN(8); - __data_start = .; - .data : - { - *(.data) - *(.data.*) - } - __data_end = .; - - . = ALIGN(8); - __bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(COMMON) - . = ALIGN(4); - } - . = ALIGN(4); - __bss_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) } - - _end = .; -} diff --git a/bsp/realview-a8/realview_vmm.lds.S b/bsp/realview-a8/realview_vmm.lds.S deleted file mode 100644 index 09cb9a302c..0000000000 --- a/bsp/realview-a8/realview_vmm.lds.S +++ /dev/null @@ -1,140 +0,0 @@ -#include - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) - -SECTIONS -{ - . = VMM_BEGIN; - - __text_start = .; - .text.share : - { - KEEP(*(.vectors)) - *(.text.isr) - *(.vmm_glue) - } - ASSERT(SIZEOF(.text.share) <= VMM_SHARE_TEXT_PGSZ, ".text.share too big") - - . = VMM_BEGIN + VMM_SHARE_TEXT_PGSZ; - /* the vectore page is saved here - * { - * } - */ - - . = VMM_SHARE_DATA_POS; - .data.share : - { - __data_share_start = .; - *(.data.share*) - __data_share_end = .; - } - ASSERT(SIZEOF(.data.share) <= (VMM_SHARE_DATA_PGSZ), ".data.share is too big") - - . = VMM_SHARE_BSS_POS; - .bss.share : - { - __bss_share_start = .; - *(.bss.share*) - __bss_share_end = .; - } - ASSERT(SIZEOF(.bss.share) <= (VMM_SHARE_BSS_PGSZ), ".bss.share is too big") - - . = VMM_SHARE_CTX_POS; - .vmm.share : - { - /* the vmm context goes here */ - __vmm_share_start = .; - *(.vmm.share*) - __vmm_share_end = .; - } - ASSERT(SIZEOF(.vmm.share) <= (VMM_SHARE_CTX_PGSZ), "vmm share context is too big") - - . = VMM_BEGIN + VMM_SHARE_PGSZ; - .text : - { - *(.vmm_init) - *(.text) - *(.text.*) - - /* 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 modules */ - . = ALIGN(4); - __rtmsymtab_start = .; - KEEP(*(RTMSymTab)) - __rtmsymtab_end = .; - - /* section information for initialization */ - . = ALIGN(4); - __rt_init_start = .; - KEEP(*(SORT(.rti_fn*))) - __rt_init_end = .; - } - __text_end = .; - - __rodata_start = .; - .rodata : { *(.rodata) *(.rodata.*) } - __rodata_end = .; - - . = ALIGN(4); - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } - - __data_start = .; - . = ALIGN(8); - .data : - { - *(.data) - *(.data.*) - } - __data_end = .; - - . = ALIGN(8); - __bss_start = __data_end; - .bss : - { - vmm_stack_start = .; - . = vmm_stack_start + RT_VMM_STACK_SIZE; - vmm_stack_end = .; - *(.bss) - *(.bss.*) - *(COMMON) - . = ALIGN(4); - } - . = ALIGN(4); - __bss_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) } - - _end = .; -} diff --git a/bsp/realview-a8/rtconfig.h b/bsp/realview-a8/rtconfig.h deleted file mode 100644 index a83c9e020d..0000000000 --- a/bsp/realview-a8/rtconfig.h +++ /dev/null @@ -1,153 +0,0 @@ -/* RT-Thread config file */ -#ifndef __RTTHREAD_CFG_H__ -#define __RTTHREAD_CFG_H__ - -// - -// -#define RT_NAME_MAX 6 -// -#define RT_ALIGN_SIZE 4 -// -// 8 -// 32 -// 256 -// -#define RT_THREAD_PRIORITY_MAX 32 -// -#define RT_TICK_PER_SECOND 1000 -// -#define IDLE_THREAD_STACK_SIZE 512 -//

-#define RT_DEBUG -#define RT_DEBUG_COLOR -// -// #define RT_THREAD_DEBUG -// -// #define RT_USING_OVERFLOW_CHECK -//
- -// -#define RT_USING_HOOK -//
-// #define RT_USING_TIMER_SOFT -// -#define RT_TIMER_THREAD_PRIO 4 -// -#define RT_TIMER_THREAD_STACK_SIZE 512 -// -#define RT_TIMER_TICK_PER_SECOND 10 -//
- -//
-// -#define RT_USING_SEMAPHORE -// -#define RT_USING_MUTEX -// -#define RT_USING_EVENT -// -#define RT_USING_MAILBOX -// -#define RT_USING_MESSAGEQUEUE -//
- -//
-// -#define RT_USING_MEMPOOL -// -// #define RT_USING_MEMHEAP -// -#define RT_USING_HEAP -// -// #define RT_USING_MEMHEAP_AS_HEAP -// -#define RT_USING_SMALL_MEM -// -// #define RT_USING_SLAB -//
- -//
-#define RT_USING_DEVICE -// -#define RT_USING_DEVICE_IPC -// -#define RT_USING_SERIAL -#define RT_SERIAL_USING_DMA -// -#define RT_UART_RX_BUFFER_SIZE 64 -// -#define RT_USING_INTERRUPT_INFO -// -// #define RT_USING_UART0 -// -#define RT_USING_UART1 -//
- -//
-#define RT_USING_CONSOLE -// -#define RT_CONSOLEBUF_SIZE 128 -// -#define RT_CONSOLE_DEVICE_NAME "uart1" -//
- -// -#define RT_USING_COMPONENTS_INIT -//
-#define RT_USING_FINSH -// -#define FINSH_USING_MSH -// -#define FINSH_USING_MSH_DEFAULT -// -#define FINSH_USING_SYMTAB -// -#define FINSH_USING_DESCRIPTION -// -#define FINSH_THREAD_STACK_SIZE 4096 -//
- -//
-// -#define RT_USING_LIBC -// -#define RT_USING_PTHREADS -//
- -//
-// #define RT_USING_DFS -// -// #define DFS_USING_WORKDIR -// -#define DFS_FILESYSTEMS_MAX 2 -// -#define DFS_FD_MAX 4 -// -#define RT_USING_DFS_ELMFAT -// -// 1 -// 2 -// -#define RT_DFS_ELM_USE_LFN 1 -// -#define RT_DFS_ELM_MAX_LFN 64 -// -// #define RT_USING_DFS_YAFFS2 -// -// #define RT_USING_DFS_UFFS -// -// #define RT_USING_DFS_DEVFS -// -// #define RT_USING_DFS_NFS -// -#define RT_NFS_HOST_EXPORT "192.168.1.5:/" -//
- -// - -//
-// #define RT_USING_VMM -//
- -#endif diff --git a/bsp/realview-a8/rtconfig.py b/bsp/realview-a8/rtconfig.py deleted file mode 100644 index 21aeec8787..0000000000 --- a/bsp/realview-a8/rtconfig.py +++ /dev/null @@ -1,55 +0,0 @@ -import os - -# toolchains options -ARCH='arm' -CPU='realview-a8-vmm' -CROSS_TOOL='gcc' - -if os.getenv('RTT_CC'): - CROSS_TOOL = os.getenv('RTT_CC') - -PLATFORM = 'gcc' -# EXEC_PATH = r'/opt/arm-2012.09/bin' -EXEC_PATH = r'C:\Program Files (x86)\CodeSourcery\Sourcery_CodeBench_Lite_for_ARM_EABI\bin' -EXEC_PATH = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin' - -if os.getenv('RTT_EXEC_PATH'): - EXEC_PATH = os.getenv('RTT_EXEC_PATH') - -BUILD = 'debug' - -if PLATFORM == 'gcc': - # toolchains - PREFIX = 'arm-none-eabi-' - 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 = ' -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3-d16 -ftree-vectorize -ffast-math -mfloat-abi=softfp' - CFLAGS = DEVICE + ' -Wall' - AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__' - LINK_SCRIPT = 'realview_vmm.lds' - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=realview.map,-cref,-u,system_vectors'+\ - ' -T %s' % LINK_SCRIPT - - CPATH = '' - LPATH = '' - - # generate debug info in all cases - AFLAGS += ' -gdwarf-2' - CFLAGS += ' -g -gdwarf-2' - - if BUILD == 'debug': - CFLAGS += ' -O0' - else: - CFLAGS += ' -O2' - - POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' +\ - SIZE + ' $TARGET \n' +\ - OBJDUMP + ' -S $TARGET > rtt.S\n' diff --git a/bsp/realview-a8/rtt_api.h b/bsp/realview-a8/rtt_api.h deleted file mode 100644 index cf8e8ddb1a..0000000000 --- a/bsp/realview-a8/rtt_api.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2014-04-07 Grissiom first version - */ - -#ifndef __RTT_API_H__ -#define __RTT_API_H__ - -/* 4MB in size */ -#define VMM_SIZE 0x400000 -#define VMM_END 0xc8000000 -#define VMM_BEGIN (VMM_END - VMM_SIZE) - -/* VMM Memory Map: - * - * --- VMM_BEGIN --- +------+ - * .vectors | 4KB | - * .text.share | | - * ----------------- + | - * guest vector page | 4KB | - * ----------------- + | - * .data.share | 4KB | - * ----------------- + | - * .bss.share | 4KB | - * -- SHARE_BASE -- + | 1MB - * shared context | shared region - * ----------------- | - * blabla... | - * ----------------- +------+ - * vmm text | - * rodata | - * blabla... | - * ----------------- | private region - * vmm data | - * ----------------- | - * vmm bss | - * ---- VMM_END ---- +------+ - * - */ - -/* 1MB is one level one page table entry, if we want to page table to be - * simple(avoid TLB miss), we could allocate 1MB for shared memory. */ -#define VMM_SHARE_PGSZ (1024*1024) - -/* the size and position of shared code text */ -#define VMM_SHARE_TEXT_PGSZ 4096 - -/* the size and position of vector's page size in Linux */ -#define LINUX_VECTOR_PGSZ 4096 -#define LINUX_VECTOR_POS (VMM_BEGIN + VMM_SHARE_TEXT_PGSZ) - -/* the size and position of shared code data */ -#define VMM_SHARE_DATA_PGSZ 4096 -#define VMM_SHARE_DATA_POS (LINUX_VECTOR_POS + LINUX_VECTOR_PGSZ) - -/* the size and position of shared code bss */ -#define VMM_SHARE_BSS_PGSZ 4096 -#define VMM_SHARE_BSS_POS (VMM_SHARE_DATA_POS + VMM_SHARE_DATA_PGSZ) - -/* the size and position of shared code bss */ -#define VMM_SHARE_CTX_PGSZ (VMM_SHARE_PGSZ - \ - LINUX_VECTOR_PGSZ - \ - VMM_SHARE_TEXT_PGSZ - \ - VMM_SHARE_DATA_PGSZ - \ - VMM_SHARE_BSS_PGSZ) -#if VMM_SHARE_CTX_PGSZ <= 0 -#error -#endif - -#define VMM_SHARE_CTX_POS (VMM_SHARE_BSS_POS + VMM_SHARE_BSS_PGSZ) - -/* the size of FIQ stack page size in RT-Thread */ -#define RT_FIQ_STACK_PGSZ 0 - -/* the size of IRQ stack page size in RT-Thread */ -#define RT_IRQ_STACK_PGSZ 4096 - -#ifdef HEAP_END -#undef HEAP_END -#endif -#define HEAP_END (VMM_END) - -#define RT_VMM_VIRQ_TRIGGER 10 - -#define RT_VMM_STACK_SIZE 1024 - -/* the max number of iomap entries */ -#define RT_VMM_IOMAP_MAXNR 16 - -#ifndef __iomem -#define __iomem -#endif - -#define IRQS_NR_32 ((96 + 31)/32) - -/*#define RT_VMM_USING_DOMAIN*/ - -#ifndef __ASSEMBLY__ - -/* keep consistent with linux/arch/arm/include/vmm/vmm.h */ -struct vmm_context -{ - /* the status of vGuest irq, read only for RT-Thread */ - volatile unsigned long virq_status; - - /* has interrupt pended on vGuest OS IRQ */ - volatile unsigned long virq_pended; - - /* pending interrupt for vGuest OS */ - volatile unsigned long virq_pending[IRQS_NR_32]; -}; - -struct vmm_domain -{ - /* the number of kernel domain */ - char kernel; - /* the number of user domain */ - char user; - /* the number of io domain */ - char io; - /* the number of vmm domain */ - char vmm; - /* the number of vmm_share domain */ - char vmm_share; -}; - -struct vmm_iomap -{ - const char name[16]; /* iomap name */ - - unsigned long pa; /* physical address */ - volatile void __iomem * va; /* virtual address */ - size_t size; /* memory size */ -}; - -struct vmm_entry_param -{ - struct vmm_iomap *iomap; - struct vmm_domain *domain; -}; - -typedef void (*vmm_entry_t)(struct vmm_entry_param* param); - -struct rt_vmm_share_layout -{ - struct vmm_context ctx; -}; - -#ifndef __KERNEL__ -/* not in Linux, use better type check */ -extern struct rt_vmm_share_layout rt_vmm_share; -#define RT_VMM_SHARE (&rt_vmm_share) -#else -#define RT_VMM_SHARE ((struct rt_vmm_share_layout*)VMM_SHARE_CTX_POS) -#endif - -#endif - -#endif /* end of include guard: __RTT_API_H__ */ From 2afca007874df3a056dcad382a303b4903e6206d Mon Sep 17 00:00:00 2001 From: chunyexixiaoyu <834670833@qq.com> Date: Sun, 25 Apr 2021 20:01:23 +0800 Subject: [PATCH 11/13] [ADD]riscv.c dlmodule can support riscv architecture [CHG]dlelf.c support distinguishing 32-bit ELF format and 64-bit ELF format --- components/libc/libdl/arch/riscv.c | 60 +++++++++++++++ components/libc/libdl/dlelf.c | 104 +++++++++++++++----------- components/libc/libdl/dlelf.h | 115 ++++++++++++++++++++++++++++- components/libc/libdl/dlmodule.c | 2 +- 4 files changed, 236 insertions(+), 45 deletions(-) create mode 100644 components/libc/libdl/arch/riscv.c diff --git a/components/libc/libdl/arch/riscv.c b/components/libc/libdl/arch/riscv.c new file mode 100644 index 0000000000..33cae28d16 --- /dev/null +++ b/components/libc/libdl/arch/riscv.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/04/23 chunyexixiaoyu first version + + */ + +#include "../dlmodule.h" +#include "../dlelf.h" + +#if (__riscv_xlen == 64) +#define R_RISCV_NONE 0 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 + +int dlmodule_relocate(struct rt_dlmodule *module, Elf_Rel *rel, Elf_Addr sym_val) +{ + Elf64_Addr *where, tmp; + Elf64_Sword addend, offset; + rt_uint64_t upper, lower, sign, j1, j2; + + where = (Elf64_Addr *)((rt_uint8_t *)module->mem_space + + rel->r_offset + - module->vstart_addr); + switch (ELF64_R_TYPE(rel->r_info)) + { + case R_RISCV_NONE: + break; + case R_RISCV_64: + *where = (Elf64_Addr)(sym_val + rel->r_addend); + RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_RISCV_64: %x -> %x\n",where, *where)); + break; + case R_RISCV_RELATIVE: + *where = (Elf64_Addr)((rt_uint8_t *)module->mem_space - module->vstart_addr + rel->r_addend); + RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_RISCV_RELATIVE: %x -> %x\n",where, *where)); + break; + case R_RISCV_JUMP_SLOT: + *where = (Elf64_Addr)sym_val; + RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_RISCV_JUMP_SLOT: %x -> %x\n",where, *where)); + break; + default: + RT_DEBUG_LOG(RT_DEBUG_MODULE, ("__riscv__ELF: invalid relocate TYPE %d\n", ELF64_R_TYPE(rel->r_info))); + return -1; + } + return 0; +} +#endif diff --git a/components/libc/libdl/dlelf.c b/components/libc/libdl/dlelf.c index f573122a48..418ad7539a 100644 --- a/components/libc/libdl/dlelf.c +++ b/components/libc/libdl/dlelf.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018/08/29 Bernard first version + * 2021/04/23 chunyexixiaoyu distinguish 32-bit and 64-bit */ #include "dlmodule.h" @@ -18,8 +19,8 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_ptr) { rt_bool_t linked = RT_FALSE; - rt_uint32_t index, module_size = 0; - Elf32_Addr vstart_addr, vend_addr; + rt_ubase_t index, module_size = 0; + Elf_Addr vstart_addr, vend_addr; rt_bool_t has_vstart; RT_ASSERT(module_ptr != RT_NULL); @@ -53,7 +54,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt has_vstart = RT_TRUE; if (vend_addr < vstart_addr) { - rt_kprintf("invalid elf: segment %d: p_vaddr: %d, p_memsz: %d\n", + LOG_E("invalid elf: segment %d: p_vaddr: %d, p_memsz: %d\n", index, phdr[index].p_vaddr, phdr[index].p_memsz); return RT_NULL; } @@ -62,7 +63,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt { if (phdr[index].p_vaddr < vend_addr) { - rt_kprintf("invalid elf: segment should be sorted and not overlapped\n"); + LOG_E("invalid elf: segment should be sorted and not overlapped\n"); return RT_NULL; } if (phdr[index].p_vaddr > vend_addr + 16) @@ -74,7 +75,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt vend_addr = phdr[index].p_vaddr + phdr[index].p_memsz; if (vend_addr < phdr[index].p_vaddr) { - rt_kprintf("invalid elf: " + LOG_E("invalid elf: " "segment %d address overflow\n", index); return RT_NULL; } @@ -85,7 +86,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt LOG_D("module size: %d, vstart_addr: 0x%p", module_size, vstart_addr); if (module_size == 0) { - rt_kprintf("Module: size error\n"); + LOG_E("Module: size error\n"); return -RT_ERROR; } @@ -96,7 +97,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt module->mem_space = rt_malloc(module_size); if (module->mem_space == RT_NULL) { - rt_kprintf("Module: allocate space failed.\n"); + LOG_E("Module: allocate space failed.\n"); return -RT_ERROR; } module->mem_size = module_size; @@ -119,42 +120,49 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt /* handle relocation section */ for (index = 0; index < elf_module->e_shnum; index ++) { - rt_uint32_t i, nr_reloc; - Elf32_Sym *symtab; - Elf32_Rel *rel; + rt_ubase_t i, nr_reloc; + Elf_Sym *symtab; + Elf_Rel *rel; rt_uint8_t *strtab; static rt_bool_t unsolved = RT_FALSE; - + #if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32)) if (!IS_REL(shdr[index])) continue; + #elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64)) + if (!IS_RELA(shdr[index])) + continue; + #endif /* get relocate item */ - rel = (Elf32_Rel *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset); + rel = (Elf_Rel *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset); /* locate .rel.plt and .rel.dyn section */ - symtab = (Elf32_Sym *)((rt_uint8_t *)module_ptr + + symtab = (Elf_Sym *)((rt_uint8_t *)module_ptr + shdr[shdr[index].sh_link].sh_offset); strtab = (rt_uint8_t *)module_ptr + shdr[shdr[shdr[index].sh_link].sh_link].sh_offset; - nr_reloc = (rt_uint32_t)(shdr[index].sh_size / sizeof(Elf32_Rel)); + nr_reloc = (rt_ubase_t)(shdr[index].sh_size / sizeof(Elf_Rel)); /* relocate every items */ for (i = 0; i < nr_reloc; i ++) { - Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)]; - + #if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32)) + Elf_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)]; + #elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64)) + Elf_Sym *sym = &symtab[ELF64_R_SYM(rel->r_info)]; + #endif LOG_D("relocate symbol %s shndx %d", strtab + sym->st_name, sym->st_shndx); if ((sym->st_shndx != SHT_NULL) ||(ELF_ST_BIND(sym->st_info) == STB_LOCAL)) { - Elf32_Addr addr; + Elf_Addr addr; - addr = (Elf32_Addr)(module->mem_space + sym->st_value - vstart_addr); + addr = (Elf_Addr)(module->mem_space + sym->st_value - vstart_addr); dlmodule_relocate(module, rel, addr); } else if (!linked) { - Elf32_Addr addr; + Elf_Addr addr; LOG_D("relocate symbol: %s", strtab + sym->st_name); /* need to resolve symbol in kernel symbol table */ @@ -191,13 +199,13 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt if (index != elf_module->e_shnum) { int i, count = 0; - Elf32_Sym *symtab = RT_NULL; + Elf_Sym *symtab = RT_NULL; rt_uint8_t *strtab = RT_NULL; - symtab = (Elf32_Sym *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset); + symtab = (Elf_Sym *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset); strtab = (rt_uint8_t *)module_ptr + shdr[shdr[index].sh_link].sh_offset; - for (i = 0; i < shdr[index].sh_size / sizeof(Elf32_Sym); i++) + for (i = 0; i < shdr[index].sh_size / sizeof(Elf_Sym); i++) { if ((ELF_ST_BIND(symtab[i].st_info) == STB_GLOBAL) && (ELF_ST_TYPE(symtab[i].st_info) == STT_FUNC)) @@ -207,7 +215,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt module->symtab = (struct rt_module_symtab *)rt_malloc (count * sizeof(struct rt_module_symtab)); module->nsym = count; - for (i = 0, count = 0; i < shdr[index].sh_size / sizeof(Elf32_Sym); i++) + for (i = 0, count = 0; i < shdr[index].sh_size / sizeof(Elf_Sym); i++) { rt_size_t length; @@ -231,7 +239,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt rt_uint32_t flag = 0; rt_uint16_t priority; rt_uint32_t stacksize; - for (i = 0; i < shdr[index].sh_size / sizeof(Elf32_Sym); i++) + for (i = 0; i < shdr[index].sh_size / sizeof(Elf_Sym); i++) { if (((flag & 0x01) == 0) && (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_priority") == 0)) @@ -267,8 +275,8 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module_ptr) { - rt_uint32_t index, rodata_addr = 0, bss_addr = 0, data_addr = 0; - rt_uint32_t module_addr = 0, module_size = 0; + rt_ubase_t index, rodata_addr = 0, bss_addr = 0, data_addr = 0; + rt_ubase_t module_addr = 0, module_size = 0; rt_uint8_t *ptr, *strtab, *shstrab; /* get the ELF image size */ @@ -306,7 +314,7 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module module->mem_space = rt_malloc(module_size); if (module->mem_space == RT_NULL) { - rt_kprintf("Module: allocate space failed.\n"); + LOG_E("Module: allocate space failed.\n"); return -RT_ERROR; } module->mem_size = module_size; @@ -367,35 +375,45 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module /* handle relocation section */ for (index = 0; index < elf_module->e_shnum; index ++) { - rt_uint32_t i, nr_reloc; - Elf32_Sym *symtab; - Elf32_Rel *rel; + rt_ubase_t i, nr_reloc; + Elf_Sym *symtab; + Elf_Rel *rel; + #if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32)) if (!IS_REL(shdr[index])) continue; + #elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64)) + if (!IS_RELA(shdr[index])) + continue; + #endif + /* get relocate item */ - rel = (Elf32_Rel *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset); + rel = (Elf_Rel *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset); /* locate .dynsym and .dynstr */ - symtab = (Elf32_Sym *)((rt_uint8_t *)module_ptr + + symtab = (Elf_Sym *)((rt_uint8_t *)module_ptr + shdr[shdr[index].sh_link].sh_offset); strtab = (rt_uint8_t *)module_ptr + shdr[shdr[shdr[index].sh_link].sh_link].sh_offset; shstrab = (rt_uint8_t *)module_ptr + shdr[elf_module->e_shstrndx].sh_offset; - nr_reloc = (rt_uint32_t)(shdr[index].sh_size / sizeof(Elf32_Rel)); + nr_reloc = (rt_uint32_t)(shdr[index].sh_size / sizeof(Elf_Rel)); /* relocate every items */ for (i = 0; i < nr_reloc; i ++) { - Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)]; + #if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32)) + Elf_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)]; + #elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64)) + Elf_Sym *sym = &symtab[ELF64_R_SYM(rel->r_info)]; + #endif LOG_D("relocate symbol: %s", strtab + sym->st_name); if (sym->st_shndx != STN_UNDEF) { - Elf32_Addr addr = 0; + Elf_Addr addr = 0; if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION) || (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)) @@ -405,28 +423,28 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module { /* relocate rodata section */ LOG_D("rodata"); - addr = (Elf32_Addr)(rodata_addr + sym->st_value); + addr = (Elf_Addr)(rodata_addr + sym->st_value); } else if (rt_strncmp((const char *) (shstrab + shdr[sym->st_shndx].sh_name), ELF_BSS, 5) == 0) { /* relocate bss section */ LOG_D("bss"); - addr = (Elf32_Addr)bss_addr + sym->st_value; + addr = (Elf_Addr)bss_addr + sym->st_value; } else if (rt_strncmp((const char *)(shstrab + shdr[sym->st_shndx].sh_name), ELF_DATA, 6) == 0) { /* relocate data section */ LOG_D("data"); - addr = (Elf32_Addr)data_addr + sym->st_value; + addr = (Elf_Addr)data_addr + sym->st_value; } if (addr != 0) dlmodule_relocate(module, rel, addr); } else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) { - addr = (Elf32_Addr)((rt_uint8_t *) module->mem_space - module_addr + sym->st_value); + addr = (Elf_Addr)((rt_uint8_t *) module->mem_space - module_addr + sym->st_value); /* relocate function */ dlmodule_relocate(module, rel, addr); @@ -436,14 +454,14 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module { /* relocate function */ dlmodule_relocate(module, rel, - (Elf32_Addr)((rt_uint8_t *) + (Elf_Addr)((rt_uint8_t *) module->mem_space - module_addr + sym->st_value)); } else { - Elf32_Addr addr; + Elf_Addr addr; if (ELF32_R_TYPE(rel->r_info) != R_ARM_V4BX) { @@ -451,7 +469,7 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module /* need to resolve symbol in kernel symbol table */ addr = dlmodule_symbol_find((const char *)(strtab + sym->st_name)); - if (addr != (Elf32_Addr)RT_NULL) + if (addr != (Elf_Addr)RT_NULL) { dlmodule_relocate(module, rel, addr); LOG_D("symbol addr 0x%x", addr); @@ -462,7 +480,7 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module } else { - addr = (Elf32_Addr)((rt_uint8_t *) module->mem_space - module_addr + sym->st_value); + addr = (Elf_Addr)((rt_uint8_t *) module->mem_space - module_addr + sym->st_value); dlmodule_relocate(module, rel, addr); } } diff --git a/components/libc/libdl/dlelf.h b/components/libc/libdl/dlelf.h index ad9e2cdade..540fe2c8aa 100644 --- a/components/libc/libdl/dlelf.h +++ b/components/libc/libdl/dlelf.h @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018/08/29 Bernard first version + * 2021/04/23 chunyexixiaoyu distinguish 32-bit and 64-bit */ #ifndef DL_ELF_H__ @@ -19,6 +20,21 @@ typedef rt_int32_t Elf32_Sword; /* Signed large integer */ typedef rt_uint32_t Elf32_Word; /* Unsigned large integer */ typedef rt_uint16_t Elf32_Half; /* Unsigned medium integer */ +typedef rt_uint64_t Elf64_Addr; +typedef rt_uint16_t Elf64_Half; +typedef rt_int16_t Elf64_SHalf; +typedef rt_uint64_t Elf64_Off; +typedef rt_int32_t Elf64_Sword; +typedef rt_uint32_t Elf64_Word; +typedef rt_uint64_t Elf64_Xword; +typedef rt_int64_t Elf64_Sxword; +typedef uint16_t Elf64_Section; + + + + + + /* e_ident[] magic number */ #define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ #define ELFMAG1 'E' /* e_ident[EI_MAG1] */ @@ -75,6 +91,25 @@ typedef struct elfhdr header string table" entry offset */ } Elf32_Ehdr; + +typedef struct elf64_hdr { + unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ + Elf64_Half e_type; /* object file type */ + Elf64_Half e_machine; /* machine */ + Elf64_Word e_version; /* object file version */ + Elf64_Addr e_entry; /* virtual entry point */ + Elf64_Off e_phoff; /* program header table offset */ + Elf64_Off e_shoff; /* section header table offset */ + Elf64_Word e_flags; /* processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size */ + Elf64_Half e_phentsize; /* program header entry size */ + Elf64_Half e_phnum; /* number of program header entries */ + Elf64_Half e_shentsize; /* section header entry size */ + Elf64_Half e_shnum; /* number of section header entries */ + Elf64_Half e_shstrndx; /* section header table's "section + header string table" entry offset */ +} Elf64_Ehdr; + /* Section Header */ typedef struct { @@ -91,6 +126,21 @@ typedef struct Elf32_Word sh_entsize; /* section entry size */ } Elf32_Shdr; +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + + /* Section names */ #define ELF_BSS ".bss" /* uninitialized data */ #define ELF_DATA ".data" /* initialized data */ @@ -126,6 +176,19 @@ typedef struct elf32_sym Elf32_Half st_shndx; /* section header index */ } Elf32_Sym; + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + + + #define STB_LOCAL 0 /* BIND */ #define STB_GLOBAL 1 #define STB_WEAK 2 @@ -160,6 +223,12 @@ typedef struct Elf32_Word r_info; /* symbol table index and type */ } Elf32_Rel; +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + /* Relocation entry with explicit addend */ typedef struct { @@ -168,11 +237,24 @@ typedef struct Elf32_Sword r_addend; } Elf32_Rela; +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + /* Extract relocation info - r_info */ #define ELF32_R_SYM(i) ((i) >> 8) #define ELF32_R_TYPE(i) ((unsigned char) (i)) #define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) + + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) + /* * Relocation type for arm */ @@ -219,6 +301,23 @@ typedef struct Elf32_Word p_align; /* memory alignment */ } Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + + + + + /* p_type */ #define PT_NULL 0 #define PT_LOAD 1 @@ -273,13 +372,27 @@ typedef struct #define IS_AX(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_EXECINSTR)) #define IS_AW(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE)) +#if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32)) #define elf_module ((Elf32_Ehdr *)module_ptr) #define shdr ((Elf32_Shdr *)((rt_uint8_t *)module_ptr + elf_module->e_shoff)) #define phdr ((Elf32_Phdr *)((rt_uint8_t *)module_ptr + elf_module->e_phoff)) +typedef Elf32_Sym Elf_Sym; +typedef Elf32_Rel Elf_Rel; +typedef Elf32_Addr Elf_Addr; +#elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64)) +#define elf_module ((Elf64_Ehdr *)module_ptr) +#define shdr ((Elf64_Shdr *)((rt_uint8_t *)module_ptr + elf_module->e_shoff)) +#define phdr ((Elf64_Phdr *)((rt_uint8_t *)module_ptr + elf_module->e_phoff)) + +typedef Elf64_Sym Elf_Sym; +typedef Elf64_Rela Elf_Rel; +typedef Elf64_Addr Elf_Addr; +#endif +int dlmodule_relocate(struct rt_dlmodule *module, Elf_Rel *rel, Elf_Addr sym_val); rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_ptr); rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module_ptr); -int dlmodule_relocate(struct rt_dlmodule *module, Elf32_Rel *rel, Elf32_Addr sym_val); + #endif diff --git a/components/libc/libdl/dlmodule.c b/components/libc/libdl/dlmodule.c index c4bbb26b37..044c05a994 100644 --- a/components/libc/libdl/dlmodule.c +++ b/components/libc/libdl/dlmodule.c @@ -464,7 +464,7 @@ struct rt_dlmodule* dlmodule_load(const char* filename) } /* check ELF class */ - if (elf_module->e_ident[EI_CLASS] != ELFCLASS32) + if ((elf_module->e_ident[EI_CLASS] != ELFCLASS32)&&(elf_module->e_ident[EI_CLASS] != ELFCLASS64)) { rt_kprintf("Module: ELF class error\n"); goto __exit; From 79771e42e7f638587bb34cdabbeb7eba850c0ee8 Mon Sep 17 00:00:00 2001 From: wanghaijing Date: Wed, 28 Apr 2021 14:26:43 +0800 Subject: [PATCH 12/13] [rename] stm32f767-fire-challenger-v1 --- .github/workflows/action.yml | 2 +- bsp/stm32/README.md | 2 +- bsp/stm32/stm32f767-atk-apollo/README.md | 2 +- bsp/stm32/stm32f767-atk-apollo/board/Kconfig | 15 - .../.config | 233 +++- .../.gitignore | 0 .../Kconfig | 0 .../README.md | 8 +- .../SConscript | 0 .../SConstruct | 0 .../applications/SConscript | 0 .../applications/main.c | 0 .../board/CubeMX_Config/.mxproject | 0 .../board/CubeMX_Config/CubeMX_Config.ioc | 0 .../board/CubeMX_Config/Inc/main.h | 0 .../CubeMX_Config/Inc/stm32f7xx_hal_conf.h | 0 .../board/CubeMX_Config/Inc/stm32f7xx_it.h | 0 .../MDK-ARM/CubeMX_Config.uvoptx | 0 .../MDK-ARM/CubeMX_Config.uvprojx | 0 .../MDK-ARM/startup_stm32f767xx.s | 0 .../board/CubeMX_Config/Src/main.c | 0 .../CubeMX_Config/Src/stm32f7xx_hal_msp.c | 0 .../board/CubeMX_Config/Src/stm32f7xx_it.c | 0 .../CubeMX_Config/Src/system_stm32f7xx.c | 0 .../board/Kconfig | 0 .../board/SConscript | 0 .../board/board.c | 0 .../board/board.h | 0 .../board/linker_scripts/link.icf | 0 .../board/linker_scripts/link.lds | 0 .../board/linker_scripts/link.sct | 0 .../board/ports/drv_qspi_flash.c | 0 .../board/ports/fal_cfg.h | 0 .../board/ports/lcd_port.h | 0 .../board/ports/phy_reset.c | 0 .../board/ports/sdcard_port.c | 0 .../board/ports/sdram_port.h | 0 .../figures/board.jpg | Bin .../project.ewd | 0 .../project.ewp | 0 .../project.eww | 0 .../project.uvopt | 0 .../project.uvoptx | 1040 +++++++++++++++++ .../project.uvprojx | 651 ++++++----- .../rtconfig.h | 29 +- .../rtconfig.py | 0 .../template.ewp | 0 .../template.eww | 0 .../template.uvoptx | 0 .../template.uvprojx | 0 50 files changed, 1613 insertions(+), 369 deletions(-) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/.config (54%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/.gitignore (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/Kconfig (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/README.md (93%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/SConscript (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/SConstruct (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/applications/SConscript (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/applications/main.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/.mxproject (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/CubeMX_Config.ioc (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/Inc/main.h (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/Inc/stm32f7xx_it.h (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvoptx (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvprojx (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/MDK-ARM/startup_stm32f767xx.s (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/Src/main.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/Src/stm32f7xx_it.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/CubeMX_Config/Src/system_stm32f7xx.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/Kconfig (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/SConscript (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/board.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/board.h (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/linker_scripts/link.icf (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/linker_scripts/link.lds (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/linker_scripts/link.sct (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/ports/drv_qspi_flash.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/ports/fal_cfg.h (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/ports/lcd_port.h (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/ports/phy_reset.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/ports/sdcard_port.c (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/board/ports/sdram_port.h (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/figures/board.jpg (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/project.ewd (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/project.ewp (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/project.eww (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/project.uvopt (100%) create mode 100644 bsp/stm32/stm32f767-fire-challenger-v1/project.uvoptx rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/project.uvprojx (79%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/rtconfig.h (88%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/rtconfig.py (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/template.ewp (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/template.eww (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/template.uvoptx (100%) rename bsp/stm32/{stm32f767-fire-challenger => stm32f767-fire-challenger-v1}/template.uvprojx (100%) diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index 6b902850a4..ecbc19cca9 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -97,7 +97,7 @@ jobs: - {RTT_BSP: "stm32/stm32f469-st-disco", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "stm32/stm32f746-st-disco", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "stm32/stm32f767-atk-apollo", RTT_TOOL_CHAIN: "sourcery-arm"} - - {RTT_BSP: "stm32/stm32f767-fire-challenger", RTT_TOOL_CHAIN: "sourcery-arm"} + - {RTT_BSP: "stm32/stm32f767-fire-challenger-v1", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "stm32/stm32f767-st-nucleo", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "stm32/stm32g070-st-nucleo", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "stm32/stm32g071-st-nucleo", RTT_TOOL_CHAIN: "sourcery-arm"} diff --git a/bsp/stm32/README.md b/bsp/stm32/README.md index 1a36605aa1..1c355c2d1d 100644 --- a/bsp/stm32/README.md +++ b/bsp/stm32/README.md @@ -43,7 +43,7 @@ STM32 系列 BSP 目前支持情况如下表所示: | **F7 系列** | | | [stm32f746-st-disco](stm32f746-st-disco) | ST 官方 STM32F746-discovery 开发板 | | [stm32f767-atk-apollo](stm32f767-atk-apollo) | 正点原子 F767 阿波罗开发板 | -| [stm32f767-fire-challenger](stm32f767-fire-challenger/) | 野火 F767 挑战者开发板 | +| [stm32f767-fire-challenger-v1](stm32f767-fire-challenger-v1/) | 野火 F767-V1 挑战者开发板 | | [stm32f767-st-nucleo](stm32f767-st-nucleo) | ST 官方 STM32F767-nucleo 开发板 | | [stm32f769-st-disco](stm32f769-st-disco) | ST 官方 STM32f769-discovery 开发板 | | **G0 系列** | | diff --git a/bsp/stm32/stm32f767-atk-apollo/README.md b/bsp/stm32/stm32f767-atk-apollo/README.md index efec3e704b..3045c68705 100644 --- a/bsp/stm32/stm32f767-atk-apollo/README.md +++ b/bsp/stm32/stm32f767-atk-apollo/README.md @@ -52,7 +52,7 @@ | **片上外设** | **支持情况** | **备注** | | GPIO | 支持 | PA0,PA1... PK15 ---> PIN: 0,1...176 | | UART | 支持 | | -| SPI | 支持 | | +| SPI | 支持 | SPI2 | | I2C | 支持 | 软件 I2C | | ADC | 支持 | | | RTC | 支持 | 支持外部晶振和内部低速时钟 | diff --git a/bsp/stm32/stm32f767-atk-apollo/board/Kconfig b/bsp/stm32/stm32f767-atk-apollo/board/Kconfig index df86ffc383..cda9c0dfef 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/Kconfig +++ b/bsp/stm32/stm32f767-atk-apollo/board/Kconfig @@ -110,21 +110,6 @@ menu "On-chip Peripheral Drivers" default n select RT_USING_SPI if BSP_USING_SPI - config BSP_USING_SPI1 - bool "Enable SPI1 BUS" - default n - - config BSP_SPI1_TX_USING_DMA - bool "Enable SPI1 TX DMA" - depends on BSP_USING_SPI1 - default n - - config BSP_SPI1_RX_USING_DMA - bool "Enable SPI1 RX DMA" - depends on BSP_USING_SPI1 - select BSP_SPI1_TX_USING_DMA - default n - config BSP_USING_SPI2 bool "Enable SPI2 BUS" default n diff --git a/bsp/stm32/stm32f767-fire-challenger/.config b/bsp/stm32/stm32f767-fire-challenger-v1/.config similarity index 54% rename from bsp/stm32/stm32f767-fire-challenger/.config rename to bsp/stm32/stm32f767-fire-challenger-v1/.config index d9bdefcf56..10dded4cd7 100644 --- a/bsp/stm32/stm32f767-fire-challenger/.config +++ b/bsp/stm32/stm32f767-fire-challenger-v1/.config @@ -21,6 +21,12 @@ CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 CONFIG_IDLE_THREAD_STACK_SIZE=1024 # CONFIG_RT_USING_TIMER_SOFT is not set + +# +# kservice optimization +# +# CONFIG_RT_KSERVICE_USING_STDLIB is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set CONFIG_RT_DEBUG=y CONFIG_RT_DEBUG_COLOR=y # CONFIG_RT_DEBUG_INIT_CONFIG is not set @@ -53,6 +59,8 @@ CONFIG_RT_USING_MEMHEAP=y # CONFIG_RT_USING_SMALL_MEM is not set # CONFIG_RT_USING_SLAB is not set CONFIG_RT_USING_MEMHEAP_AS_HEAP=y +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set CONFIG_RT_USING_HEAP=y # @@ -64,7 +72,7 @@ CONFIG_RT_USING_DEVICE=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" -CONFIG_RT_VER_NUM=0x40002 +CONFIG_RT_VER_NUM=0x40003 CONFIG_ARCH_ARM=y CONFIG_RT_USING_CPU_FFS=y CONFIG_ARCH_ARM_CORTEX_M=y @@ -121,28 +129,29 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64 # CONFIG_RT_USING_HWTIMER is not set # CONFIG_RT_USING_CPUTIME is not set # CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC 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_SPI=y +# CONFIG_RT_USING_QSPI is not set +# CONFIG_RT_USING_SPI_MSD is not set +# CONFIG_RT_USING_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set # CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_SENSOR is not set - -# -# Using Hardware Crypto drivers -# +# CONFIG_RT_USING_TOUCH is not set # CONFIG_RT_USING_HWCRYPTO is not set - -# -# Using WiFi -# +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set # CONFIG_RT_USING_WIFI is not set # @@ -156,6 +165,7 @@ CONFIG_RT_USING_PIN=y # # CONFIG_RT_USING_LIBC is not set # CONFIG_RT_USING_PTHREADS is not set +CONFIG_RT_LIBC_USING_TIME=y # # Network @@ -176,11 +186,6 @@ CONFIG_RT_USING_PIN=y # # CONFIG_RT_USING_LWIP is not set -# -# Modbus master and slave stack -# -# CONFIG_RT_USING_MODBUS is not set - # # AT commands # @@ -206,14 +211,20 @@ CONFIG_RT_USING_PIN=y # # IoT - internet of things # +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set # CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT 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_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT 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_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set @@ -235,6 +246,8 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_COAP is not set # CONFIG_PKG_USING_NOPOLL is not set # CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set # CONFIG_PKG_USING_AT_DEVICE is not set # CONFIG_PKG_USING_ATSRV_SOCKET is not set # CONFIG_PKG_USING_WIZNET is not set @@ -246,12 +259,38 @@ CONFIG_RT_USING_PIN=y # 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 +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set # CONFIG_PKG_USING_NIMBLE is not set # CONFIG_PKG_USING_OTA_DOWNLOADER is not set # CONFIG_PKG_USING_IPMSG is not set # CONFIG_PKG_USING_LSSDP is not set # CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set # # security packages @@ -259,6 +298,8 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_MBEDTLS is not set # CONFIG_PKG_USING_libsodium is not set # CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set # # language packages @@ -273,6 +314,12 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_OPENMV is not set # CONFIG_PKG_USING_MUPDF is not set # CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set # # tools packages @@ -284,7 +331,35 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_RDB is not set # CONFIG_PKG_USING_QRCODE is not set # CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ULOG_FILE is not set +# CONFIG_PKG_USING_LOGMGR is not set # CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set # # system packages @@ -293,16 +368,47 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_PERSIMMON 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_FLASHDB 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 +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set # CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set # # peripheral libraries and drivers @@ -310,7 +416,8 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_SENSORS_DRIVERS is not set # CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_SHT2X is not set -# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AS7341 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 @@ -319,15 +426,69 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_SX12XX is not set # CONFIG_PKG_USING_SIGNAL_LED is not set # CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set # CONFIG_PKG_USING_WM_LIBRARIES is not set # CONFIG_PKG_USING_KENDRYTE_SDK is not set # CONFIG_PKG_USING_INFRARED is not set # CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set # CONFIG_PKG_USING_AT24CXX is not set # CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set # CONFIG_PKG_USING_AD7746 is not set # CONFIG_PKG_USING_PCA9685 is not set # CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set # # miscellaneous packages @@ -337,13 +498,17 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_FASTLZ is not set # CONFIG_PKG_USING_MINILZO is not set # CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set # CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON 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 # CONFIG_PKG_USING_KENDRYTE_DEMO is not set # CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set # # samples: kernel and components samples @@ -354,7 +519,25 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set # CONFIG_PKG_USING_HELLO is not set # CONFIG_PKG_USING_VI is not set -# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_UKAL is not set +# CONFIG_PKG_USING_CRCLIB is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_COWSAY is not set CONFIG_SOC_FAMILY_STM32=y CONFIG_SOC_SERIES_STM32F7=y @@ -384,7 +567,12 @@ CONFIG_BSP_USING_UART1=y # CONFIG_BSP_USING_UART2 is not set # CONFIG_BSP_USING_UART3 is not set # CONFIG_BSP_USING_ON_CHIP_FLASH is not set -# CONFIG_BSP_USING_SPI is not set +CONFIG_BSP_USING_SPI=y +CONFIG_BSP_USING_SPI1=y +CONFIG_BSP_SPI1_TX_USING_DMA=y +CONFIG_BSP_SPI1_RX_USING_DMA=y +# CONFIG_BSP_USING_SPI2 is not set +# CONFIG_BSP_USING_SPI5 is not set # CONFIG_BSP_USING_QSPI is not set # CONFIG_BSP_USING_ADC is not set # CONFIG_BSP_USING_I2C1 is not set @@ -393,6 +581,9 @@ CONFIG_BSP_USING_UART1=y # CONFIG_BSP_USING_SDIO is not set # CONFIG_BSP_USING_FMC is not set # CONFIG_BSP_USING_LTDC is not set +# CONFIG_BSP_USING_CRC is not set +# CONFIG_BSP_USING_RNG is not set +# CONFIG_BSP_USING_UDID is not set # # Board extended module Drivers diff --git a/bsp/stm32/stm32f767-fire-challenger/.gitignore b/bsp/stm32/stm32f767-fire-challenger-v1/.gitignore similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/.gitignore rename to bsp/stm32/stm32f767-fire-challenger-v1/.gitignore diff --git a/bsp/stm32/stm32f767-fire-challenger/Kconfig b/bsp/stm32/stm32f767-fire-challenger-v1/Kconfig similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/Kconfig rename to bsp/stm32/stm32f767-fire-challenger-v1/Kconfig diff --git a/bsp/stm32/stm32f767-fire-challenger/README.md b/bsp/stm32/stm32f767-fire-challenger-v1/README.md similarity index 93% rename from bsp/stm32/stm32f767-fire-challenger/README.md rename to bsp/stm32/stm32f767-fire-challenger-v1/README.md index 3945c9acea..12709f2ce9 100644 --- a/bsp/stm32/stm32f767-fire-challenger/README.md +++ b/bsp/stm32/stm32f767-fire-challenger-v1/README.md @@ -1,8 +1,8 @@ -# STM32F767 挑战者开发板 BSP 说明 +# STM32F767-V1 挑战者开发板 BSP 说明 ## 简介 -本文档为 野火stm32f767 开发板的 BSP (板级支持包) 说明。 +本文档为 野火stm32f767-v1 开发板的 BSP (板级支持包) 说明。 主要内容如下: @@ -14,7 +14,7 @@ ## 开发板介绍 -挑战者 STM32F767 是野火推出的一款基于 ARM Cortex-M7 内核的开发板,最高主频为 216Mhz,该开发板具有丰富的板载资源,可以充分发挥 STM32F767 的芯片性能。 +挑战者 STM32F767-V1 是野火推出的一款基于 ARM Cortex-M7 内核的开发板,最高主频为 216Mhz,该开发板具有丰富的板载资源,可以充分发挥 STM32F767 的芯片性能。 开发板外观如下图所示: @@ -53,7 +53,7 @@ | **片上外设** | **支持情况** | **备注** | | GPIO | 支持 | PA0, PA1... PK15 ---> PIN: 0, 1...176 | | UART | 支持 | UART1/x/x | -| SPI | 支持 | SPI1/x/x | +| SPI | 暂不支持 | | | I2C | 支持 | 软件 I2C | | ADC | 支持 | | | RTC | 支持 | 支持外部晶振和内部低速时钟 | diff --git a/bsp/stm32/stm32f767-fire-challenger/SConscript b/bsp/stm32/stm32f767-fire-challenger-v1/SConscript similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/SConscript rename to bsp/stm32/stm32f767-fire-challenger-v1/SConscript diff --git a/bsp/stm32/stm32f767-fire-challenger/SConstruct b/bsp/stm32/stm32f767-fire-challenger-v1/SConstruct similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/SConstruct rename to bsp/stm32/stm32f767-fire-challenger-v1/SConstruct diff --git a/bsp/stm32/stm32f767-fire-challenger/applications/SConscript b/bsp/stm32/stm32f767-fire-challenger-v1/applications/SConscript similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/applications/SConscript rename to bsp/stm32/stm32f767-fire-challenger-v1/applications/SConscript diff --git a/bsp/stm32/stm32f767-fire-challenger/applications/main.c b/bsp/stm32/stm32f767-fire-challenger-v1/applications/main.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/applications/main.c rename to bsp/stm32/stm32f767-fire-challenger-v1/applications/main.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/.mxproject similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/.mxproject rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/.mxproject diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/CubeMX_Config.ioc similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/CubeMX_Config.ioc rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/CubeMX_Config.ioc diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Inc/main.h b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Inc/main.h similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Inc/main.h rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Inc/main.h diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Inc/stm32f7xx_it.h b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Inc/stm32f7xx_it.h similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Inc/stm32f7xx_it.h rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Inc/stm32f7xx_it.h diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvoptx b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvoptx similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvoptx rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvoptx diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvprojx b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvprojx similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvprojx rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/MDK-ARM/CubeMX_Config.uvprojx diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/MDK-ARM/startup_stm32f767xx.s b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/MDK-ARM/startup_stm32f767xx.s similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/MDK-ARM/startup_stm32f767xx.s rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/MDK-ARM/startup_stm32f767xx.s diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Src/main.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Src/main.c rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Src/main.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Src/stm32f7xx_it.c b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Src/stm32f7xx_it.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Src/stm32f7xx_it.c rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Src/stm32f7xx_it.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Src/system_stm32f7xx.c b/bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Src/system_stm32f7xx.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/CubeMX_Config/Src/system_stm32f7xx.c rename to bsp/stm32/stm32f767-fire-challenger-v1/board/CubeMX_Config/Src/system_stm32f7xx.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/Kconfig b/bsp/stm32/stm32f767-fire-challenger-v1/board/Kconfig similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/Kconfig rename to bsp/stm32/stm32f767-fire-challenger-v1/board/Kconfig diff --git a/bsp/stm32/stm32f767-fire-challenger/board/SConscript b/bsp/stm32/stm32f767-fire-challenger-v1/board/SConscript similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/SConscript rename to bsp/stm32/stm32f767-fire-challenger-v1/board/SConscript diff --git a/bsp/stm32/stm32f767-fire-challenger/board/board.c b/bsp/stm32/stm32f767-fire-challenger-v1/board/board.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/board.c rename to bsp/stm32/stm32f767-fire-challenger-v1/board/board.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/board.h b/bsp/stm32/stm32f767-fire-challenger-v1/board/board.h similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/board.h rename to bsp/stm32/stm32f767-fire-challenger-v1/board/board.h diff --git a/bsp/stm32/stm32f767-fire-challenger/board/linker_scripts/link.icf b/bsp/stm32/stm32f767-fire-challenger-v1/board/linker_scripts/link.icf similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/linker_scripts/link.icf rename to bsp/stm32/stm32f767-fire-challenger-v1/board/linker_scripts/link.icf diff --git a/bsp/stm32/stm32f767-fire-challenger/board/linker_scripts/link.lds b/bsp/stm32/stm32f767-fire-challenger-v1/board/linker_scripts/link.lds similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/linker_scripts/link.lds rename to bsp/stm32/stm32f767-fire-challenger-v1/board/linker_scripts/link.lds diff --git a/bsp/stm32/stm32f767-fire-challenger/board/linker_scripts/link.sct b/bsp/stm32/stm32f767-fire-challenger-v1/board/linker_scripts/link.sct similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/linker_scripts/link.sct rename to bsp/stm32/stm32f767-fire-challenger-v1/board/linker_scripts/link.sct diff --git a/bsp/stm32/stm32f767-fire-challenger/board/ports/drv_qspi_flash.c b/bsp/stm32/stm32f767-fire-challenger-v1/board/ports/drv_qspi_flash.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/ports/drv_qspi_flash.c rename to bsp/stm32/stm32f767-fire-challenger-v1/board/ports/drv_qspi_flash.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/ports/fal_cfg.h b/bsp/stm32/stm32f767-fire-challenger-v1/board/ports/fal_cfg.h similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/ports/fal_cfg.h rename to bsp/stm32/stm32f767-fire-challenger-v1/board/ports/fal_cfg.h diff --git a/bsp/stm32/stm32f767-fire-challenger/board/ports/lcd_port.h b/bsp/stm32/stm32f767-fire-challenger-v1/board/ports/lcd_port.h similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/ports/lcd_port.h rename to bsp/stm32/stm32f767-fire-challenger-v1/board/ports/lcd_port.h diff --git a/bsp/stm32/stm32f767-fire-challenger/board/ports/phy_reset.c b/bsp/stm32/stm32f767-fire-challenger-v1/board/ports/phy_reset.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/ports/phy_reset.c rename to bsp/stm32/stm32f767-fire-challenger-v1/board/ports/phy_reset.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/ports/sdcard_port.c b/bsp/stm32/stm32f767-fire-challenger-v1/board/ports/sdcard_port.c similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/ports/sdcard_port.c rename to bsp/stm32/stm32f767-fire-challenger-v1/board/ports/sdcard_port.c diff --git a/bsp/stm32/stm32f767-fire-challenger/board/ports/sdram_port.h b/bsp/stm32/stm32f767-fire-challenger-v1/board/ports/sdram_port.h similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/board/ports/sdram_port.h rename to bsp/stm32/stm32f767-fire-challenger-v1/board/ports/sdram_port.h diff --git a/bsp/stm32/stm32f767-fire-challenger/figures/board.jpg b/bsp/stm32/stm32f767-fire-challenger-v1/figures/board.jpg similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/figures/board.jpg rename to bsp/stm32/stm32f767-fire-challenger-v1/figures/board.jpg diff --git a/bsp/stm32/stm32f767-fire-challenger/project.ewd b/bsp/stm32/stm32f767-fire-challenger-v1/project.ewd similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/project.ewd rename to bsp/stm32/stm32f767-fire-challenger-v1/project.ewd diff --git a/bsp/stm32/stm32f767-fire-challenger/project.ewp b/bsp/stm32/stm32f767-fire-challenger-v1/project.ewp similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/project.ewp rename to bsp/stm32/stm32f767-fire-challenger-v1/project.ewp diff --git a/bsp/stm32/stm32f767-fire-challenger/project.eww b/bsp/stm32/stm32f767-fire-challenger-v1/project.eww similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/project.eww rename to bsp/stm32/stm32f767-fire-challenger-v1/project.eww diff --git a/bsp/stm32/stm32f767-fire-challenger/project.uvopt b/bsp/stm32/stm32f767-fire-challenger-v1/project.uvopt similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/project.uvopt rename to bsp/stm32/stm32f767-fire-challenger-v1/project.uvopt diff --git a/bsp/stm32/stm32f767-fire-challenger-v1/project.uvoptx b/bsp/stm32/stm32f767-fire-challenger-v1/project.uvoptx new file mode 100644 index 0000000000..c133c6c7b2 --- /dev/null +++ b/bsp/stm32/stm32f767-fire-challenger-v1/project.uvoptx @@ -0,0 +1,1040 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\keil\List\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 4 + + + + + + + + + + + Segger\JL2CM3.dll + + + + 0 + JL2CM3 + -U59400616 -O14 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight JTAG-DP") -D00(5BA00477) -L00(4) -N01("Unknown JTAG device") -D01(06451041) -L01(5) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20020000 -FC1000 -FN1 -FF0STM32F7x_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F767IGTx$CMSIS\Flash\STM32F7x_1024.FLM) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN2 -FC1000 -FD20020000 -FF0STM32F7x_1024 -FF1STM32F7x_1024dual -FL0100000 -FL1100000 -FS08000000 -FS18000000 -FP0($$Device:STM32F767IGTx$CMSIS\Flash\STM32F7x_1024.FLM) -FP1($$Device:STM32F767IGTx$CMSIS\Flash\STM32F7x_1024dual.FLM) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Applications + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + applications\main.c + main.c + 0 + 0 + + + + + CPU + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\backtrace.c + backtrace.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\showmem.c + showmem.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\div0.c + div0.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m7\cpu_cache.c + cpu_cache.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m7\cpuport.c + cpuport.c + 0 + 0 + + + 2 + 7 + 2 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m7\context_rvds.S + context_rvds.S + 0 + 0 + + + + + DeviceDrivers + 0 + 0 + 0 + 0 + + 3 + 8 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\pin.c + pin.c + 0 + 0 + + + 3 + 9 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\serial\serial.c + serial.c + 0 + 0 + + + 3 + 10 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\spi\spi_core.c + spi_core.c + 0 + 0 + + + 3 + 11 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\spi\spi_dev.c + spi_dev.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\pipe.c + pipe.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\ringbuffer.c + ringbuffer.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\workqueue.c + workqueue.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\waitqueue.c + waitqueue.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\completion.c + completion.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\dataqueue.c + dataqueue.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\ringblk_buf.c + ringblk_buf.c + 0 + 0 + + + + + Drivers + 1 + 0 + 0 + 0 + + 4 + 19 + 1 + 0 + 0 + 0 + board\CubeMX_Config\Src\stm32f7xx_hal_msp.c + stm32f7xx_hal_msp.c + 0 + 0 + + + 4 + 20 + 2 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\CMSIS\Device\ST\STM32F7xx\Source\Templates\arm\startup_stm32f767xx.s + startup_stm32f767xx.s + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + board\board.c + board.c + 0 + 0 + + + 4 + 22 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_gpio.c + drv_gpio.c + 0 + 0 + + + 4 + 23 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_usart.c + drv_usart.c + 0 + 0 + + + 4 + 24 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_common.c + drv_common.c + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_spi.c + drv_spi.c + 0 + 0 + + + + + finsh + 0 + 0 + 0 + 0 + + 5 + 26 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\shell.c + shell.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\cmd.c + cmd.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\msh.c + msh.c + 0 + 0 + + + + + Kernel + 0 + 0 + 0 + 0 + + 6 + 29 + 1 + 0 + 0 + 0 + ..\..\..\src\timer.c + timer.c + 0 + 0 + + + 6 + 30 + 1 + 0 + 0 + 0 + ..\..\..\src\object.c + object.c + 0 + 0 + + + 6 + 31 + 1 + 0 + 0 + 0 + ..\..\..\src\clock.c + clock.c + 0 + 0 + + + 6 + 32 + 1 + 0 + 0 + 0 + ..\..\..\src\idle.c + idle.c + 0 + 0 + + + 6 + 33 + 1 + 0 + 0 + 0 + ..\..\..\src\mempool.c + mempool.c + 0 + 0 + + + 6 + 34 + 1 + 0 + 0 + 0 + ..\..\..\src\device.c + device.c + 0 + 0 + + + 6 + 35 + 1 + 0 + 0 + 0 + ..\..\..\src\ipc.c + ipc.c + 0 + 0 + + + 6 + 36 + 1 + 0 + 0 + 0 + ..\..\..\src\kservice.c + kservice.c + 0 + 0 + + + 6 + 37 + 1 + 0 + 0 + 0 + ..\..\..\src\irq.c + irq.c + 0 + 0 + + + 6 + 38 + 1 + 0 + 0 + 0 + ..\..\..\src\thread.c + thread.c + 0 + 0 + + + 6 + 39 + 1 + 0 + 0 + 0 + ..\..\..\src\scheduler.c + scheduler.c + 0 + 0 + + + 6 + 40 + 1 + 0 + 0 + 0 + ..\..\..\src\memheap.c + memheap.c + 0 + 0 + + + 6 + 41 + 1 + 0 + 0 + 0 + ..\..\..\src\components.c + components.c + 0 + 0 + + + + + libc + 0 + 0 + 0 + 0 + + 7 + 42 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\time.c + time.c + 0 + 0 + + + + + Libraries + 1 + 0 + 0 + 0 + + 8 + 43 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal.c + stm32f7xx_hal.c + 0 + 0 + + + 8 + 44 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart_ex.c + stm32f7xx_hal_uart_ex.c + 0 + 0 + + + 8 + 45 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_pwr.c + stm32f7xx_hal_pwr.c + 0 + 0 + + + 8 + 46 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_sram.c + stm32f7xx_hal_sram.c + 0 + 0 + + + 8 + 47 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rcc_ex.c + stm32f7xx_hal_rcc_ex.c + 0 + 0 + + + 8 + 48 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_crc.c + stm32f7xx_hal_crc.c + 0 + 0 + + + 8 + 49 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_spi_ex.c + stm32f7xx_hal_spi_ex.c + 0 + 0 + + + 8 + 50 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_usart.c + stm32f7xx_hal_usart.c + 0 + 0 + + + 8 + 51 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rcc.c + stm32f7xx_hal_rcc.c + 0 + 0 + + + 8 + 52 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cec.c + stm32f7xx_hal_cec.c + 0 + 0 + + + 8 + 53 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cryp.c + stm32f7xx_hal_cryp.c + 0 + 0 + + + 8 + 54 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_gpio.c + stm32f7xx_hal_gpio.c + 0 + 0 + + + 8 + 55 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_exti.c + stm32f7xx_hal_exti.c + 0 + 0 + + + 8 + 56 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cryp_ex.c + stm32f7xx_hal_cryp_ex.c + 0 + 0 + + + 8 + 57 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_dma_ex.c + stm32f7xx_hal_dma_ex.c + 0 + 0 + + + 8 + 58 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_qspi.c + stm32f7xx_hal_qspi.c + 0 + 0 + + + 8 + 59 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cortex.c + stm32f7xx_hal_cortex.c + 0 + 0 + + + 8 + 60 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_dma.c + stm32f7xx_hal_dma.c + 0 + 0 + + + 8 + 61 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_spi.c + stm32f7xx_hal_spi.c + 0 + 0 + + + 8 + 62 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\CMSIS\Device\ST\STM32F7xx\Source\Templates\system_stm32f7xx.c + system_stm32f7xx.c + 0 + 0 + + + 8 + 63 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart.c + stm32f7xx_hal_uart.c + 0 + 0 + + + 8 + 64 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_pwr_ex.c + stm32f7xx_hal_pwr_ex.c + 0 + 0 + + + 8 + 65 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rng.c + stm32f7xx_hal_rng.c + 0 + 0 + + + 8 + 66 + 1 + 0 + 0 + 0 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_crc_ex.c + stm32f7xx_hal_crc_ex.c + 0 + 0 + + + +
diff --git a/bsp/stm32/stm32f767-fire-challenger/project.uvprojx b/bsp/stm32/stm32f767-fire-challenger-v1/project.uvprojx similarity index 79% rename from bsp/stm32/stm32f767-fire-challenger/project.uvprojx rename to bsp/stm32/stm32f767-fire-challenger-v1/project.uvprojx index c77cfd7c72..d8d44b6237 100644 --- a/bsp/stm32/stm32f767-fire-challenger/project.uvprojx +++ b/bsp/stm32/stm32f767-fire-challenger-v1/project.uvprojx @@ -1,13 +1,16 @@ + 2.1 +
### uVision Project, (C) Keil Software
+ rt-thread 0x4 ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC + 5060750::V5.06 update 6 (build 750)::.\ARMCC 0 @@ -16,28 +19,28 @@ Keil.STM32F7xx_DFP.2.11.0 http://www.keil.com/pack IRAM(0x20020000,0x60000) IRAM2(0x20000000,0x20000) IROM(0x08000000,0x100000) IROM2(0x00200000,0x100000) CPUTYPE("Cortex-M7") FPU3(DFPU) CLOCK(12000000) ELITTLE - - + + UL2CM3(-S0 -C0 -P0 -FD20020000 -FC1000 -FN2 -FF0STM32F7x_1024 -FS08000000 -FL0100000 -FF1STM32F7x_1024dual -FS18000000 -FL1100000 -FP0($$Device:STM32F767IGTx$CMSIS\Flash\STM32F7x_1024.FLM) -FP1($$Device:STM32F767IGTx$CMSIS\Flash\STM32F7x_1024dual.FLM)) 0 $$Device:STM32F767IGTx$Drivers\CMSIS\Device\ST\STM32F7xx\Include\stm32f7xx.h - - - - - - - - - + + + + + + + + + $$Device:STM32F767IGTx$CMSIS\SVD\STM32F7x7_v1r2.svd 0 0 - - - - - + + + + + 0 0 @@ -59,8 +62,8 @@ 0 0 - - + + 0 0 0 @@ -69,8 +72,8 @@ 0 0 - - + + 0 0 0 @@ -80,14 +83,14 @@ 1 0 fromelf --bin !L --output rtthread.bin - + 0 0 0 0 0 - + 0 @@ -101,8 +104,8 @@ 0 0 3 - - + + 1 @@ -135,11 +138,11 @@ 1 BIN\UL2CM3.DLL - - - - - + + + + + 0 @@ -172,7 +175,7 @@ 0 0 "Cortex-M7" - + 0 0 0 @@ -182,6 +185,7 @@ 0 3 0 + 0 1 1 8 @@ -305,7 +309,7 @@ 0x20000 - + 1 @@ -332,10 +336,10 @@ 0 0 - - STM32F767xx, USE_HAL_DRIVER, __RTTHREAD__ - - applications;.;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m7;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;board;board\CubeMX_Config\Inc;board\ports;..\libraries\HAL_Drivers;..\libraries\HAL_Drivers\config;..\..\..\components\finsh;.;..\..\..\include;..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Inc;..\libraries\STM32F7xx_HAL\CMSIS\Device\ST\STM32F7xx\Include;..\libraries\STM32F7xx_HAL\CMSIS\Include + + STM32F767xx, USE_HAL_DRIVER, __RTTHREAD__, __CLK_TCK=RT_TICK_PER_SECOND + + applications;.;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m7;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\spi;..\..\..\components\drivers\include;..\..\..\components\drivers\include;board;board\CubeMX_Config\Inc;board\ports;..\libraries\HAL_Drivers;..\libraries\HAL_Drivers\config;..\..\..\components\finsh;.;..\..\..\include;..\..\..\components\libc\compilers\common;..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Inc;..\libraries\STM32F7xx_HAL\CMSIS\Device\ST\STM32F7xx\Include;..\libraries\STM32F7xx_HAL\CMSIS\Include @@ -348,12 +352,12 @@ 0 0 0 - 0 + 4 - - - - + + + + @@ -365,13 +369,13 @@ 0 0x08000000 0x20000000 - + .\board\linker_scripts\link.sct - - - - - + + + + + @@ -394,36 +398,26 @@ 1 ..\..\..\libcpu\arm\common\backtrace.c - - - - div0.c - 1 - ..\..\..\libcpu\arm\common\div0.c - - - showmem.c 1 ..\..\..\libcpu\arm\common\showmem.c - - + + div0.c + 1 + ..\..\..\libcpu\arm\common\div0.c + cpu_cache.c 1 ..\..\..\libcpu\arm\cortex-m7\cpu_cache.c - - cpuport.c 1 ..\..\..\libcpu\arm\cortex-m7\cpuport.c - - context_rvds.S 2 @@ -433,113 +427,171 @@ DeviceDrivers + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + pin.c 1 ..\..\..\components\drivers\misc\pin.c - - serial.c 1 ..\..\..\components\drivers\serial\serial.c - - - completion.c + spi_core.c 1 - ..\..\..\components\drivers\src\completion.c + ..\..\..\components\drivers\spi\spi_core.c - - - dataqueue.c + spi_dev.c 1 - ..\..\..\components\drivers\src\dataqueue.c + ..\..\..\components\drivers\spi\spi_dev.c - - pipe.c 1 ..\..\..\components\drivers\src\pipe.c - - - - ringblk_buf.c - 1 - ..\..\..\components\drivers\src\ringblk_buf.c - - - ringbuffer.c 1 ..\..\..\components\drivers\src\ringbuffer.c - - + + workqueue.c + 1 + ..\..\..\components\drivers\src\workqueue.c + waitqueue.c 1 ..\..\..\components\drivers\src\waitqueue.c - - - workqueue.c + completion.c 1 - ..\..\..\components\drivers\src\workqueue.c + ..\..\..\components\drivers\src\completion.c + + + dataqueue.c + 1 + ..\..\..\components\drivers\src\dataqueue.c + + + ringblk_buf.c + 1 + ..\..\..\components\drivers\src\ringblk_buf.c Drivers - - - board.c - 1 - board\board.c - - stm32f7xx_hal_msp.c 1 board\CubeMX_Config\Src\stm32f7xx_hal_msp.c - - startup_stm32f767xx.s 2 ..\libraries\STM32F7xx_HAL\CMSIS\Device\ST\STM32F7xx\Source\Templates\arm\startup_stm32f767xx.s - - + + board.c + 1 + board\board.c + drv_gpio.c 1 ..\libraries\HAL_Drivers\drv_gpio.c - - drv_usart.c 1 ..\libraries\HAL_Drivers\drv_usart.c - - drv_common.c 1 ..\libraries\HAL_Drivers\drv_common.c + + drv_spi.c + 1 + ..\libraries\HAL_Drivers\drv_spi.c + @@ -550,15 +602,11 @@ 1 ..\..\..\components\finsh\shell.c - - cmd.c 1 ..\..\..\components\finsh\cmd.c - - msh.c 1 @@ -569,260 +617,231 @@ Kernel + + timer.c + 1 + ..\..\..\src\timer.c + + + object.c + 1 + ..\..\..\src\object.c + clock.c 1 ..\..\..\src\clock.c - - + + idle.c + 1 + ..\..\..\src\idle.c + + + mempool.c + 1 + ..\..\..\src\mempool.c + + + device.c + 1 + ..\..\..\src\device.c + + + ipc.c + 1 + ..\..\..\src\ipc.c + + + kservice.c + 1 + ..\..\..\src\kservice.c + + + irq.c + 1 + ..\..\..\src\irq.c + + + thread.c + 1 + ..\..\..\src\thread.c + + + scheduler.c + 1 + ..\..\..\src\scheduler.c + + + memheap.c + 1 + ..\..\..\src\memheap.c + components.c 1 ..\..\..\src\components.c + + + libc - device.c + time.c 1 - ..\..\..\src\device.c - - - - - idle.c - 1 - ..\..\..\src\idle.c - - - - - ipc.c - 1 - ..\..\..\src\ipc.c - - - - - irq.c - 1 - ..\..\..\src\irq.c - - - - - kservice.c - 1 - ..\..\..\src\kservice.c - - - - - memheap.c - 1 - ..\..\..\src\memheap.c - - - - - mempool.c - 1 - ..\..\..\src\mempool.c - - - - - object.c - 1 - ..\..\..\src\object.c - - - - - scheduler.c - 1 - ..\..\..\src\scheduler.c - - - - - signal.c - 1 - ..\..\..\src\signal.c - - - - - thread.c - 1 - ..\..\..\src\thread.c - - - - - timer.c - 1 - ..\..\..\src\timer.c + ..\..\..\components\libc\compilers\common\time.c Libraries - - - system_stm32f7xx.c - 1 - ..\libraries\STM32F7xx_HAL\CMSIS\Device\ST\STM32F7xx\Source\Templates\system_stm32f7xx.c - - stm32f7xx_hal.c 1 ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal.c - - - stm32f7xx_hal_cec.c + stm32f7xx_hal_uart_ex.c 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cec.c + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart_ex.c - - - stm32f7xx_hal_cortex.c + stm32f7xx_hal_pwr.c 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cortex.c + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_pwr.c + + + stm32f7xx_hal_sram.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_sram.c + + + stm32f7xx_hal_rcc_ex.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rcc_ex.c - - stm32f7xx_hal_crc.c 1 ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_crc.c - - + + stm32f7xx_hal_spi_ex.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_spi_ex.c + + + stm32f7xx_hal_usart.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_usart.c + + + stm32f7xx_hal_rcc.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rcc.c + + + stm32f7xx_hal_cec.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cec.c + + + stm32f7xx_hal_cryp.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cryp.c + + + stm32f7xx_hal_gpio.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_gpio.c + + + stm32f7xx_hal_exti.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_exti.c + + + stm32f7xx_hal_cryp_ex.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cryp_ex.c + + + stm32f7xx_hal_dma_ex.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_dma_ex.c + + + stm32f7xx_hal_qspi.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_qspi.c + + + stm32f7xx_hal_cortex.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cortex.c + + + stm32f7xx_hal_dma.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_dma.c + + + stm32f7xx_hal_spi.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_spi.c + + + system_stm32f7xx.c + 1 + ..\libraries\STM32F7xx_HAL\CMSIS\Device\ST\STM32F7xx\Source\Templates\system_stm32f7xx.c + + + stm32f7xx_hal_uart.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart.c + + + stm32f7xx_hal_pwr_ex.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_pwr_ex.c + + + stm32f7xx_hal_rng.c + 1 + ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rng.c + stm32f7xx_hal_crc_ex.c 1 ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_crc_ex.c - - - stm32f7xx_hal_cryp.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cryp.c - - - - - stm32f7xx_hal_cryp_ex.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_cryp_ex.c - - - - - stm32f7xx_hal_exti.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_exti.c - - - - - stm32f7xx_hal_dma.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_dma.c - - - - - stm32f7xx_hal_dma_ex.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_dma_ex.c - - - - - stm32f7xx_hal_pwr.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_pwr.c - - - - - stm32f7xx_hal_pwr_ex.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_pwr_ex.c - - - - - stm32f7xx_hal_rcc.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rcc.c - - - - - stm32f7xx_hal_rcc_ex.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rcc_ex.c - - - - - stm32f7xx_hal_rng.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_rng.c - - - - - stm32f7xx_hal_sram.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_sram.c - - - - - stm32f7xx_hal_gpio.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_gpio.c - - - - - stm32f7xx_hal_uart.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart.c - - - - - stm32f7xx_hal_uart_ex.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart_ex.c - - - - - stm32f7xx_hal_usart.c - 1 - ..\libraries\STM32F7xx_HAL\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_usart.c - - + - - - + + + + + + + + <Project Info> + + + + + + 0 + 1 + + + +
diff --git a/bsp/stm32/stm32f767-fire-challenger/rtconfig.h b/bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.h similarity index 88% rename from bsp/stm32/stm32f767-fire-challenger/rtconfig.h rename to bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.h index 5cdccf1960..8efa97ef30 100644 --- a/bsp/stm32/stm32f767-fire-challenger/rtconfig.h +++ b/bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.h @@ -16,6 +16,9 @@ #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 #define IDLE_THREAD_STACK_SIZE 1024 + +/* kservice optimization */ + #define RT_DEBUG #define RT_DEBUG_COLOR @@ -40,7 +43,7 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLE_DEVICE_NAME "uart1" -#define RT_VER_NUM 0x40002 +#define RT_VER_NUM 0x40003 #define ARCH_ARM #define RT_USING_CPU_FFS #define ARCH_ARM_CORTEX_M @@ -82,18 +85,14 @@ #define RT_USING_SERIAL #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_PIN - -/* Using Hardware Crypto drivers */ - - -/* Using WiFi */ - +#define RT_USING_SPI /* Using USB */ /* POSIX layer and C standard library */ +#define RT_LIBC_USING_TIME /* Network */ @@ -106,9 +105,6 @@ /* light weight TCP/IP stack */ -/* Modbus master and slave stack */ - - /* AT commands */ @@ -149,14 +145,23 @@ /* system packages */ +/* Micrium: Micrium software products porting for RT-Thread */ + + /* peripheral libraries and drivers */ +/* AI packages */ + + /* miscellaneous packages */ /* samples: kernel and components samples */ + +/* entertainment: terminal games and other interesting software packages */ + #define SOC_FAMILY_STM32 #define SOC_SERIES_STM32F7 @@ -173,6 +178,10 @@ #define BSP_USING_GPIO #define BSP_USING_UART #define BSP_USING_UART1 +#define BSP_USING_SPI +#define BSP_USING_SPI1 +#define BSP_SPI1_TX_USING_DMA +#define BSP_SPI1_RX_USING_DMA /* Board extended module Drivers */ diff --git a/bsp/stm32/stm32f767-fire-challenger/rtconfig.py b/bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.py similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/rtconfig.py rename to bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.py diff --git a/bsp/stm32/stm32f767-fire-challenger/template.ewp b/bsp/stm32/stm32f767-fire-challenger-v1/template.ewp similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/template.ewp rename to bsp/stm32/stm32f767-fire-challenger-v1/template.ewp diff --git a/bsp/stm32/stm32f767-fire-challenger/template.eww b/bsp/stm32/stm32f767-fire-challenger-v1/template.eww similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/template.eww rename to bsp/stm32/stm32f767-fire-challenger-v1/template.eww diff --git a/bsp/stm32/stm32f767-fire-challenger/template.uvoptx b/bsp/stm32/stm32f767-fire-challenger-v1/template.uvoptx similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/template.uvoptx rename to bsp/stm32/stm32f767-fire-challenger-v1/template.uvoptx diff --git a/bsp/stm32/stm32f767-fire-challenger/template.uvprojx b/bsp/stm32/stm32f767-fire-challenger-v1/template.uvprojx similarity index 100% rename from bsp/stm32/stm32f767-fire-challenger/template.uvprojx rename to bsp/stm32/stm32f767-fire-challenger-v1/template.uvprojx From 2715dca27bb129865c5af5f0ac20b79f990be8af Mon Sep 17 00:00:00 2001 From: wanghaijing Date: Wed, 28 Apr 2021 14:37:31 +0800 Subject: [PATCH 13/13] [remove] configuration options for Kconfig --- .../stm32f767-fire-challenger-v1/.config | 7 +-- .../board/Kconfig | 51 ------------------- .../stm32f767-fire-challenger-v1/rtconfig.h | 4 -- 3 files changed, 1 insertion(+), 61 deletions(-) diff --git a/bsp/stm32/stm32f767-fire-challenger-v1/.config b/bsp/stm32/stm32f767-fire-challenger-v1/.config index 10dded4cd7..e6459865bc 100644 --- a/bsp/stm32/stm32f767-fire-challenger-v1/.config +++ b/bsp/stm32/stm32f767-fire-challenger-v1/.config @@ -567,12 +567,7 @@ CONFIG_BSP_USING_UART1=y # CONFIG_BSP_USING_UART2 is not set # CONFIG_BSP_USING_UART3 is not set # CONFIG_BSP_USING_ON_CHIP_FLASH is not set -CONFIG_BSP_USING_SPI=y -CONFIG_BSP_USING_SPI1=y -CONFIG_BSP_SPI1_TX_USING_DMA=y -CONFIG_BSP_SPI1_RX_USING_DMA=y -# CONFIG_BSP_USING_SPI2 is not set -# CONFIG_BSP_USING_SPI5 is not set +# CONFIG_BSP_USING_SPI is not set # CONFIG_BSP_USING_QSPI is not set # CONFIG_BSP_USING_ADC is not set # CONFIG_BSP_USING_I2C1 is not set diff --git a/bsp/stm32/stm32f767-fire-challenger-v1/board/Kconfig b/bsp/stm32/stm32f767-fire-challenger-v1/board/Kconfig index 6239d9e6f6..ecf85400fb 100644 --- a/bsp/stm32/stm32f767-fire-challenger-v1/board/Kconfig +++ b/bsp/stm32/stm32f767-fire-challenger-v1/board/Kconfig @@ -104,57 +104,6 @@ menu "On-chip Peripheral Drivers" config BSP_USING_ON_CHIP_FLASH bool "Enable on-chip FLASH" default n - -menuconfig BSP_USING_SPI - bool "Enable SPI BUS" - default n - select RT_USING_SPI - if BSP_USING_SPI - config BSP_USING_SPI1 - bool "Enable SPI1 BUS" - default n - - config BSP_SPI1_TX_USING_DMA - bool "Enable SPI1 TX DMA" - depends on BSP_USING_SPI1 - default n - - config BSP_SPI1_RX_USING_DMA - bool "Enable SPI1 RX DMA" - depends on BSP_USING_SPI1 - select BSP_SPI1_TX_USING_DMA - default n - - config BSP_USING_SPI2 - bool "Enable SPI2 BUS" - default n - - config BSP_SPI2_TX_USING_DMA - bool "Enable SPI2 TX DMA" - depends on BSP_USING_SPI2 - default n - - config BSP_SPI2_RX_USING_DMA - bool "Enable SPI2 RX DMA" - depends on BSP_USING_SPI2 - select BSP_SPI2_TX_USING_DMA - default n - - config BSP_USING_SPI5 - bool "Enable SPI5 BUS" - default n - - config BSP_SPI5_TX_USING_DMA - bool "Enable SPI5 TX DMA" - depends on BSP_USING_SPI5 - default n - - config BSP_SPI5_RX_USING_DMA - bool "Enable SPI5 RX DMA" - depends on BSP_USING_SPI5 - select BSP_SPI5_TX_USING_DMA - default n - endif config BSP_USING_QSPI bool "Enable QSPI BUS" diff --git a/bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.h b/bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.h index 8efa97ef30..2844ad29ff 100644 --- a/bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.h +++ b/bsp/stm32/stm32f767-fire-challenger-v1/rtconfig.h @@ -178,10 +178,6 @@ #define BSP_USING_GPIO #define BSP_USING_UART #define BSP_USING_UART1 -#define BSP_USING_SPI -#define BSP_USING_SPI1 -#define BSP_SPI1_TX_USING_DMA -#define BSP_SPI1_RX_USING_DMA /* Board extended module Drivers */