#!/bin/bash # FreeRTOS CBMC验证环境设置脚本 set -e FREERTOS_VERSION="10.4.6" FREERTOS_URL="https://github.com/FreeRTOS/FreeRTOS/archive/refs/tags/V${FREERTOS_VERSION}.tar.gz" INSTALL_DIR="/opt/freertos" CODEDETECT_DIR="$(pwd)" FREERTOS_PATH="" echo "🚀 开始设置FreeRTOS CBMC验证环境..." # 检查是否已安装 if [ -d "$INSTALL_DIR" ]; then echo "✅ FreeRTOS已安装在 $INSTALL_DIR" FREERTOS_PATH="$INSTALL_DIR" else # 创建安装目录 sudo mkdir -p "$INSTALL_DIR" sudo chown $USER:$USER "$INSTALL_DIR" # 下载并解压FreeRTOS echo "📥 下载FreeRTOS V${FREERTOS_VERSION}..." cd /tmp wget -q "$FREERTOS_URL" -O freertos.tar.gz tar -xzf freertos.tar.gz # 复制到安装目录 echo "📦 安装FreeRTOS..." cp -r "FreeRTOS-${FREERTOS_VERSION}"/* "$INSTALL_DIR/" # 清理 rm -rf "FreeRTOS-${FREERTOS_VERSION}" freertos.tar.gz FREERTOS_PATH="$INSTALL_DIR" echo "✅ FreeRTOS已安装到 $INSTALL_DIR" fi # 设置环境变量 echo "⚙️ 设置环境变量..." if ! grep -q "FREERTOS_PATH" ~/.bashrc; then echo "export FREERTOS_PATH=\"$FREERTOS_PATH\"" >> ~/.bashrc echo "export C_INCLUDE_PATH=\"$FREERTOS_PATH/FreeRTOS/Source/include:\$FREERTOS_PATH/FreeRTOS/Plus/Source/FreeRTOS-Plus-CLI/include:\$C_INCLUDE_PATH\"" >> ~/.bashrc fi # 验证安装 echo "🔍 验证安装..." if [ -f "$FREERTOS_PATH/FreeRTOS/Source/include/FreeRTOS.h" ]; then echo "✅ FreeRTOS.h found at $FREERTOS_PATH/FreeRTOS/Source/include/FreeRTOS.h" else echo "❌ FreeRTOS.h not found" exit 1 fi # 创建CBMC配置文件 echo "📝 创建CBMC配置文件..." CONFIG_DIR="$CODEDETECT_DIR/config/freertos" mkdir -p "$CONFIG_DIR" cat > "$CONFIG_DIR/cbmc_config.yaml" << 'EOF' # FreeRTOS CBMC验证配置 cbmc: path: "cbmc" timeout: 600 unwind: 50 depth: 30 memory_model: "simple" output_format: "text" # FreeRTOS特定配置 freertos_mode: true freertos_include_path: "/opt/freertos/FreeRTOS/Source/include" # 包含路径 include_paths: - "/opt/freertos/FreeRTOS/Source/include" - "/opt/freertos/FreeRTOS/Source/portable/GCC/Linux" - "/opt/freertos/FreeRTOS/Source/portable/MemMang" # 宏定义 define_macros: - "FREERTOS" - "CBMC" - "configUSE_PREEMPTION=1" - "configUSE_PORT_OPTIMISED_TASK_SELECTION=0" - "configUSE_TICKLESS_IDLE=0" - "configCPU_CLOCK_HZ=16000000" - "configTICK_RATE_HZ=1000" - "configMAX_PRIORITIES=5" - "configMINIMAL_STACK_SIZE=128" - "configTOTAL_HEAP_SIZE=8192" - "configMAX_TASK_NAME_LEN=16" - "configUSE_16_BIT_TICKS=0" - "configIDLE_SHOULD_YIELD=1" - "configUSE_TASK_NOTIFICATIONS=1" - "configUSE_MUTEXES=1" - "configUSE_RECURSIVE_MUTEXES=1" - "configUSE_COUNTING_SEMAPHORES=1" - "configQUEUE_REGISTRY_SIZE=8" - "configUSE_QUEUE_SETS=0" - "configUSE_TIME_SLICING=1" - "configUSE_NEWLIB_REENTRANT=0" - "configENABLE_BACKWARD_COMPATIBILITY=0" - "configNUM_THREAD_LOCAL_STORAGE_POINTERS=5" # 检查选项 check_assertions: true check_overflow: true check_bounds: true check_division: true check_pointers: true check_memory_safety: true check_concurrency: true # 输出选项 show_locations: true show_steps: true show_values: true show_trace: true verbose: false # 并发控制 max_concurrent: 2 # 缓存选项 cache_enabled: true # CodeDetect配置 llm: provider: "deepseek" model: "deepseek-coder" max_tokens: 3000 temperature: 0.3 web: host: "0.0.0.0" port: 8080 debug: false max_file_size: "10MB" EOF # 创建示例代码目录 echo "📝 创建示例代码..." EXAMPLE_DIR="$INSTALL_DIR/examples" mkdir -p "$EXAMPLE_DIR" # 创建简单的FreeRTOS任务示例 cat > "$EXAMPLE_DIR/simple_task.c" << 'EOF' #include #include #include // 任务函数 void vTaskFunction(void *pvParameters) { const char *pcTaskName = "Task"; TickType_t xLastWakeTime; // 初始化xLastWakeTime变量 xLastWakeTime = xTaskGetTickCount(); for (;;) { // 打印任务信息 printf("%s is running\n", pcTaskName); // 延迟500ms vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(500)); } } int main(void) { printf("FreeRTOS CBMC Verification Example\n"); // 创建任务 xTaskCreate( vTaskFunction, // 任务函数 "Task", // 任务名称 configMINIMAL_STACK_SIZE, // 堆栈大小 NULL, // 任务参数 1, // 任务优先级 NULL // 任务句柄 ); // 启动调度器 vTaskStartScheduler(); // 正常情况下不会执行到这里 for (;;); return 0; } EOF # 创建队列操作示例 cat > "$EXAMPLE_DIR/queue_example.c" << 'EOF' #include #include #include #include // 队列句柄 QueueHandle_t xQueue; // 发送者任务 void vSenderTask(void *pvParameters) { int32_t lValueToSend = 100; BaseType_t xStatus; for (;;) { // 发送数据到队列 xStatus = xQueueSend(xQueue, &lValueToSend, 0); if (xStatus == pdPASS) { printf("Sent: %d\n", lValueToSend); } // 延迟1秒 vTaskDelay(pdMS_TO_TICKS(1000)); // 更新发送值 lValueToSend++; } } // 接收者任务 void vReceiverTask(void *pvParameters) { int32_t lReceivedValue; BaseType_t xStatus; const TickType_t xTicksToWait = pdMS_TO_TICKS(100); for (;;) { // 从队列接收数据 xStatus = xQueueReceive(xQueue, &lReceivedValue, xTicksToWait); if (xStatus == pdPASS) { printf("Received: %d\n", lReceivedValue); } else { printf("Could not receive from queue\n"); } } } int main(void) { printf("FreeRTOS Queue Example\n"); // 创建队列,长度为5,每个元素大小为int32_t xQueue = xQueueCreate(5, sizeof(int32_t)); if (xQueue == NULL) { printf("Failed to create queue\n"); return 1; } // 创建发送者任务 xTaskCreate( vSenderTask, "Sender", configMINIMAL_STACK_SIZE, NULL, 1, NULL ); // 创建接收者任务 xTaskCreate( vReceiverTask, "Receiver", configMINIMAL_STACK_SIZE, NULL, 2, // 更高优先级 NULL ); // 启动调度器 vTaskStartScheduler(); return 0; } EOF # 创建互斥锁示例 cat > "$EXAMPLE_DIR/mutex_example.c" << 'EOF' #include #include #include #include // 互斥锁句柄 SemaphoreHandle_t xMutex; // 共享资源 int32_t lSharedVariable = 0; // 任务函数 void vTaskFunction(void *pvParameters) { const char *pcTaskName = (const char *)pvParameters; BaseType_t xStatus; for (;;) { // 获取互斥锁 xStatus = xSemaphoreTake(xMutex, portMAX_DELAY); if (xStatus == pdTRUE) { // 临界区开始 int32_t lLocalCopy = lSharedVariable; printf("%s: Read shared variable = %d\n", pcTaskName, lLocalCopy); // 修改共享变量 lLocalCopy++; lSharedVariable = lLocalCopy; printf("%s: Wrote shared variable = %d\n", pcTaskName, lSharedVariable); // 释放互斥锁 xSemaphoreGive(xMutex); } // 延迟 vTaskDelay(pdMS_TO_TICKS(1000)); } } int main(void) { printf("FreeRTOS Mutex Example\n"); // 创建互斥锁 xMutex = xSemaphoreCreateMutex(); if (xMutex == NULL) { printf("Failed to create mutex\n"); return 1; } // 创建任务1 xTaskCreate( vTaskFunction, "Task1", configMINIMAL_STACK_SIZE, (void *)"Task1", 1, NULL ); // 创建任务2 xTaskCreate( vTaskFunction, "Task2", configMINIMAL_STACK_SIZE, (void *)"Task2", 2, NULL ); // 启动调度器 vTaskStartScheduler(); return 0; } EOF # 创建CBMC验证脚本 cat > "$EXAMPLE_DIR/verify_with_cbmc.sh" << 'EOF' #!/bin/bash # FreeRTOS CBMC验证脚本 set -e FREERTOS_PATH="/opt/freertos" EXAMPLE_DIR="$FREERTOS_PATH/examples" CODEDETECT_DIR="$(pwd)" echo "🔍 开始FreeRTOS CBMC验证..." # 检查CBMC是否可用 if ! command -v cbmc &> /dev/null; then echo "❌ CBMC未安装,请先安装CBMC" exit 1 fi # 检查FreeRTOS路径 if [ ! -d "$FREERTOS_PATH" ]; then echo "❌ FreeRTOS未安装,请先运行setup-freertos-example.sh" exit 1 fi # 验证简单任务示例 echo "📋 验证简单任务示例..." cd "$EXAMPLE_DIR" if [ -f "simple_task.c" ]; then echo "验证 simple_task.c..." cbmc --unwind 50 --depth 30 \ -I "$FREERTOS_PATH/FreeRTOS/Source/include" \ -I "$FREERTOS_PATH/FreeRTOS/Source/portable/GCC/Linux" \ -I "$FREERTOS_PATH/FreeRTOS/Source/portable/MemMang" \ -DFREERTOS -DCBMC \ simple_task.c 2>&1 | head -20 fi # 验证队列示例 echo "📋 验证队列示例..." if [ -f "queue_example.c" ]; then echo "验证 queue_example.c..." cbmc --unwind 50 --depth 30 \ -I "$FREERTOS_PATH/FreeRTOS/Source/include" \ -I "$FREERTOS_PATH/FreeRTOS/Source/portable/GCC/Linux" \ -I "$FREERTOS_PATH/FreeRTOS/Source/portable/MemMang" \ -DFREERTOS -DCBMC \ queue_example.c 2>&1 | head -20 fi # 验证互斥锁示例 echo "📋 验证互斥锁示例..." if [ -f "mutex_example.c" ]; then echo "验证 mutex_example.c..." cbmc --unwind 50 --depth 30 \ -I "$FREERTOS_PATH/FreeRTOS/Source/include" \ -I "$FREERTOS_PATH/FreeRTOS/Source/portable/GCC/Linux" \ -I "$FREERTOS_PATH/FreeRTOS/Source/portable/MemMang" \ -DFREERTOS -DCBMC \ mutex_example.c 2>&1 | head -20 fi echo "✅ FreeRTOS CBMC验证完成" # 使用CodeDetect进行验证 if [ -d "$CODEDETECT_DIR" ]; then echo "🚀 使用CodeDetect进行FreeRTOS验证..." cd "$CODEDETECT_DIR" # 运行FreeRTOS特定的测试 python -m pytest tests/integration/test_freertos_verification.py -v --tb=short fi echo "🎉 所有验证完成" EOF chmod +x "$EXAMPLE_DIR/verify_with_cbmc.sh" # 创建README文件 cat > "$EXAMPLE_DIR/README.md" << 'EOF' # FreeRTOS CBMC验证示例 本目录包含用于CodeDetect的FreeRTOS验证示例。 ## 目录结构 - `simple_task.c` - 简单的FreeRTOS任务示例 - `queue_example.c` - 队列操作示例 - `mutex_example.c` - 互斥锁使用示例 - `verify_with_cbmc.sh` - CBMC验证脚本 ## 环境设置 确保已安装以下组件: 1. **FreeRTOS**: 运行 `../scripts/setup-freertos-example.sh` 2. **CBMC**: 安装CBMC模型检查器 3. **CodeDetect**: 确保CodeDetect项目可用 ## 使用方法 ### 直接CBMC验证 ```bash # 验证单个文件 cbmc --unwind 50 --depth 30 -I/opt/freertos/FreeRTOS/Source/include -DFREERTOS -DCBMC simple_task.c # 运行所有验证 ./verify_with_cbmc.sh ``` ### 使用CodeDetect验证 ```bash # 从CodeDetect项目根目录运行 python -m pytest tests/integration/test_freertos_verification.py -v # 或者使用完整的工作流 python scripts/run_comprehensive_tests.sh --include freertos ``` ## 示例说明 ### 1. 简单任务示例 演示基本的任务创建和调度功能。 ### 2. 队列示例 演示任务间通过队列进行通信。 ### 3. 互斥锁示例 演示资源同步和互斥访问。 ## 验证目标 - 内存安全性检查 - 空指针解引用检测 - 缓冲区溢出检查 - 数据竞争检测 - 死锁检测 - 任务调度正确性 ## 故障排除 ### 常见问题 1. **CBMC未找到**: 确保CBMC已安装并在PATH中 2. **FreeRTOS头文件缺失**: 检查环境变量FREERTOS_PATH设置 3. **验证超时**: 增加unwind和depth参数值 ### 调试技巧 1. 使用`--show-properties`查看验证属性 2. 使用`--trace`生成详细执行轨迹 3. 使用`--xml-ui`获取结构化输出 ## 扩展示例 要创建新的验证示例: 1. 创建包含FreeRTOS API调用的C文件 2. 确保包含必要的头文件 3. 定义CBMC特定的宏 4. 编写测试用例和断言 ## 参考资料 - [FreeRTOS官方文档](https://www.freertos.org/) - [CBMC用户手册](https://www.cprover.org/cbmc/) - [CodeDetect项目文档](https://github.com/your-org/codedetect) EOF echo "✅ FreeRTOS CBMC验证环境设置完成" echo "📍 FreeRTOS路径: $FREERTOS_PATH" echo "📁 示例代码目录: $EXAMPLE_DIR" echo "🔧 请运行 'source ~/.bashrc' 来加载环境变量" echo "🚀 运行 './verify_with_cbmc.sh' 来验证示例代码"