diff --git a/bin/ecos b/bin/ecos index c143392..4dedbe3 100755 --- a/bin/ecos +++ b/bin/ecos @@ -19,19 +19,24 @@ show_help() { echo "Usage: ecos [options]" echo "" echo "Available commands:" - echo " set_board Set the board configuration" - echo " init_project |list Initialize a project or list available projects" - echo " help Show this help message" + echo " set_board Set the board configuration" + echo " init_project |list Initialize a project or list available projects" + echo " help Show this help message" + echo "" + echo "Isolated:" + echo " Isolated project gathers all the resource so that you can compile your project without SDK" + echo " But the riscv-toolchain is still indispensable" echo "" echo "Board list:" - echo " c1 StarrySky C1 board" - echo " c2 StarrySky C2 board" - echo " l3 StarrySky L3 board" + echo " c1 StarrySky C1 board" + echo " c2 StarrySky C2 board" + echo " l3 StarrySky L3 board" echo "" echo "Examples:" - echo " ecos set_board c1 Set the board to StarrySky C1" - echo " ecos init_project hello Initialize a new project named 'hello'" - echo " ecos init_project list List all available project templates" + echo " ecos set_board c1 Set the board to StarrySky C1" + echo " ecos init_project hello Initialize a new project named 'hello'" + echo " ecos init_project list List all available project templates" + echo " ecos init_project hello -isolated Initialize a new isolated project named 'hello'" echo "" } diff --git a/bin/ecos-init_project b/bin/ecos-init_project index b757b6f..341d7c5 100755 --- a/bin/ecos-init_project +++ b/bin/ecos-init_project @@ -8,9 +8,10 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SDK_ROOT="$(dirname "$SCRIPT_DIR")" # Color output -log() { echo -e "\033[1;32m[ECOS]\033[0m $*"; } -warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; } -err() { echo -e "\033[1;31m[ERROR]\033[0m $*"; } +log() { echo -e "\033[1;32m[ECOS]\033[0m $*"; } +warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; } +err() { echo -e "\033[1;31m[ERROR]\033[0m $*"; } +tips() { echo -e "\033[1;94m[ECOS]\033[0m $*"; } echo_available_templates() { log "Available project templates:" @@ -98,21 +99,68 @@ init_project() { log "Project '$new_project_name' created successfully in './$new_project_name'" } +init_project_isolated() { + local isolated_project_name="${1:-HelloWorld}" + local target_board="${2:-c2}" + + # Check if project directory exists + if [[ -d "$isolated_project_name" ]]; then + err "Project directory already exists: $isolated_project_name" + exit 1 + fi + + # Copy project source must needed from sdk + log "Initializing project '$isolated_project_name' isolated..." + mkdir -p "$isolated_project_name/Library" + mkdir -p "$isolated_project_name/Startup" + mkdir -p "$isolated_project_name/User" + mkdir -p "$isolated_project_name/Hardware" + mkdir -p "$isolated_project_name/System" + find "$SDK_ROOT/components" -mindepth 2 -type f -regex '.*\.\(c\|h\|cpp\|hpp\)$' \ + -exec cp {} "$isolated_project_name/Library" \; + find "$SDK_ROOT/components" -maxdepth 1 -type f -regex '.*\.\(c\|h\|cpp\|hpp\)$' \ + -exec cp {} "$isolated_project_name/User" \; + # due to diversity of the device drivers, copy its whole structure + find "$SDK_ROOT/devices" -maxdepth 1 -mindepth 1 -type d -exec cp -r {} "$isolated_project_name/Hardware" \; + cp "$SDK_ROOT/docs/isolated_guide.md" "$isolated_project_name" + + + cd "$isolated_project_name" + # Initialize project config file + local board_to_set="${target_board:-c2}" + echo "BOARD=${board_to_set}" > ".ecos-project" + log "Initialized project: $isolated_project_name" + log "Config file: .ecos-project" + + # Set default board + ecos set_board_isolated "${board_to_set}" + + # Create configs directory and copy scripts + mkdir -p configs + cp -r "$SDK_ROOT/tools/scripts/" "." + log "Project '$isolated_project_name' created successfully in './$isolated_project_name'" + tips "Please set menuconfig before project isolation" +} + # Main entry point for the subcommand if [[ $# -eq 0 ]]; then err "Missing project name or 'list' argument" echo "" - echo "Usage: ecos init_project [-name new_project_name] [-target target_board]" + echo "Usage: ecos init_project [-isolated] [-name new_project_name] [-target target_board]" echo " ecos init_project list" echo "Example: ecos init_project hello" echo " ecos init_project hello -name my_new_hello" echo " ecos init_project hello -name my_new_hello -target l3" + echo " ecos init_project my_project -isolated" + echo " ecos init_project my_project -isolated -target c2" + echo " ecos init_project my_project -isolated -name my_new_project -target c2" exit 1 fi template_name="" new_project_name="" target_board="" +isIsolated=false while [[ $# -gt 0 ]]; do case "$1" in @@ -124,6 +172,10 @@ while [[ $# -gt 0 ]]; do target_board="$2" shift 2 ;; + -isolated) + isIsolated=true + shift 1 + ;; *) if [[ -z "$template_name" ]]; then template_name="$1" @@ -141,4 +193,8 @@ if [[ -z "$template_name" ]]; then exit 1 fi -init_project "$template_name" "${new_project_name:-$template_name}" "${target_board:-c1}" +if [[ "${isIsolated:-false}" == false ]]; then + init_project "$template_name" "${new_project_name:-$template_name}" "${target_board:-c2}" +else + init_project_isolated "${new_project_name:-$template_name}" "${target_board:-c2}" +fi diff --git a/bin/ecos-set_board_isolated b/bin/ecos-set_board_isolated new file mode 100755 index 0000000..0091751 --- /dev/null +++ b/bin/ecos-set_board_isolated @@ -0,0 +1,241 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ECOS `set_board` subcommand +# Sets the board configuration for the project + +# WARN: only C2 was checked!!! +# TODO: fix C1 start_file / L3 loader dir + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SDK_ROOT="$(dirname "$SCRIPT_DIR")" + +# Color output +log() { echo -e "\033[1;32m[ECOS]\033[0m $*"; } +warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; } +err() { echo -e "\033[1;31m[ERROR]\033[0m $*"; } + +board_name="" +project_type="" + +# Check if inside a project directory +check_project_dir() { + if [[ ! -f "Makefile" ]] && [[ ! -f ".ecos-project" ]]; then + err "Not an ECOS project directory." + err "Run this command in a directory containing a Makefile or .ecos-project file." + exit 1 + fi +} + +get_config() { + source .ecos-project + + board_name="${BOARD}" + project_type="${TYPE:-}" + + echo "Project type: $project_type" + echo "Board name: $board_name" +} + +rewrite_config() { + echo "BOARD=$target_board_name" > ".ecos-project" + echo "TYPE=$project_type" >> ".ecos-project" +} +# Set board configuration +set_board() { + local target_board_name="$1" + + check_project_dir + rewrite_config + get_config + + if [[ "$project_type" == "asm" ]]; then + rm -f Makefile + log "Removed Makefile for assembly project." + log "Board configuration set to: $target_board_name" + cp "$SDK_ROOT/board/${target_board_name}/Makefile_asm" "./Makefile" + exit 0 + fi + + case "$target_board_name" in + "c1") + local board_file="board.h" + local make_file="Makefile_isolated" + local lds_file="sections.lds" + # local start_file="start.s" # C1 might not have start.s in board dir yet, checking... + + local board_source_path="$SDK_ROOT/board/StarrySkyC1/$board_file" + local make_source_path="$SDK_ROOT/board/StarrySkyC1/$make_file" + local lds_source_path="$SDK_ROOT/board/StarrySkyC1/$lds_file" + + local board_target_path="./Library/board.h" + local make_target_path="./Makefile" + local lds_target_path="./Startup/sections.lds" + + if [[ ! -f "$board_source_path" ]]; then + err "Board config file not found: $board_source_path" + exit 1 + fi + + # Copy board config file + cp "$board_source_path" "$board_target_path" + log "Set board configuration to: starrysky_c1" + log "Config file: $board_target_path" + + # Copy Makefile + cp "$make_source_path" "$make_target_path" + log "Set Makefile: $make_target_path" + + # Copy Linker Script + if [[ -f "$lds_source_path" ]]; then + cp "$lds_source_path" "$lds_target_path" + log "Set Linker Script: $lds_target_path" + fi + + # Copy start.s if exists (C1 support) + if [[ -f "$SDK_ROOT/board/StarrySkyC1/start.s" ]]; then + cp "$SDK_ROOT/board/StarrySkyC1/start.s" "./Startup/start.s" + log "Set startup code: ./Startup/start.s" + fi + + # Update project config file if it exists + if [[ -f ".ecos-project" ]]; then + if grep -q "BOARD=" ".ecos-project"; then + sed -i "s/BOARD=.*/BOARD=$target_board_name/" ".ecos-project" + else + echo "BOARD=$target_board_name" >> ".ecos-project" + fi + log "Updated project configuration file." + fi + ;; + "c2") + local board_file="board.h" + local make_file="Makefile_isolated" + local lds_file="sections.lds" + local start_file="start.s" + + local board_source_path="$SDK_ROOT/board/StarrySkyC2/$board_file" + local make_source_path="$SDK_ROOT/board/StarrySkyC2/$make_file" + local lds_source_path="$SDK_ROOT/board/StarrySkyC2/$lds_file" + local start_source_path="$SDK_ROOT/board/StarrySkyC2/$start_file" + + local board_target_path="./Library/board.h" + local make_target_path="./Makefile" + local lds_target_path="./Startup/sections.lds" + local start_target_path="./Startup/start.s" + + if [[ ! -f "$board_source_path" ]]; then + err "Board config file not found: $board_source_path" + exit 1 + fi + + # Copy board config file + cp "$board_source_path" "$board_target_path" + log "Set board configuration to: starrysky_c2" + log "Config file: $board_target_path" + + # Copy Makefile + cp "$make_source_path" "$make_target_path" + log "Set Makefile: $make_target_path" + + # Copy Linker Script + if [[ -f "$lds_source_path" ]]; then + cp "$lds_source_path" "$lds_target_path" + log "Set Linker Script: $lds_target_path" + else + warn "Linker script not found for C2: $lds_source_path" + fi + + # Copy startup code + if [[ -f "$start_source_path" ]]; then + cp "$start_source_path" "$start_target_path" + log "Set startup code: $start_target_path" + else + warn "Startup code not found for C2: $start_source_path" + fi + + # Update project config file if it exists + if [[ -f ".ecos-project" ]]; then + if grep -q "BOARD=" ".ecos-project"; then + sed -i "s/BOARD=.*/BOARD=$target_board_name/" ".ecos-project" + else + echo "BOARD=$target_board_name" >> ".ecos-project" + fi + log "Updated project configuration file." + fi + ;; + "l3") + local board_file="board.h" + local make_file="Makefile_isolated" + local lds_file="sections.lds" + + local board_source_path="$SDK_ROOT/board/StarrySkyL3/$board_file" + local make_source_path="$SDK_ROOT/board/StarrySkyL3/$make_file" + local lds_source_path="$SDK_ROOT/board/StarrySkyL3/$lds_file" + + local board_target_path="./Library/board.h" + local make_target_path="./Makefile" + local lds_target_path="./Startup/sections.lds" + local start_target_path="./Startup/start.s" + + if [[ ! -f "$board_source_path" ]]; then + err "Board config file not found: $board_source_path" + exit 1 + fi + + # Copy board config file + cp "$board_source_path" "$board_target_path" + log "Set board configuration to: starrysky_l3" + log "Config file: $board_target_path" + + # Copy Makefile + cp "$make_source_path" "$make_target_path" + log "Set Makefile: $make_target_path" + + # Copy Linker Script + if [[ -f "$lds_source_path" ]]; then + cp "$lds_source_path" "$lds_target_path" + log "Set Linker Script: $lds_target_path" + fi + + # Copy start.s if exists + if [[ -f "$SDK_ROOT/board/StarrySkyL3/start.s" ]]; then + cp "$SDK_ROOT/board/StarrySkyL3/start.s" "./start.s" + log "Set startup code: ./start.s" + fi + + # Copy bootloader + local bootloader_source_path="$SDK_ROOT/board/StarrySkyL3/loader" + local bootloader_target_path="./Startup/loader" + cp -r "$bootloader_source_path" "$bootloader_target_path" + log "Set bootloader: $bootloader_target_path" + + # Update project config file if it exists + if [[ -f ".ecos-project" ]]; then + if grep -q "BOARD=" ".ecos-project"; then + sed -i "s/BOARD=.*/BOARD=$target_board_name/" ".ecos-project" + else + echo "BOARD=$target_board_name" >> ".ecos-project" + fi + log "Updated project configuration file." + fi + ;; + *) + err "Unsupported board: $board_name" + echo "" + echo "Supported boards:" + echo " c1 StarrySky C1 board" + echo " c2 StarrySky C2 board" + echo " l3 StarrySky L3 board" + exit 1 + ;; + esac +} + +# Main entry point for the subcommand +if [[ $# -eq 0 ]]; then + err "Missing board name argument for isolated project." + exit 1 +fi + +set_board "$1" \ No newline at end of file diff --git a/board/StarrySkyC2/Makefile_isolated b/board/StarrySkyC2/Makefile_isolated new file mode 100644 index 0000000..2bdfe4a --- /dev/null +++ b/board/StarrySkyC2/Makefile_isolated @@ -0,0 +1,105 @@ +# retroSoC 固件构建脚本 +# 用于编译基于RISC-V架构的嵌入式固件 + +# RISC-V 交叉编译工具链前缀 +CROSS=riscv64-unknown-elf- +BUILD_DIR := build +PROJECT_PATH := $(shell pwd) +# 包含配置文件 +-include configs/.config + +# 编译器标志配置 +# -mabi=ilp32: 使用ILP32 ABI +# -march=rv32im: RV32I基础指令集 + M乘除法扩展 +# -ffreestanding: 独立环境编译 +# -nostdlib: 不链接标准库 +CFLAGS := -mabi=ilp32 \ + -march=rv32im \ + -Wl,-Bstatic,-T,$(BUILD_DIR)/retrosoc_sections.lds,--strip-debug \ + -Wl,-Map=$(BUILD_DIR)/$(FIRMWARE_NAME).map,--cref \ + -ffreestanding \ + -nostdlib + +# 根据配置文件设置链接选项 +ifdef CONFIG_LINK_RAM_REGION_SRAM +LDFLAGS += -DCONFIG_LINK_RAM_REGION_SRAM +CFLAGS += -DCONFIG_LINK_RAM_REGION_SRAM +endif + +ifdef CONFIG_LINK_RAM_REGION_PSRAM +LDFLAGS += -DCONFIG_LINK_RAM_REGION_PSRAM +CFLAGS += -DCONFIG_LINK_RAM_REGION_PSRAM +endif + +# 根据配置文件添加编译优化选项 +ifdef CONFIG_BUILD_OPT_FLAGS +CFLAGS += $(subst ",,$(CONFIG_BUILD_OPT_FLAGS)) +endif + +# 根据配置文件添加调试选项 +ifdef CONFIG_BUILD_DEBUG +CFLAGS += -g -DDEBUG +endif + +# 根据配置文件添加详细输出选项 +ifdef CONFIG_BUILD_VERBOSE +VERBOSE := 1 +endif + +# 固件名称 - 从配置文件读取,如果未定义则使用默认值 +ifdef CONFIG_FIRMWARE_NAME +FIRMWARE_NAME := $(subst ",,$(CONFIG_FIRMWARE_NAME)) +else +FIRMWARE_NAME := main +endif + +# find包含目录 +INCLUDE_DIRS := Library Startup User Hardware System + +# 源文件列表 +SRC_PATH := $(shell find $(INCLUDE_DIRS) -type f -name "*.s") +SRC_PATH += $(shell find $(INCLUDE_DIRS) -type f -name "*.c") + +CFLAGS += -I./configs +CFLAGS += $(addprefix -I,$(shell find $(INCLUDE_DIRS) -type d)) + +# 链接脚本路径 +LDS_PATH := $(shell find $(INCLUDE_DIRS) -type f -name "sections.lds") + +# 包含内存报告工具 +-include ./scripts/mem_report.mk + +# 主要构建目标:生成固件的所有格式文件 +$(FIRMWARE_NAME): + @echo "Building $(FIRMWARE_NAME)..." + @mkdir -p $(BUILD_DIR) + @$(CROSS)cpp -P -o $(BUILD_DIR)/retrosoc_sections.lds $(LDS_PATH) + @$(CROSS)gcc $(CFLAGS) -I./ -o $(BUILD_DIR)/$@ $(SRC_PATH) + @echo "Linking $(FIRMWARE_NAME)..." + @$(CROSS)objcopy -O verilog $(BUILD_DIR)/$@ $(BUILD_DIR)/$(FIRMWARE_NAME).hex + @echo "Post-processing $(FIRMWARE_NAME).hex..." + @sed -i 's/@30000000/@00000000/g' $(BUILD_DIR)/$(FIRMWARE_NAME).hex + @echo "Generating $(FIRMWARE_NAME).bin..." + @$(CROSS)objcopy -O binary $(BUILD_DIR)/$@ $(BUILD_DIR)/$(FIRMWARE_NAME).bin + @echo "Generating $(FIRMWARE_NAME).txt..." + @$(CROSS)objdump -d $(BUILD_DIR)/$@ > $(BUILD_DIR)/$(FIRMWARE_NAME).txt + $(call show_mem_usage, $(BUILD_DIR)/$@) + @echo "Done." + +# 清理构建产物 +clean: + rm -rf $(BUILD_DIR) + +clean_config: + rm -rf configs/generated configs/config configs/.config configs/.config.old + +clean_all: + rm -rf $(BUILD_DIR) + rm -rf configs/generated configs/config configs/.config configs/.config.old + rm -rf $(PROJECT_PATH)/tools/fixdep/build + rm -rf $(PROJECT_PATH)/tools/kconfig/build + + +-include scripts/config.mk +# 声明伪目标 +.PHONY: $(FIRMWARE_NAME).elf clean diff --git a/board/StarrySkyC2/start.S b/board/StarrySkyC2/start.s similarity index 100% rename from board/StarrySkyC2/start.S rename to board/StarrySkyC2/start.s diff --git a/components/main.c b/components/main.c new file mode 100644 index 0000000..d79b2db --- /dev/null +++ b/components/main.c @@ -0,0 +1,8 @@ +#include "main.h" + +void main(void){ + + sys_uart_init(); + printf("Hello, World!\n"); + +} \ No newline at end of file diff --git a/components/main.h b/components/main.h new file mode 100644 index 0000000..46f8de5 --- /dev/null +++ b/components/main.h @@ -0,0 +1,21 @@ +// System Headers +#include "string.h" +#include "stdio.h" +#include "libgcc.h" + +// System Configuration +#include "generated/autoconf.h" + +// Components headers +// #include "timer.h" +// #include "qspi.h" +// #include "gpio.h" +// #include "pwm.h" +// #include "hp_uart.h" +// #include "i2c.h" + +// Device headers +// #include "st7735.h" +// #include "sgp30.h" + +#define PSRAM_SCKL_FREQ_MHZ (CONFIG_CPU_FREQ_MHZ / CONFIG_PSRAM_NUM) \ No newline at end of file diff --git a/docs/isolated_guide.md b/docs/isolated_guide.md new file mode 100644 index 0000000..0ba4639 --- /dev/null +++ b/docs/isolated_guide.md @@ -0,0 +1,22 @@ +# 分离式项目 + +## 项目概述 +生成分离式项目将会按照板卡类型,收集 SDK 中所有可用资源,使得无需 SDK 即可编译项目。 +但 riscv-toolchain 仍然是不可缺少的组件。 + +## 项目结构 +``` +ECOS_Isolated_Project/ +├── README.md # 项目说明文档 +├── Makefile # 构建配置 +├── script/ # 构建工具 +├── configs/ # 构建的编译清单 +├── build/ # 生成的SoC固件 +├── Library/ # 工作区: 包含与Core相关的文件、SDK提供的标准库文件 +├── Startup/ # 工作区: 包含与系统链接与链接相关的文件 +├── User/ # 工作区: 包含自定义的程序入口 +├── System/ # 工作区: 包含自定义的片上资源驱动 +└── Hardware/ # 工作区: 包含自定义的片外资源驱动 +``` + +工作区中,除了Library、Startup、User是正常运行所必须的文件夹以外,其他文件夹可以任意自定义 \ No newline at end of file