#!/bin/bash # FreeRTOS环境设置脚本 # 用于设置CodeDetect项目中的FreeRTOS验证环境 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 配置变量 FREERTOS_VERSION="10.4.6" FREERTOS_SOURCE_URL="https://github.com/FreeRTOS/FreeRTOS-Kernel/archive/refs/tags/V${FREERTOS_VERSION}.tar.gz" INSTALL_DIR="/opt/freertos" CODEDETECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" FREERTOS_CONFIG_DIR="${CODEDETECT_DIR}/config/freertos" # 日志函数 log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查依赖 check_dependencies() { log_info "检查系统依赖..." local deps=("wget" "tar" "gcc" "make" "cmake" "python3" "pip3") local missing_deps=() for dep in "${deps[@]}"; do if ! command -v "$dep" &> /dev/null; then missing_deps+=("$dep") fi done if [ ${#missing_deps[@]} -gt 0 ]; then log_error "缺少以下依赖: ${missing_deps[*]}" log_info "请安装缺少的依赖:" echo " Ubuntu/Debian: sudo apt-get install ${missing_deps[*]}" echo " CentOS/RHEL: sudo yum install ${missing_deps[*]}" exit 1 fi log_success "所有依赖已安装" } # 创建目录结构 create_directory_structure() { log_info "创建目录结构..." # 创建主安装目录 sudo mkdir -p "$INSTALL_DIR" sudo chown "$USER:$USER" "$INSTALL_DIR" # 创建FreeRTOS子目录 mkdir -p "$INSTALL_DIR/src" mkdir -p "$INSTALL_DIR/include" mkdir -p "$INSTALL_DIR/config" mkdir -p "$INSTALL_DIR/examples" # 创建CodeDetect配置目录 mkdir -p "$FREERTOS_CONFIG_DIR" log_success "目录结构创建完成" } # 下载FreeRTOS源码 download_freertos() { log_info "下载FreeRTOS源码 (版本: $FREERTOS_VERSION)..." cd "$INSTALL_DIR/src" if [ ! -f "FreeRTOS-Kernel-${FREERTOS_VERSION}.tar.gz" ]; then wget "$FREERTOS_SOURCE_URL" -O "FreeRTOS-Kernel-${FREERTOS_VERSION}.tar.gz" fi # 解压源码 if [ ! -d "FreeRTOS-Kernel-${FREERTOS_VERSION}" ]; then tar -xzf "FreeRTOS-Kernel-${FREERTOS_VERSION}.tar.gz" fi # 创建符号链接 ln -sf "FreeRTOS-Kernel-${FREERTOS_VERSION}" "freertos-kernel" log_success "FreeRTOS源码下载完成" } # 安装FreeRTOS头文件 install_headers() { log_info "安装FreeRTOS头文件..." local kernel_dir="$INSTALL_DIR/src/freertos-kernel" # 复制核心头文件 cp -r "$kernel_dir/include" "$INSTALL_DIR/" # 复制便携层头文件(选择x86_64作为示例) cp -r "$kernel_dir/portable/GCC/Linux" "$INSTALL_DIR/portable/" # 创建include目录的符号链接 ln -sf "$INSTALL_DIR/include" "$INSTALL_DIR/freertos" log_success "FreeRTOS头文件安装完成" } # 创建配置文件 create_config_files() { log_info "创建FreeRTOS配置文件..." # 创建基础FreeRTOSConfig.h cat > "$FREERTOS_CONFIG_DIR/FreeRTOSConfig.h" << 'EOF' #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /* 包含标准头文件 */ #include #include /* 基础配置 */ #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_TICKLESS_IDLE 0 #define configCPU_CLOCK_HZ ( ( uint32_t ) 16000000 ) #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( ( uint16_t ) 128 ) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_TASK_NOTIFICATIONS 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 10 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 1 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 0 #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 /* 内存分配相关 */ #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configTOTAL_HEAP_SIZE ( ( size_t ) 40960 ) #define configAPPLICATION_ALLOCATED_HEAP 0 /* 钩子函数相关 */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_MALLOC_FAILED_HOOK 1 #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 /* 运行时统计相关 */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 0 #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* 协程相关 */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* 软件定时器相关 */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) /* 中断配置 */ #define configKERNEL_INTERRUPT_PRIORITY 0 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 0 #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 0 /* 定义和断言 */ #define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );} /* 可选函数定义 */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_xQueueGetMutexHolder 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_eTaskGetState 1 #define INCLUDE_xTaskAbortDelay 1 #define INCLUDE_xTaskGetHandle 1 /* 映射函数到Linux环境 */ #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() #define portGET_RUN_TIME_COUNTER_VALUE() 0 /* 针对CBMC验证的特定配置 */ #ifdef CBMC_VERIFICATION #define configASSERT( x ) if ((x) == 0) { __CPROVER_assert(0, "FreeRTOS config assertion failed"); } #endif #endif /* FREERTOS_CONFIG_H */ EOF # 创建测试专用配置 cat > "$FREERTOS_CONFIG_DIR/FreeRTOSConfig_Test.h" << 'EOF' #ifndef FREERTOS_CONFIG_TEST_H #define FREERTOS_CONFIG_TEST_H #include "FreeRTOSConfig.h" /* 测试环境特定配置 */ #define configTOTAL_HEAP_SIZE ( ( size_t ) 8192 ) #define configMINIMAL_STACK_SIZE ( ( uint16_t ) 64 ) #define configMAX_PRIORITIES ( 3 ) #define configTICK_RATE_HZ ( ( TickType_t ) 100 ) /* CBMC验证优化 */ #ifdef CBMC_VERIFICATION #define configMAX_TASK_NAME_LEN ( 8 ) #define configQUEUE_REGISTRY_SIZE 3 #define configTIMER_QUEUE_LENGTH 3 #endif #endif /* FREERTOS_CONFIG_TEST_H */ EOF # 创建CodeDetect集成配置 cat > "$FREERTOS_CONFIG_DIR/codedetect_freertos.yaml" << EOF # FreeRTOS配置文件 - CodeDetect集成 freertos: version: "$FREERTOS_VERSION" install_path: "$INSTALL_DIR" include_paths: - "$INSTALL_DIR/include" - "$INSTALL_DIR/portable/GCC/Linux" config_files: - "$FREERTOS_CONFIG_DIR/FreeRTOSConfig.h" - "$FREERTOS_CONFIG_DIR/FreeRTOSConfig_Test.h" # 验证参数 verification: max_tasks: 10 max_queues: 5 max_semaphores: 5 max_timers: 3 heap_size: 8192 stack_size: 1024 # CBMC配置 cbmc: include_paths: - "$INSTALL_DIR/include" - "$INSTALL_DIR/portable/GCC/Linux" defines: - "CBMC_VERIFICATION" unwind_set: task: 5 queue: 3 timer: 2 options: - "--bounds-check" - "--pointer-check" - "--memory-leak-check" - "--div-by-zero-check" - "--float-div-by-zero-check" # 编译配置 compilation: c_flags: "-std=c99 -Wall -Wextra -I$INSTALL_DIR/include" ld_flags: "-lpthread -lrt" # 示例配置 examples: task_verification: source: "examples/freertos/task_verification_example.c" config: "FreeRTOSConfig.h" queue_verification: source: "examples/freertos/queue_verification_example.c" config: "FreeRTOSConfig.h" EOF log_success "配置文件创建完成" } # 创建示例构建脚本 create_build_scripts() { log_info "创建构建脚本..." # 创建主构建脚本 cat > "$INSTALL_DIR/build_freertos.sh" << 'EOF' #!/bin/bash # FreeRTOS构建脚本 set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" FREERTOS_DIR="$SCRIPT_DIR/src/freertos-kernel" PORTABLE_DIR="$SCRIPT_DIR/portable/GCC/Linux" # 编译参数 CC="gcc" CFLAGS="-std=c99 -Wall -Wextra -I$SCRIPT_DIR/include" LDFLAGS="-lpthread -lrt" # 创建构建目录 BUILD_DIR="$SCRIPT_DIR/build" mkdir -p "$BUILD_DIR" # 编译FreeRTOS核心 echo "编译FreeRTOS核心..." $CC $CFLAGS -c \ "$FREERTOS_DIR/tasks.c" \ "$FREERTOS_DIR/queue.c" \ "$FREERTOS_DIR/timers.c" \ "$FREERTOS_DIR/event_groups.c" \ "$FREERTOS_DIR/list.c" \ "$PORTABLE_DIR/port.c" \ "$PORTABLE_DIR/../memory.c" \ -o "$BUILD_DIR/freertos.o" # 创建静态库 echo "创建静态库..." ar rcs "$BUILD_DIR/libfreertos.a" "$BUILD_DIR/freertos.o" echo "FreeRTOS构建完成: $BUILD_DIR/libfreertos.a" EOF # 创建测试构建脚本 cat > "$INSTALL_DIR/test_example.sh" << 'EOF' #!/bin/bash # FreeRTOS示例测试脚本 set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BUILD_DIR="$SCRIPT_DIR/build" CODEDETECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" # 编译测试示例 echo "编译FreeRTOS测试示例..." gcc -std=c99 -Wall -Wextra \ -I"$SCRIPT_DIR/include" \ -L"$BUILD_DIR" \ "$CODEDETECT_DIR/examples/freertos/task_verification_example.c" \ -lfreertos -lpthread -lrt \ -o "$BUILD_DIR/task_test" gcc -std=c99 -Wall -Wextra \ -I"$SCRIPT_DIR/include" \ -L"$BUILD_DIR" \ "$CODEDETECT_DIR/examples/freertos/queue_verification_example.c" \ -lfreertos -lpthread -lrt \ -o "$BUILD_DIR/queue_test" echo "示例编译完成:" echo " 任务测试: $BUILD_DIR/task_test" echo " 队列测试: $BUILD_DIR/queue_test" EOF # 使脚本可执行 chmod +x "$INSTALL_DIR/build_freertos.sh" chmod +x "$INSTALL_DIR/test_example.sh" log_success "构建脚本创建完成" } # 创建验证测试 create_verification_tests() { log_info "创建验证测试..." local test_dir="$INSTALL_DIR/tests" mkdir -p "$test_dir" # 创建基础验证测试 cat > "$test_dir/test_freertos_basic.c" << 'EOF' #include "FreeRTOS.h" #include "task.h" #include #include #include void vTestTask(void *pvParameters) { int counter = 0; for (int i = 0; i < 10; i++) { counter++; vTaskDelay(pdMS_TO_TICKS(100)); } printf("Test task completed: %d\n", counter); vTaskDelete(NULL); } int main() { printf("Starting FreeRTOS basic test...\n"); xTaskCreate(vTestTask, "Test", 128, NULL, 1, NULL); vTaskStartScheduler(); return 0; } EOF # 创建CBMC验证规范 cat > "$test_dir/cbmc_task_test.c" << 'EOF' #include "FreeRTOS.h" #include "task.h" #include void test_task_creation() { TaskHandle_t xTaskHandle = NULL; // 测试任务创建 BaseType_t xResult = xTaskCreate( (TaskFunction_t)0, // 简化的任务函数 "TestTask", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandle ); __CPROVER_assert(xResult == pdPASS, "Task creation should succeed"); __CPROVER_assert(xTaskHandle != NULL, "Task handle should not be NULL"); } void test_task_parameters() { // 测试任务参数边界 UBaseType_t uxPriority = configMAX_PRIORITIES - 1; uint16_t usStackDepth = configMINIMAL_STACK_SIZE; __CPROVER_assert(uxPriority < configMAX_PRIORITIES, "Priority should be valid"); __CPROVER_assert(usStackDepth >= configMINIMAL_STACK_SIZE, "Stack depth should be sufficient"); } int main() { test_task_creation(); test_task_parameters(); return 0; } EOF log_success "验证测试创建完成" } # 设置环境变量 setup_environment() { log_info "设置环境变量..." local bashrc_file="$HOME/.bashrc" local profile_file="$HOME/.profile" # 检查是否已经设置 if ! grep -q "FREERTOS_HOME" "$bashrc_file" 2>/dev/null; then cat >> "$bashrc_file" << EOF # FreeRTOS环境变量 export FREERTOS_HOME="$INSTALL_DIR" export FREERTOS_INCLUDE="$INSTALL_DIR/include" export PATH="\$PATH:\$FREERTOS_HOME" EOF log_success "环境变量已添加到 ~/.bashrc" else log_warning "环境变量已存在" fi # 创建当前会话的环境变量 export FREERTOS_HOME="$INSTALL_DIR" export FREERTOS_INCLUDE="$INSTALL_DIR/include" export PATH="$PATH:$FREERTOS_HOME" log_success "环境变量设置完成" } # 验证安装 verify_installation() { log_info "验证FreeRTOS安装..." # 检查目录结构 local required_dirs=( "$INSTALL_DIR/include" "$INSTALL_DIR/src/freertos-kernel" "$INSTALL_DIR/portable" "$FREERTOS_CONFIG_DIR" ) for dir in "${required_dirs[@]}"; do if [ ! -d "$dir" ]; then log_error "目录不存在: $dir" exit 1 fi done # 检查关键文件 local required_files=( "$INSTALL_DIR/include/FreeRTOS.h" "$INSTALL_DIR/include/task.h" "$FREERTOS_CONFIG_DIR/FreeRTOSConfig.h" "$INSTALL_DIR/build_freertos.sh" ) for file in "${required_files[@]}"; do if [ ! -f "$file" ]; then log_error "文件不存在: $file" exit 1 fi done # 测试编译 cd "$INSTALL_DIR" if ! ./build_freertos.sh; then log_error "FreeRTOS编译失败" exit 1 fi log_success "FreeRTOS安装验证完成" } # 显示使用说明 show_usage_info() { echo "" echo "=======================================" echo "FreeRTOS环境设置完成" echo "=======================================" echo "" echo "环境变量:" echo " FREERTOS_HOME: $INSTALL_DIR" echo " FREERTOS_INCLUDE: $INSTALL_DIR/include" echo "" echo "重要文件:" echo " 配置文件: $FREERTOS_CONFIG_DIR/FreeRTOSConfig.h" echo " 构建脚本: $INSTALL_DIR/build_freertos.sh" echo " 测试脚本: $INSTALL_DIR/test_example.sh" echo "" echo "下一步操作:" echo " 1. 重新启动终端或运行: source ~/.bashrc" echo " 2. 编译FreeRTOS: cd $INSTALL_DIR && ./build_freertos.sh" echo " 3. 运行测试示例: cd $INSTALL_DIR && ./test_example.sh" echo " 4. 在CodeDetect中验证FreeRTOS代码" echo "" echo "CodeDetect集成:" echo " 配置文件: $FREERTOS_CONFIG_DIR/codedetect_freertos.yaml" echo " 示例代码: $CODEDETECT_DIR/examples/freertos/" echo "" } # 主函数 main() { echo "=======================================" echo "FreeRTOS环境设置脚本" echo "=======================================" echo "" # 检查是否已安装 if [ -f "$INSTALL_DIR/include/FreeRTOS.h" ]; then log_warning "FreeRTOS已安装" read -p "是否重新安装? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then log_info "安装已取消" exit 0 fi fi # 执行安装步骤 check_dependencies create_directory_structure download_freertos install_headers create_config_files create_build_scripts create_verification_tests setup_environment verify_installation show_usage_info log_success "FreeRTOS环境设置完成" } # 脚本入口点 if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi