You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cbmc/codedetect/scripts/setup-freertos-verification.sh

536 lines
12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/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 <FreeRTOS.h>
#include <task.h>
#include <stdio.h>
// 任务函数
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 <FreeRTOS.h>
#include <task.h>
#include <queue.h>
#include <stdio.h>
// 队列句柄
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 <FreeRTOS.h>
#include <task.h>
#include <semphr.h>
#include <stdio.h>
// 互斥锁句柄
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' 来验证示例代码"