chore: upgrade FreeRTOS to v2 (CMSIS-RTOS_V2), update CubeMX project config

- Remove CMSIS-RTOS v1 (cmsis_os.h/cmsis_os.c), add CMSIS-RTOS v2 (cmsis_os2.c/freertos_os2.h/mpool.h)
- Update FreeRTOS kernel, port, and headers to match v2 integration
- Remove unused heap implementations, keep heap_4
- Update CubeMX project config (.mxproject, .ioc, CMakeLists.txt)
- Update FreeRTOSConfig.h, freertos.c, main.c, stm32h7xx_it.c
- Update application modules (master_machine, dmmotor)
- Add CMSIS-RTOS2 headers, mpu_syscall_numbers.h, newlib/picolibc support
This commit is contained in:
2026-05-30 20:40:00 +08:00
parent b7328a0c93
commit 8763b25839
63 changed files with 27596 additions and 23151 deletions
+38 -36
View File
File diff suppressed because one or more lines are too long
+88
View File
@@ -121,6 +121,50 @@
} }
] ]
}, },
{
"name": "programmer",
"version": "2.22.0+st.1",
"platform": "aarch64-darwin",
"selected_by": [
{
"name": "programmer",
"version": "2.22.0+st.1"
}
]
},
{
"name": "programmer",
"version": "2.22.0+st.1",
"platform": "darwin",
"selected_by": [
{
"name": "programmer",
"version": "2.22.0+st.1"
}
]
},
{
"name": "programmer",
"version": "2.22.0+st.1",
"platform": "x86_64-linux",
"selected_by": [
{
"name": "programmer",
"version": "2.22.0+st.1"
}
]
},
{
"name": "programmer",
"version": "2.22.0+st.1",
"platform": "x86_64-windows",
"selected_by": [
{
"name": "programmer",
"version": "2.22.0+st.1"
}
]
},
{ {
"name": "st-arm-clangd", "name": "st-arm-clangd",
"version": "21.1.0+st.2", "version": "21.1.0+st.2",
@@ -153,6 +197,50 @@
"version": "21.1.0+st.2" "version": "21.1.0+st.2"
} }
] ]
},
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3",
"platform": "aarch64-darwin",
"selected_by": [
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3"
}
]
},
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3",
"platform": "darwin",
"selected_by": [
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3"
}
]
},
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3",
"platform": "x86_64-linux",
"selected_by": [
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3"
}
]
},
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3",
"platform": "x86_64-windows",
"selected_by": [
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3"
}
]
} }
] ]
} }
+8
View File
@@ -15,6 +15,14 @@
{ {
"name": "st-arm-clangd", "name": "st-arm-clangd",
"version": "21.1.0+st.2" "version": "21.1.0+st.2"
},
{
"name": "programmer",
"version": "2.22.0+st.1"
},
{
"name": "stlink-gdbserver",
"version": "7.13.0+st.3"
} }
] ]
} }
+15
View File
@@ -2,6 +2,21 @@
// 启动调试的快捷键是F5 // 启动调试的快捷键是F5
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"type": "stlinkgdbtarget",
"request": "launch",
"name": "STM32Cube: Launch ST-Link GDB Server",
"origin": "snippet",
"cwd": "${workspaceFolder}",
"preBuild": "${command:st-stm32-ide-debug-launch.build}",
"runEntry": "main",
"imagesAndSymbols": [
{
"imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}"
}
]
},
// 使用dap-link(如无线调试器时的参考配置) // 使用dap-link(如无线调试器时的参考配置)
{ {
"name": "DAPlink", "name": "DAPlink",
+228 -247
View File
@@ -1,329 +1,310 @@
# 项目架构分析报告:Basic_Framework_MC02 (RoboMaster 云台机器人) # 项目架构:Basic_Framework_MC02 (DM 云台控制系统)
## 概览 ## 概览
这是一个基于 **STM32H723** (Cortex-M7) 的 RoboMaster 竞赛机器人控制项目。项目采用 FreeRTOS 实时操作系统,目前配置为**单板控制整车**(`ONE_BOARD` 模式),代码组织呈分层架构。项目由 **湖南大学岳麓电气 (HNU YueLu EC)** 开发。 基于 **STM32H723** (Cortex-M7, 480MHz) 的达妙电机云台控制系统。采用 FreeRTOS,通过 IMU 反馈实现角度闭环,通过串口接收上位机指令实现视觉追踪。项目源自 HNU YueLu EC RoboMaster 项目,经重构精简为纯云台控制。
--- ---
## 一、硬件与通信总览 ## 一、硬件与通信
| 资源 | 用途 | | 资源 | 用途 |
|------|------| |------|------|
| **FDCAN1/2/3** | 电机控制总线(DJI 电机、达妙电机等) | | **FDCAN1** | 电机控制总线 (DM-G6220 yaw, DM-J4310-2EC pitch) |
| **USART1** | 板间通信 (BoardComm) | | **USART10** | 上位机通信 (master_machine 协议) |
| **USART5** | 遥控器 (DBUS/DR16) |
| **USART7** | VoFA 调试输出 | | **USART7** | VoFA 调试输出 |
| **USART10** | 视觉/上位机 (OpenCV 通信) | | **USART1** | 板间通信 (BoardComm) |
| **SPI1/2** | BMI088 IMU 传感器、OLED | | **SPI2** | BMI088 IMU 传感器 |
| **I2C2** | 通用 I2C |
| **OCTOSPI2** | 外部 Flash (W25Qxx) |
| **TIM1/2/3/12** | PWM 输出、编码器输入、DWT 时钟基准 |
| **USB Device** | 虚拟串口 (CDC) |
| **ADC1** | 模拟量采集 |
| **GPIO** | 电源控制、激光器等 |
--- ---
## 二、分层架构 ## 二、分层架构
项目采用 **4 层架构**:
``` ```
┌──────────────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────┐
│ application/ 应用层 │ │ application/ 应用层 │
│ robot.c → robot_cmd → gimbal / chassis / shoot │ │ robot.c → robot_cmd → gimbal │
├──────────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────┤
│ modules/ 模块层 │ │ modules/ 模块层 │
│ motor, imu, referee, remote, vision, algorithm, ... │ │ motor, imu, master_machine, algorithm, ... │
├──────────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────┤
│ bsp/ 板级支持包 │ │ bsp/ 板级支持包 │
│ can, usart, spi, iic, pwm, dwt, log, gpio │ │ can, usart, spi, dwt, log, gpio │
├──────────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────┤
│ Drivers/ HAL 驱动层 (CubeMX 生成) │ │ Drivers/ HAL 驱动层 (CubeMX 生成) │
│ STM32H7xx_HAL, CMSIS, FreeRTOS, USB, SEGGER RTT │ │ STM32H7xx_HAL, CMSIS, FreeRTOS │
└──────────────────────────────────────────────────────────┘ └──────────────────────────────────────────────┘
``` ```
--- ---
## 三、启动与初始化流程 ## 三、启动流程
### 3.1 main() 启动序列
``` ```
HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_DMA_Init() main()
→ MX_ADC1_Init() → MX_USB_DEVICE_Init() → MX_TIM/SPI/USART/UART/FDCAN/..._Init() ├── HAL_Init() → SystemClock_Config() → MX_*_Init() // CubeMX 外设初始化
→ RobotInit() ← 唯一的用户初始化入口 └── RobotInit()
→ while(1) {} ← 空循环,所有逻辑在 RTOS 任务中 ├── BSPInit() // DWT + Log
├── RobotCMDInit() // pub-sub, 视觉PID, 串口初始化
├── GimbalInit() // IMU + DM 电机初始化
└── OSTaskInit() // 创建 4 个 RTOS 任务
``` ```
### 3.2 RobotInit() 初始化链 ### FreeRTOS 任务
```
RobotInit()
├── __disable_irq() // 关中断,保证初始化原子性
├── BSPInit()
│ ├── DWT_Init(480) // 时钟周期计数器 (CPU=480MHz)
│ └── BSPLogInit() // 日志系统(SEGGER RTT + 串口)
├── RobotCMDInit() // 核心命令任务初始化
│ ├── RemoteControlInit(&huart5) // 遥控器 (DBUS)
│ ├── PubRegister() x6 // 注册 6 个消息话题:
│ │ gimbal_cmd / gimbal_feed // 云台控制/反馈
│ │ shoot_cmd / shoot_feed // 发射控制/反馈
│ │ chassis_cmd / chassis_feed // 底盘控制/反馈
│ ├── PIDInit() x2 (yaw + pitch 跟踪PID) // 视觉跟踪 PID 初始化
│ ├── VisionKalmanFilterInit() // 视觉误差卡尔曼滤波器
│ ├── Vision_Uart_Init(&huart10) // 视觉串口通信
│ └── BoardCommInit(&huart1) // 板间通信
├── GimbalInit() // 云台电机初始化
│ ├── INS_Init() → BMI088 SPI 初始化 // IMU 惯导
│ ├── PubRegister("gimbal_feed") / SubRegister("gimbal_cmd")
│ ├── DJIMotorInit(GM6020) → yaw 电机 // Yaw: GM6020 直驱
│ └── DMMotorInit() → pitch 电机 // Pitch: 达妙电机
├── OSTaskInit() // 创建 RTOS 任务
│ ├── INS Task (1kHz, AboveNormal) // 姿态解算最高优先级
│ ├── Motor Task (1kHz, Normal) // 电机控制
│ ├── Daemon Task (100Hz, Normal) // 看门狗/蜂鸣器
│ ├── Robot Task (500Hz, Normal) // 机器人核心控制
│ └── DMMotorControlInit() // 达妙大电机初始化
└── __enable_irq() // 开中断
```
---
## 四、FreeRTOS 任务架构
| 任务 | 频率 | 优先级 | 功能 | | 任务 | 频率 | 优先级 | 功能 |
|------|------|--------|------| |------|------|--------|------|
| **INS Task** | 1kHz | AboveNormal | 阻塞读取 BMI088,进行四元数 EKF 姿态解算 | | **INS Task** | 1kHz | AboveNormal | BMI088 读取 → 四元数 EKF 姿态解算 |
| **Motor Task** | 1kHz | Normal | DJI/LK/HT 电机 PID 闭环计算与 CAN 发送 | | **Motor Task** | 1kHz | Normal | DM 电机角度 PID → CAN 速度指令发送 |
| **Robot Task** | 500Hz | Normal | 调用 `RobotTask()` 串联各应用层任务 | | **Robot Task** | 500Hz | Normal | 上位机命令处理 + 模式切换 + 控制执行 |
| **Daemon Task** | 100Hz | Normal | 模块看门狗喂狗检查 + 蜂鸣器控制 | | **Daemon Task** | 100Hz | Normal | 模块看门狗 + 蜂鸣器 |
--- ---
## 五、消息中心 (Pub-Sub) ## 四、PID 双环架构
位于 `modules/message_center/`,这是应用层内部的核心通信机制:
- **发布者 (Publisher)**:以**话题名 (topic name)** 标识,通过**链表**管理订阅者
- **订阅者 (Subscriber)**:每个订阅者维护一个长度为 1 的 **FIFO 队列**
- 支持最多 **12 个话题**,话题名最长 **32 字符**
### 当前消息流:
``` ```
robot_cmd (CMD) ──→ gimbal_cmd ──→ gimbal 应用 ┌──────────────────────────────────────────────────────┐
├── chassis_cmd → chassis 应用 │ application/cmd/robot_cmd.c (外环, 500Hz) │
└── shoot_cmd ──→ shoot 应用 │ │
│ 上位机 0xA5 帧 → error_x/y → KF → vision PID │
gimbal ──→ gimbal_feed ──→ robot_cmd (CMD) │ → 角度增量 → 累计 angle ref │
chassis ──→ chassis_feed ──→ robot_cmd (CMD) │ 上位机 0xA6 帧 → yaw_ref/pitch_ref 直接设定 │
shoot ──→ shoot_feed ──→ robot_cmd (CMD) │ │
│ ProcessCommand() 处理模式切换 / 激光控制 │
└──────────────────────┬───────────────────────────────┘
│ gimbal_cmd (pub-sub)
▼
┌──────────────────────────────────────────────────────┐
│ application/gimbal/gimbal.c (传递, 500Hz) │
│ │
│ DMMotorSetRef(yaw, cmd.yaw) │
│ DMMotorSetRef(pitch, cmd.pitch) │
│ 反馈: gimbal_feed → gimbal_IMU_data 指针 │
└──────────────────────┬───────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────┐
│ modules/motor/DMmotor/ (内环, 1kHz) │
│ │
│ IMU 角度反馈 → angle PID → velocity output │
│ → DMMotorSendVelocity() → CAN 速度模式 │
│ output_reverse 控制输出方向 │
└──────────────────────────────────────────────────────┘
``` ```
--- ---
## 六、应用层模块 ## 五、上位机串口协议
### 6.1 RobotCMD (`application/cmd/`) — 机器人大脑 位于 `modules/master_machine/`。三种帧类型,通过帧头区分。
核心决策模块,集成以下功能: ### 自动/视觉追踪数据帧 `0xA5` (10 字节)
| 功能 | 说明 | | 字节 | 0 | 1-4 | 5-8 | 9 |
|------|---|-----|-----|---|
| 内容 | 0xA5 | error_x (float) | error_y (float) | checksum |
### 手动控制数据帧 `0xA6` (11 字节)
| 字节 | 0 | 1 | 2-5 | 6-9 | 10 |
|------|---|-----|-----|-----|----|
| 内容 | 0xA6 | zero_force | yaw_ref (float) | pitch_ref (float) | checksum |
### 命令帧 `0xA7` (3 字节)
| 字节 | 0 | 1 | 2 |
|------|---|-----|----|
| 内容 | 0xA7 | cmd | checksum |
命令码:`0x01` 切换到自动模式, `0x02` 切换到手动模式, `0x03` 激光开, `0x04` 激光关
### 数据流
```
上位机 USART10 → DecodeVision() → vision_data (全局结构体)
├── 0xA5 → auto_updated=1, error_x/y
├── 0xA6 → manual_updated=1, zero_force, yaw_ref/pitch_ref
└── 0xA7 → cmd_pending=1, cmd
robot_cmd 每轮:
ProcessCommand() → 模式切换 / 激光
AUTO: vision_data.error_x/y → KF → vision PID → 角度增量
MANUAL: vision_data.yaw_ref/pitch_ref → 直接设定
PubPushMessage(gimbal_cmd) → gimbal 执行
```
---
## 六、DM 电机驱动
位于 `modules/motor/DMmotor/`。基于 DM_6220 参考协议。
### 速度模式 (当前默认)
CAN ID = motor_id + 0x200,发送 float velocity (4 bytes)。
```
DMMotorControl() @ 1kHz:
PIDCalculate(angle_PID, IMU_angle, pid_ref) → velocity
output_reverse? → DMMotorSendVelocity() → CAN
```
### 电机配置
| 电机 | CAN ID | 反馈 ID | 模式 | MIT KP/KD |
|------|--------|---------|------|-----------|
| DM-G6220 (Yaw) | 0x01 | 0xF1 | Velocity | — |
| DM-J4310-2EC (Pitch) | 0x02 | 0xF2 | Velocity | — |
### API
| 函数 | 说明 |
|------|------| |------|------|
| **遥控器解析** | DBUS 协议,摇杆/开关/键鼠 | | `DMMotorInit()` | 初始化电机实例 (CAN 注册, PID 初始化, daemon) |
| **视觉跟踪** | OpenCV 视觉数据 → 卡尔曼滤波 → PID 跟踪 → 云台角度控制 | | `DMMotorSetRef()` | 设定角度参考值 (degrees) |
| **画圆模式** | 遥控器拨轮控制画圆轨迹跟踪 | | `DMMotorControl()` | 1kHz 控制循环 (所有电机) |
| **题号状态机** | 竞赛自动任务状态机,支持 6 种题号,含转向/搜索/跟踪子状态 | | `DMMotorSetMode()` | 发送命令 (使能/停止/清零/清除错误) |
| **急停处理** | 遥控器右侧开关拨下 → 所有电机零力输出 | | `DMMotorSendVelocity()` | 速度模式 CAN 发送 |
| **激光控制** | GPIO 控制激光笔开关 | | `DMMotorSendMIT()` | MIT 模式 CAN 发送 |
| `DMMotorSendPosVel()` | 位置-速度模式 CAN 发送 |
`RobotCMDTask()` 执行流程(500Hz):
```
读取底盘/发射/云台反馈消息 → 判断控制模式(手动/自动/视觉)
→ EmergencyHandler(急停检测) → 推送控制消息给各应用
```
**题号状态机** (YunTaiState):
```
YUNT_IDLE
→ NO1: 零力模式
→ NO2: 视觉跟踪 + 激光 (等待1.5s后开启激光)
→ NO3: 转向0度 → 视觉跟踪/搜索 → 激光 (3.5s后)
→ NO4_1: 转向-45度 → 视觉跟踪 + 前馈
→ NO4_3: 转向-45度 → 视觉跟踪 (error=60) + 画圆前馈
```
### 6.2 Gimbal (`application/gimbal/`) — 云台控制
- **Yaw 轴**:GM6020 (DJI 直驱电机),CAN1 ID=0x01,IMU 反馈替代电机编码器
- **Pitch 轴**:达妙电机 (DM Motor),CAN1 ID=0x06/0x16,IMU 反馈
- **控制模式**:
- `GIMBAL_ZERO_FORCE`:零力
- `GIMBAL_GYRO_MODE`:陀螺仪姿态闭环 (使用 IMU Pitch + YawTotalAngle)
- **特点**:角度/角速度反馈均来自 IMU(替代电机编码器),带有速度和电流前馈
### 6.3 Chassis (`application/chassis/`) — 底盘控制
- 麦克纳姆轮底盘 (Mecanum),4x GM6020 电机
- 运动学解算:正逆运动学,云台→底盘坐标系变换
- 支持裁判系统功率限制和超级电容管理
### 6.4 Shoot (`application/shoot/`) — 发射控制
- **摩擦轮**:2x M3508 (CAN2 ID=1,2),速度串联电流闭环
- **拨盘电机**:M2006 (CAN2 ID=3),多模式:
- `LOAD_STOP`:停止
- `LOAD_1_BULLET`:单发(角度闭环,加减角度 = ONE_BULLET_DELTA_ANGLE)
- `LOAD_3_BULLET`:三连发
- `LOAD_BURSTFIRE`:连发(速度闭环,可调射频)
- `LOAD_REVERSE`:反转
- **弹速模式**:15m/s / 18m/s / 30m/s
- 弹舱盖开关控制
--- ---
## 七、模块层 (modules/) ## 七、模块层
| 分类 | 模块 | 功能 | | 分类 | 模块 | 功能 |
|------|------|------| |------|------|------|
| **电机** | `dji_motor` | DJI GM6020/M3508/M2006 标准电机驱动,串级 PID (角度→速度→电流) | | **电机** | `motor/DMmotor` | 达妙电机驱动 (MIT/PosVel/Velocity 三模式) |
| | `DMMotor` | 达妙电机 (DM Motor) 驱动 | | | `motor/motor_task` | 电机控制统一调度 (`DMMotorControl`) |
| | `LKmotor` (LK9025) | LK 电机驱动 | | **姿态** | `imu/ins_task` | 惯导解算 (四元数 EKF, 返回 INS_t 指针) |
| | `HTmotor` (HT04) | HT04 电机驱动 | | | `imu/BMI088driver` | BMI088 SPI 读取 |
| | `step_motor` | 步进电机 (含 X_V2 变体) |
| | `servo_motor` | 舵机控制 |
| | `motor_task` | 电机控制统一调度 (`MotorControlTask`) |
| **姿态** | `imu/ins_task` | 惯导解算:四元数 EKF,BMI088 传感器 |
| | `imu/BMI088driver` | BMI088 SPI 底层读取 |
| | `imu/BMI088Middleware` | BMI088 数据换算 | | | `imu/BMI088Middleware` | BMI088 数据换算 |
| **算法** | `controller` | 通用 PID 控制器(支持变积分、梯形积分、微分先行、输出滤波等改进) | | **算法** | `algorithm/controller` | PID 控制器 (梯形积分/变速积分/微分先行/输出滤波) |
| | `kalman_filter` | 标准卡尔曼滤波器 + 自适应 (`UseAutoAdjustment`) | | | `algorithm/kalman_filter` | 卡尔曼滤波器 (自适应) |
| | `QuaternionEKF` | 四元数扩展卡尔曼滤波 | | | `algorithm/QuaternionEKF` | 四元数 EKF (陀螺零偏估计/卡方检验) |
| | `crc8/crc16` | CRC 校验 | | | `algorithm/crc8/crc16` | CRC 校验 |
| | `user_lib` | 通用数学/工具函数 | | | `algorithm/user_lib` | 数学/工具函数 |
| **通信** | `remote/remote_control` | DJI DBUS 遥控器解析 (位域优化) | | **通信** | `master_machine` | 上位机通信 (0xA5/0xA6/0xA7 协议, 接收+解析) |
| | `master_machine` | 视觉上位机通信 (SeaSky 协议) | | | `timachine/board_comm` | 板间通信 |
| | `referee` | 裁判系统 (RM Referee Protocol, UI 绘制) | | | `message_center` | Pub-Sub 消息中间件 (链表, FIFO) |
| | `can_comm` | CAN 通信抽象层(双板情况下的数据转发) | | **系统** | `daemon` | 看门狗 (重载计数+离线回调) |
| | `board_comm` | 板间通信(固定帧格式: 帧头 + 2x int32 + 2x float + 校验) | | | `alarm/buzzer` | 蜂鸣器 |
| | `bluetooth/HC05` | HC05 蓝牙模块 | | | `vofa` | VoFA+ 调试输出 |
| | `opencv` | OpenCV 视觉数据处理 |
| **辅助** | `message_center` | Pub-Sub 消息中间件(伪发布订阅,仅做应用间隔离) |
| | `daemon` | 看门狗守护进程(在线检测 + 异常回调) |
| | `alarm/buzzer` | 蜂鸣器告警 |
| | `vofa` | 调试数据可视化 (VoFA+ FireWater) |
| | `oled` | OLED 显示屏 |
| | `super_cap` | 超级电容管理 |
--- ---
## 八、BSP 驱动层 ## 八、BSP 驱动层
所有 BSP 驱动采用**实例化注册**模式(不注册不初始化): 实例化注册模式 (不注册不初始化):
| 模块 | 功能 | | 模块 | 功能 |
|------|------| |------|------|
| `bsp_dwt` | DWT 时钟周期计数器(精确延时 μs/ms,时间戳获取) | | `bsp_dwt` | DWT 周期计数器 (μs/ms 延时, 时间戳) |
| `bsp_can` | CAN 总线收发封装(FIFO+中断,实例化注册) | | `bsp_can` | FDCAN 收发 (FIFO+中断) |
| `bsp_usart` | 串口收发封装(DMA+环形缓冲区,实例化注册) | | `bsp_usart` | 串口收发 (DMA+环形缓冲区) |
| `bsp_spi` | SPI 通信封装 | | `bsp_spi` | SPI 通信 |
| `bsp_iic` | I2C 通信封装 | | `bsp_log` | SEGGER RTT + 串口日志 |
| `bsp_pwm` | PWM 输出(支持 DMA 传输) | | `bsp_pwm` | PWM 输出 |
| `bsp_gpio` | GPIO 管理 |
| `bsp_log` | SEGGER RTT + 串口日志输出(LOGINFO/LOGERROR/LOGWARNING) |
| `bsp_tools` | RTOS 任务创建工具 (`CreateCallbackTask`) |
--- ---
## 九、数据流与控制流总结 ## 九、数据流
``` ```
┌─────────────┐ ┌──────────────┐
│ 遥控器DBUS │ │ 上位机 │
│ (USART5) │ │ (USART10) │
└──────┬──────┘ └──────┬───────┘
↓ │ 0xA5 / 0xA6 / 0xA7
▼
┌────────────────────────┐ ┌────────────────────────┐
│ RobotCMD │ │ RobotCMD │
│ ┌─────────────────┐ │ │ ProcessCommand() │ ← 模式切换/激光
│ │ RemoteControlSet│ │ ← 手动模式 (遥控器调试) │ VisionTrackingSet() │ ← KF → vision PID → 角度增量
│ │ AutoSet (题号) │ │ ← 自动模式 (竞赛任务) │ ManualModeSet() │ ← 直接角度参考
│ └───────┬─────────┘ │ │ PubPushMessage() │
│ ↓ │ └───────────┬────────────┘
│ 发布: gimbal_cmd │──→ Gimbal (云台 PID → IMU 反馈) │ gimbal_cmd
│ chassis_cmd │──→ Chassis (运动学 → 麦轮) ▼
│ shoot_cmd │──→ Shoot (摩擦轮/拨盘) ┌────────────────────────┐
│ Gimbal │
│ DMMotorSetRef() │
│ 反馈: gimbal_feed │ ← INS_t* 指针
└───────────┬────────────┘
│ angle ref
▼
┌────────────────────────┐
│ DMMotor │ (1kHz Motor Task)
│ IMU angle → PID │
│ → Velocity mode CAN │
└────────────────────────┘ └────────────────────────┘
↑ │
┌────────────┴───────────┐ ┌───────────┴────────────┐
│ 反馈: gimbal_feed │ ← 云台姿态 + 电机角度 │ DM-G6220 DM-J4310 │
│ chassis_feed │ ← 底盘速度 + 热量 │ (Yaw) (Pitch) │
│ shoot_feed │ ← 发射状态
└────────────────────────┘ └────────────────────────┘
视觉/OpenCV (USART10) ──→ 卡尔曼滤波 ──→ PID ──→ 云台角度控制
板间通信 (USART1) ──→ BoardComm ──→ 题号/坐标数据
裁判系统 ──→ 热量/弹速/UI 绘制
``` ```
--- ---
## 十、关键设计特点 ## 十、关键设计
1. **IMU 替代电机反馈**:云台 Yaw/Pitch 使用陀螺仪角度/角速度替代编码器,实现更高精度姿态闭环 1. **IMU 反馈替代编码器** — 云台 Yaw/Pitch 使用 INS_t 中的 YawTotalAngle/Pitch 和 Gyro[]
2. **伪 Pub-Sub 模式**:应用间通过 `message_center` 解耦,支持单板/双板条件编译切换(`ONE_BOARD` / `GIMBAL_BOARD` / `CHASSIS_BOARD`) 2. **速度模式控制** — MCU 跑角度 PID,电机内部处理速度闭环
3. **Daemon 看门狗**:每个外设模块注册独立的 `DaemonInstance`(重载计数 + 离线回调),模块离线时自动触发异常处理 3. **伪 Pub-Sub** — 应用间通过 message_center 解耦
4. **BSP 实例化注册**:CAN/串口等外设不注册不初始化,避免资源浪费 4. **Daemon 看门狗** — 每个外设模块独立 DaemonInstance,离线自动回调
5. **竞赛状态机**:完整的题号自动任务流程(转向→搜索→跟踪→激光打击) 5. **BSP 实例化注册** — CAN/串口不注册不初始化
6. **卡尔曼滤波 + PID 级联**:视觉误差经过 KF 平滑后由 PID 计算输出,带前馈补偿 6. **KF + PID 级联** — 视觉误差经 KF 平滑 → vision PID → 角度增量 → 内环角度 PID
7. **位域优化**:遥控器键盘状态使用位域 (`Key_t`),空间减少 8 倍 7. **模式切换重置** — 切换到自动模式时重置 KF 状态 (x=0, P=diag(5,5)) 和 PID 积分项
8. **条件编译**:单板/双板/电机类型/视觉通信方式均通过宏定义切换 8. **串口命令控制** — 模式切换、激光控制均通过 0xA7 命令帧触发
9. **output_reverse** — PID 输出方向统一通过单标志位控制
--- ---
## 十一、项目规模统计 ## 十一、项目规模
| 类别 | 数量 | | 类别 | 数量 |
|------|------| |------|------|
| C 源文件 | 115 个 | | C 源文件 | 96 |
| ASM 源文件 | 2 个 | | ASM 源文件 | 2 |
| 应用层模块 | 4 (robot_cmd, gimbal, chassis, shoot) | | 应用层模块 | 3 (robot, robot_cmd, gimbal) |
| 模块层子模块 | 20+ (电机×6, 姿态×3, 算法×5, 通信×7, 辅助×5) | | 模块层子模块 | 10 (motor, imu, algorithm, master_machine, message_center, daemon, buzzer, vofa, board_comm) |
| BSP 驱动模块 | 10 | | BSP 驱动模块 | 8 |
| FreeRTOS 任务 | 4 (默认) | | FreeRTOS 任务 | 4 |
| 最高控制频率 | 1kHz | | 最高控制频率 | 1kHz |
| CPU 频率 | 480MHz (PLL = HSE 8MHz / 2 × 40 / 2) | | CPU 频率 | 480MHz |
| FLASH 使用 | 161,556 B / 1 MB (15.41%) | | FLASH 使用 | ~133 KB / 1 MB (13%) |
| DTCMRAM 使用 | 60,920 B / 128 KB (46.48%) | | DTCMRAM 使用 | ~59 KB / 128 KB (46%) |
--- ---
## 十二、电机配置速查 ## 十二、核心数据类型
| 电机 | 类型 | CAN 总线 | TX ID | 控制闭环 | PID 级联 |
|------|------|----------|-------|----------|----------|
| Yaw (云台) | GM6020 | CAN1 | 0x01 | 角度+速度 | Angle → Speed (IMU 反馈) |
| Pitch (云台) | DM Motor | CAN1 | 0x06/0x16 | 角度+速度 | Angle → Speed (IMU 反馈) |
| 摩擦轮 左 | M3508 | CAN2 | 0x01 | 速度+电流 | Speed → Current |
| 摩擦轮 右 | M3508 | CAN2 | 0x02 | 速度+电流 | Speed → Current (反转) |
| 拨盘 | M2006 | CAN2 | 0x03 | 角度/速度+电流 | Angle/Speed → Current |
---
## 十三、关键配置宏 (`robot_def.h`)
```c ```c
#define ONE_BOARD // 单板控制整车 // INS 惯导实例 (ins_task.h)
#define VISION_USE_UART // 使用串口发送视觉数据 typedef struct {
#define YAW_CHASSIS_ALIGN_ECD 2711 // 云台底盘对齐编码器值 float q[4]; // 四元数
#define PITCH_HORIZON_ECD 3412 // 云台水平位置编码器值 float Gyro[3]; // 角速度 (rad/s)
#define ONE_BULLET_DELTA_ANGLE 36 // 单发弹丸拨盘转动角度 float Accel[3]; // 加速度 (m/s²)
#define WHEEL_BASE 350 // 纵向轴距 (mm) float Roll, Pitch, Yaw;
#define TRACK_WIDTH 300 // 横向轮距 (mm) float YawTotalAngle; // 多圈 yaw (degrees)
#define RADIUS_WHEEL 60 // 轮子半径 (mm) } INS_t;
// 云台控制指令 (robot_def.h)
typedef struct {
float yaw; // yaw 目标角度 (degrees)
float pitch; // pitch 目标角度 (degrees)
} Gimbal_Ctrl_Cmd_s;
// 上位机数据 (master_machine.h)
typedef struct {
float error_x, error_y; // 自动模式: 归一化误差
uint8_t auto_updated;
uint8_t zero_force; // 手动模式: 零力标志
float yaw_ref, pitch_ref; // 手动模式: 角度参考
uint8_t manual_updated;
uint8_t cmd, cmd_pending; // 命令
float frequency;
} VisionData_t;
``` ```
+85 -67
View File
@@ -383,42 +383,50 @@ FDCAN3.RxFifo0ElmtsNbr=4
FDCAN3.RxFifo1ElmtsNbr=4 FDCAN3.RxFifo1ElmtsNbr=4
FDCAN3.StdFiltersNbr=14 FDCAN3.StdFiltersNbr=14
FDCAN3.TxFifoQueueElmtsNbr=4 FDCAN3.TxFifoQueueElmtsNbr=4
FREERTOS.IPParameters=Tasks01,configENABLE_FPU
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
FREERTOS.configENABLE_FPU=1
File.Version=6 File.Version=6
GPIO.groupedBy=Group By Peripherals GPIO.groupedBy=Group By Peripherals
I2C2.IPParameters=Timing I2C2.IPParameters=Timing
I2C2.Timing=0x307075B1 I2C2.Timing=0x307075B1
KeepUserPlacement=false KeepUserPlacement=false
MMTAppRegionsCount=0
MMTConfigApplied=false
MMTSectionSuffix=
Mcu.CPN=STM32H723VGT6 Mcu.CPN=STM32H723VGT6
Mcu.Family=STM32H7 Mcu.Family=STM32H7
Mcu.IP0=ADC1 Mcu.IP0=ADC1
Mcu.IP1=CORTEX_M7 Mcu.IP1=CORTEX_M7
Mcu.IP10=RCC Mcu.IP10=NVIC
Mcu.IP11=SPI1 Mcu.IP11=OCTOSPI2
Mcu.IP12=SPI2 Mcu.IP12=RCC
Mcu.IP13=SYS Mcu.IP13=SPI1
Mcu.IP14=TIM1 Mcu.IP14=SPI2
Mcu.IP15=TIM2 Mcu.IP15=SYS
Mcu.IP16=TIM3 Mcu.IP16=TIM1
Mcu.IP17=TIM12 Mcu.IP17=TIM2
Mcu.IP18=UART5 Mcu.IP18=TIM3
Mcu.IP19=UART7 Mcu.IP19=TIM12
Mcu.IP2=DEBUG Mcu.IP2=DEBUG
Mcu.IP20=UART8 Mcu.IP20=UART5
Mcu.IP21=UART9 Mcu.IP21=UART7
Mcu.IP22=USART1 Mcu.IP22=UART8
Mcu.IP23=USART2 Mcu.IP23=UART9
Mcu.IP24=USART3 Mcu.IP24=USART1
Mcu.IP25=USART10 Mcu.IP25=USART2
Mcu.IP26=USB_DEVICE Mcu.IP26=USART3
Mcu.IP27=USB_OTG_HS Mcu.IP27=USART10
Mcu.IP28=USB_DEVICE
Mcu.IP29=USB_OTG_HS
Mcu.IP3=DMA Mcu.IP3=DMA
Mcu.IP4=FDCAN1 Mcu.IP4=FDCAN1
Mcu.IP5=FDCAN2 Mcu.IP5=FDCAN2
Mcu.IP6=FDCAN3 Mcu.IP6=FDCAN3
Mcu.IP7=I2C2 Mcu.IP7=FREERTOS
Mcu.IP8=NVIC Mcu.IP8=I2C2
Mcu.IP9=OCTOSPI2 Mcu.IP9=MEMORYMAP
Mcu.IPNb=28 Mcu.IPNb=30
Mcu.Name=STM32H723VGTx Mcu.Name=STM32H723VGTx
Mcu.Package=LQFP100 Mcu.Package=LQFP100
Mcu.Pin0=PE2 Mcu.Pin0=PE2
@@ -482,64 +490,69 @@ Mcu.Pin60=PB5
Mcu.Pin61=PB6 Mcu.Pin61=PB6
Mcu.Pin62=PE0 Mcu.Pin62=PE0
Mcu.Pin63=PE1 Mcu.Pin63=PE1
Mcu.Pin64=VP_OCTOSPI2_VS_quad Mcu.Pin64=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin65=VP_SYS_VS_tim23 Mcu.Pin65=VP_OCTOSPI2_VS_quad
Mcu.Pin66=VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS Mcu.Pin66=VP_SYS_VS_tim23
Mcu.Pin67=VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.4.0_1.4.0 Mcu.Pin67=VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS
Mcu.Pin68=VP_MEMORYMAP_VS_MEMORYMAP
Mcu.Pin69=VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.4.0_1.4.0
Mcu.Pin7=PC0 Mcu.Pin7=PC0
Mcu.Pin8=PC1 Mcu.Pin8=PC1
Mcu.Pin9=PC2_C Mcu.Pin9=PC2_C
Mcu.PinsNb=68 Mcu.PinsNb=70
Mcu.ThirdParty0=STMicroelectronics.X-CUBE-ALGOBUILD.1.4.0 Mcu.ThirdParty0=STMicroelectronics.X-CUBE-ALGOBUILD.1.4.0
Mcu.ThirdPartyNb=1 Mcu.ThirdPartyNb=1
Mcu.UserConstants= Mcu.UserConstants=
Mcu.UserName=STM32H723VGTx Mcu.UserName=STM32H723VGTx
MxCube.Version=6.17.0 MxCube.Version=6.17.0
MxDb.Version=DB.6.0.170 MxDb.Version=DB.6.0.170
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.DMA1_Stream0_IRQn=true\:5\:0\:false\:false\:true\:false\:false\:true NVIC.DMA1_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream6_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Stream6_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream7_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Stream7_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA2_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA2_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA2_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA2_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA2_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA2_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA2_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA2_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA2_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA2_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA2_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA2_Stream6_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA2_Stream6_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DMA2_Stream7_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA2_Stream7_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.FDCAN1_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.FDCAN1_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN1_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.FDCAN1_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN2_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.FDCAN2_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN2_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.FDCAN2_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN3_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.FDCAN3_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN3_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.FDCAN3_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=true NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.I2C2_EV_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.I2C2_EV_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.OTG_HS_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.OTG_HS_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:true\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false NVIC.SavedPendsvIrqHandlerGenerated=false
NVIC.TIM23_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true NVIC.SavedSvcallIrqHandlerGenerated=false
NVIC.SavedSystickIrqHandlerGenerated=false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:true\:true\:false
NVIC.TIM23_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TimeBase=TIM23_IRQn NVIC.TimeBase=TIM23_IRQn
NVIC.TimeBaseIP=TIM23 NVIC.TimeBaseIP=TIM23
NVIC.UART5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.UART5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.UART7_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.UART7_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.USART10_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.USART10_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.USART2_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.USART2_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.USART3_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.USART3_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
OCTOSPI2.ClockMode=HAL_OSPI_CLOCK_MODE_3 OCTOSPI2.ClockMode=HAL_OSPI_CLOCK_MODE_3
OCTOSPI2.ClockPrescaler=3 OCTOSPI2.ClockPrescaler=3
OCTOSPI2.DeviceSize=23 OCTOSPI2.DeviceSize=23
@@ -957,6 +970,10 @@ USB_DEVICE.VirtualMode=Cdc
USB_DEVICE.VirtualModeHS=Cdc_HS USB_DEVICE.VirtualModeHS=Cdc_HS
USB_OTG_HS.IPParameters=VirtualMode-Device_Only_FS USB_OTG_HS.IPParameters=VirtualMode-Device_Only_FS
USB_OTG_HS.VirtualMode-Device_Only_FS=Device_Only_FS USB_OTG_HS.VirtualMode-Device_Only_FS=Device_Only_FS
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
VP_OCTOSPI2_VS_quad.Mode=quad_mode VP_OCTOSPI2_VS_quad.Mode=quad_mode
VP_OCTOSPI2_VS_quad.Signal=OCTOSPI2_VS_quad VP_OCTOSPI2_VS_quad.Signal=OCTOSPI2_VS_quad
VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.4.0_1.4.0.Mode=DSPOoLibraryJjLibrary VP_STMicroelectronics.X-CUBE-ALGOBUILD_VS_DSPOoLibraryJjLibrary_1.4.0_1.4.0.Mode=DSPOoLibraryJjLibrary
@@ -966,3 +983,4 @@ VP_SYS_VS_tim23.Signal=SYS_VS_tim23
VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS.Mode=CDC_HS VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS.Mode=CDC_HS
VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_HS VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_HS
board=custom board=custom
rtos.0.ip=FREERTOS
+4 -12
View File
@@ -18,6 +18,10 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_BUILD_TYPE "Debug")
endif() endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_compile_definitions(DISABLE_LOG_SYSTEM)
endif()
# Set the project name # Set the project name
set(CMAKE_PROJECT_NAME Basic_Framework_MC02) set(CMAKE_PROJECT_NAME Basic_Framework_MC02)
@@ -44,18 +48,6 @@ target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
# Add sources to executable # Add sources to executable
target_sources(${CMAKE_PROJECT_NAME} PRIVATE target_sources(${CMAKE_PROJECT_NAME} PRIVATE
# FreeRTOS
Middlewares/Third_Party/FreeRTOS/Source/croutine.c
Middlewares/Third_Party/FreeRTOS/Source/event_groups.c
Middlewares/Third_Party/FreeRTOS/Source/list.c
Middlewares/Third_Party/FreeRTOS/Source/queue.c
Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c
Middlewares/Third_Party/FreeRTOS/Source/tasks.c
Middlewares/Third_Party/FreeRTOS/Source/timers.c
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
# SEGGER RTT # SEGGER RTT
Middlewares/Third_Party/SEGGER/RTT/SEGGER_RTT_printf.c Middlewares/Third_Party/SEGGER/RTT/SEGGER_RTT_printf.c
Middlewares/Third_Party/SEGGER/RTT/SEGGER_RTT.c Middlewares/Third_Party/SEGGER/RTT/SEGGER_RTT.c
+34 -22
View File
@@ -27,7 +27,6 @@
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* USER CODE END Header */ /* USER CODE END Header */
#ifndef FREERTOS_CONFIG_H #ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H
@@ -49,13 +48,13 @@
/* Ensure definitions are only used by the compiler, and not by the assembler. */ /* Ensure definitions are only used by the compiler, and not by the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h> #include <stdint.h>
extern uint32_t SystemCoreClock; extern uint32_t SystemCoreClock;
/* USER CODE BEGIN 0 */
extern void configureTimerForRunTimeStats(void);
extern unsigned long getRunTimeCounterValue(void);
/* USER CODE END 0 */
#endif #endif
#ifndef CMSIS_device_header
#define CMSIS_device_header "stm32h7xx.h"
#endif /* CMSIS_device_header */
#define configENABLE_FPU 1 #define configENABLE_FPU 1
#define configENABLE_MPU 0 #define configENABLE_MPU 0
@@ -66,17 +65,20 @@
#define configUSE_TICK_HOOK 0 #define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ((TickType_t)1000) #define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 7 ) #define configMAX_PRIORITIES ( 56 )
#define configUSE_SB_COMPLETED_CALLBACK ( 0 )
#define configUSE_MINI_LIST_ITEM ( 1 )
#define configMINIMAL_STACK_SIZE ((uint16_t)128) #define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)25600) #define configTOTAL_HEAP_SIZE ((size_t)15360)
#define configMAX_TASK_NAME_LEN ( 16 ) #define configMAX_TASK_NAME_LEN ( 16 )
#define configGENERATE_RUN_TIME_STATS 1 #define configHEAP_CLEAR_MEMORY_ON_FREE 0
#define configUSE_TRACE_FACILITY 1 #define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0 #define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1 #define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8 #define configQUEUE_REGISTRY_SIZE 8
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ /* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
/* Defaults to size_t for backward compatibility, but can be changed /* Defaults to size_t for backward compatibility, but can be changed
if lengths will always be less than the number of bytes in a size_t. */ if lengths will always be less than the number of bytes in a size_t. */
@@ -93,6 +95,13 @@
#define configTIMER_QUEUE_LENGTH 10 #define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH 256 #define configTIMER_TASK_STACK_DEPTH 256
/* CMSIS-RTOS V2 flags */
#define configUSE_OS2_THREAD_SUSPEND_RESUME 1
#define configUSE_OS2_THREAD_ENUMERATE 1
#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1
#define configUSE_OS2_THREAD_FLAGS 1
#define configUSE_OS2_TIMER 1
#define configUSE_OS2_MUTEX 1
/* Set the following definitions to 1 to include the API function, or zero /* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */ to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_vTaskPrioritySet 1
@@ -100,10 +109,20 @@ to exclude the API function. */
#define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_xTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1 #define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xQueueGetMutexHolder 1 #define INCLUDE_xQueueGetMutexHolder 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_eTaskGetState 1
/*
* The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
* by the application thus the correct define need to be enabled below
*/
#define USE_FreeRTOS_HEAP_4
/* Cortex-M specific definitions. */ /* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS
@@ -115,6 +134,7 @@ to exclude the API function. */
/* The lowest interrupt priority that can be used in a call to a "set priority" /* The lowest interrupt priority that can be used in a call to a "set priority"
function. */ function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
/* The highest interrupt priority that can be used by any interrupt service /* The highest interrupt priority that can be used by any interrupt service
@@ -140,17 +160,9 @@ header file. */
standard names. */ standard names. */
#define vPortSVCHandler SVC_Handler #define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler #define xPortPendSVHandler PendSV_Handler
/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
/* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick, #define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0
to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
#define xPortSysTickHandler SysTick_Handler
/* USER CODE BEGIN 2 */
/* Definitions needed when configGENERATE_RUN_TIME_STATS is on */
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats
#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue
/* USER CODE END 2 */
/* USER CODE BEGIN Defines */ /* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
+18 -56
View File
@@ -21,7 +21,8 @@
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#include "main.h" #include "main.h"
#include "cmsis_os.h" #include "FreeRTOS.h"
#include "cmsis_os2.h"
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
@@ -47,67 +48,24 @@
/* USER CODE BEGIN Variables */ /* USER CODE BEGIN Variables */
/* USER CODE END Variables */ /* USER CODE END Variables */
osThreadId defaultTaskHandle; /* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */ /* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */ /* USER CODE END FunctionPrototypes */
void StartDefaultTask(void const * argument); void StartDefaultTask(void *argument);
extern void MX_USB_DEVICE_Init(void); extern void MX_USB_DEVICE_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
/* GetTimerTaskMemory prototype (linked to static allocation support) */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );
/* Hook prototypes */
void configureTimerForRunTimeStats(void);
unsigned long getRunTimeCounterValue(void);
/* USER CODE BEGIN 1 */
/* Functions needed when configGENERATE_RUN_TIME_STATS is on */
__weak void configureTimerForRunTimeStats(void)
{
}
__weak unsigned long getRunTimeCounterValue(void)
{
return 0;
}
/* USER CODE END 1 */
/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
*ppxIdleTaskStackBuffer = &xIdleStack[0];
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
/* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY */
/* USER CODE BEGIN GET_TIMER_TASK_MEMORY */
static StaticTask_t xTimerTaskTCBBuffer;
static StackType_t xTimerStack[configTIMER_TASK_STACK_DEPTH];
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{
*ppxTimerTaskTCBBuffer = &xTimerTaskTCBBuffer;
*ppxTimerTaskStackBuffer = &xTimerStack[0];
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
/* place for user code */
}
/* USER CODE END GET_TIMER_TASK_MEMORY */
/** /**
* @brief FreeRTOS initialization * @brief FreeRTOS initialization
* @param None * @param None
@@ -135,14 +93,17 @@ void MX_FREERTOS_Init(void) {
/* USER CODE END RTOS_QUEUES */ /* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */ /* Create the thread(s) */
/* definition and creation of defaultTask */ /* creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128); defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* USER CODE BEGIN RTOS_THREADS */ /* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */ /* add threads, ... */
/* USER CODE END RTOS_THREADS */ /* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
} }
/* USER CODE BEGIN Header_StartDefaultTask */ /* USER CODE BEGIN Header_StartDefaultTask */
@@ -152,7 +113,7 @@ void MX_FREERTOS_Init(void) {
* @retval None * @retval None
*/ */
/* USER CODE END Header_StartDefaultTask */ /* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument) void StartDefaultTask(void *argument)
{ {
/* init code for USB_DEVICE */ /* init code for USB_DEVICE */
MX_USB_DEVICE_Init(); MX_USB_DEVICE_Init();
@@ -169,3 +130,4 @@ void StartDefaultTask(void const * argument)
/* USER CODE BEGIN Application */ /* USER CODE BEGIN Application */
/* USER CODE END Application */ /* USER CODE END Application */
+12 -1
View File
@@ -18,6 +18,8 @@
/* USER CODE END Header */ /* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "main.h" #include "main.h"
#include "FreeRTOS.h"
#include "cmsis_os2.h"
#include "adc.h" #include "adc.h"
#include "dma.h" #include "dma.h"
#include "fdcan.h" #include "fdcan.h"
@@ -63,6 +65,7 @@ uint8_t W25Qxx_ReadBuffer[W25Qxx_NumByteToTest]; // ��������
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void); void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
/* USER CODE BEGIN PFP */ /* USER CODE BEGIN PFP */
/* USER CODE END PFP */ /* USER CODE END PFP */
@@ -103,7 +106,6 @@ int main(void)
MX_GPIO_Init(); MX_GPIO_Init();
MX_DMA_Init(); MX_DMA_Init();
MX_ADC1_Init(); MX_ADC1_Init();
MX_USB_DEVICE_Init();
MX_TIM12_Init(); MX_TIM12_Init();
MX_SPI1_Init(); MX_SPI1_Init();
MX_SPI2_Init(); MX_SPI2_Init();
@@ -128,6 +130,15 @@ int main(void)
LOGINFO("[main] SystemInit() and RobotInit() done"); LOGINFO("[main] SystemInit() and RobotInit() done");
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize(); /* Call init function for freertos objects (in cmsis_os2.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */ /* Infinite loop */
/* USER CODE BEGIN WHILE */ /* USER CODE BEGIN WHILE */
while (1) while (1)
+19 -1
View File
@@ -6,7 +6,7 @@
****************************************************************************** ******************************************************************************
* @attention * @attention
* *
* Copyright (c) 2024 STMicroelectronics. * Copyright (c) 2026 STMicroelectronics.
* All rights reserved. * All rights reserved.
* *
* This software is licensed under terms that can be found in the LICENSE file * This software is licensed under terms that can be found in the LICENSE file
@@ -194,6 +194,7 @@ void DMA1_Stream0_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream0_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream0_IRQn 0 */
/* USER CODE END DMA1_Stream0_IRQn 0 */ /* USER CODE END DMA1_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA1_Stream0_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream0_IRQn 1 */
/* USER CODE END DMA1_Stream0_IRQn 1 */ /* USER CODE END DMA1_Stream0_IRQn 1 */
@@ -207,6 +208,7 @@ void DMA1_Stream1_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream1_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */
/* USER CODE END DMA1_Stream1_IRQn 0 */ /* USER CODE END DMA1_Stream1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart3_tx);
/* USER CODE BEGIN DMA1_Stream1_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */
/* USER CODE END DMA1_Stream1_IRQn 1 */ /* USER CODE END DMA1_Stream1_IRQn 1 */
@@ -220,6 +222,7 @@ void DMA1_Stream2_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream2_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */
/* USER CODE END DMA1_Stream2_IRQn 0 */ /* USER CODE END DMA1_Stream2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_i2c2_rx);
/* USER CODE BEGIN DMA1_Stream2_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */
/* USER CODE END DMA1_Stream2_IRQn 1 */ /* USER CODE END DMA1_Stream2_IRQn 1 */
@@ -233,6 +236,7 @@ void DMA1_Stream3_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream3_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */
/* USER CODE END DMA1_Stream3_IRQn 0 */ /* USER CODE END DMA1_Stream3_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_i2c2_tx);
/* USER CODE BEGIN DMA1_Stream3_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream3_IRQn 1 */
/* USER CODE END DMA1_Stream3_IRQn 1 */ /* USER CODE END DMA1_Stream3_IRQn 1 */
@@ -246,6 +250,7 @@ void DMA1_Stream4_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream4_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream4_IRQn 0 */
/* USER CODE END DMA1_Stream4_IRQn 0 */ /* USER CODE END DMA1_Stream4_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_uart9_rx);
/* USER CODE BEGIN DMA1_Stream4_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream4_IRQn 1 */
/* USER CODE END DMA1_Stream4_IRQn 1 */ /* USER CODE END DMA1_Stream4_IRQn 1 */
@@ -259,6 +264,7 @@ void DMA1_Stream5_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream5_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream5_IRQn 0 */
/* USER CODE END DMA1_Stream5_IRQn 0 */ /* USER CODE END DMA1_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_uart9_tx);
/* USER CODE BEGIN DMA1_Stream5_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream5_IRQn 1 */
/* USER CODE END DMA1_Stream5_IRQn 1 */ /* USER CODE END DMA1_Stream5_IRQn 1 */
@@ -272,6 +278,7 @@ void DMA1_Stream6_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream6_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream6_IRQn 0 */
/* USER CODE END DMA1_Stream6_IRQn 0 */ /* USER CODE END DMA1_Stream6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart3_rx);
/* USER CODE BEGIN DMA1_Stream6_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream6_IRQn 1 */
/* USER CODE END DMA1_Stream6_IRQn 1 */ /* USER CODE END DMA1_Stream6_IRQn 1 */
@@ -397,6 +404,7 @@ void DMA1_Stream7_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream7_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream7_IRQn 0 */
/* USER CODE END DMA1_Stream7_IRQn 0 */ /* USER CODE END DMA1_Stream7_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_uart5_rx);
/* USER CODE BEGIN DMA1_Stream7_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream7_IRQn 1 */
/* USER CODE END DMA1_Stream7_IRQn 1 */ /* USER CODE END DMA1_Stream7_IRQn 1 */
@@ -424,6 +432,7 @@ void DMA2_Stream0_IRQHandler(void)
/* USER CODE BEGIN DMA2_Stream0_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
/* USER CODE END DMA2_Stream0_IRQn 0 */ /* USER CODE END DMA2_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA2_Stream0_IRQn 1 */ /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
/* USER CODE END DMA2_Stream0_IRQn 1 */ /* USER CODE END DMA2_Stream0_IRQn 1 */
@@ -437,6 +446,7 @@ void DMA2_Stream1_IRQHandler(void)
/* USER CODE BEGIN DMA2_Stream1_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream1_IRQn 0 */
/* USER CODE END DMA2_Stream1_IRQn 0 */ /* USER CODE END DMA2_Stream1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_tx);
/* USER CODE BEGIN DMA2_Stream1_IRQn 1 */ /* USER CODE BEGIN DMA2_Stream1_IRQn 1 */
/* USER CODE END DMA2_Stream1_IRQn 1 */ /* USER CODE END DMA2_Stream1_IRQn 1 */
@@ -450,6 +460,7 @@ void DMA2_Stream2_IRQHandler(void)
/* USER CODE BEGIN DMA2_Stream2_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
/* USER CODE END DMA2_Stream2_IRQn 0 */ /* USER CODE END DMA2_Stream2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_tx);
/* USER CODE BEGIN DMA2_Stream2_IRQn 1 */ /* USER CODE BEGIN DMA2_Stream2_IRQn 1 */
/* USER CODE END DMA2_Stream2_IRQn 1 */ /* USER CODE END DMA2_Stream2_IRQn 1 */
@@ -463,6 +474,7 @@ void DMA2_Stream3_IRQHandler(void)
/* USER CODE BEGIN DMA2_Stream3_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream3_IRQn 0 */
/* USER CODE END DMA2_Stream3_IRQn 0 */ /* USER CODE END DMA2_Stream3_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_rx);
/* USER CODE BEGIN DMA2_Stream3_IRQn 1 */ /* USER CODE BEGIN DMA2_Stream3_IRQn 1 */
/* USER CODE END DMA2_Stream3_IRQn 1 */ /* USER CODE END DMA2_Stream3_IRQn 1 */
@@ -476,6 +488,7 @@ void DMA2_Stream4_IRQHandler(void)
/* USER CODE BEGIN DMA2_Stream4_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream4_IRQn 0 */
/* USER CODE END DMA2_Stream4_IRQn 0 */ /* USER CODE END DMA2_Stream4_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart10_rx);
/* USER CODE BEGIN DMA2_Stream4_IRQn 1 */ /* USER CODE BEGIN DMA2_Stream4_IRQn 1 */
/* USER CODE END DMA2_Stream4_IRQn 1 */ /* USER CODE END DMA2_Stream4_IRQn 1 */
@@ -489,6 +502,7 @@ void DMA2_Stream5_IRQHandler(void)
/* USER CODE BEGIN DMA2_Stream5_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream5_IRQn 0 */
/* USER CODE END DMA2_Stream5_IRQn 0 */ /* USER CODE END DMA2_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart10_tx);
/* USER CODE BEGIN DMA2_Stream5_IRQn 1 */ /* USER CODE BEGIN DMA2_Stream5_IRQn 1 */
/* USER CODE END DMA2_Stream5_IRQn 1 */ /* USER CODE END DMA2_Stream5_IRQn 1 */
@@ -502,6 +516,7 @@ void DMA2_Stream6_IRQHandler(void)
/* USER CODE BEGIN DMA2_Stream6_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream6_IRQn 0 */
/* USER CODE END DMA2_Stream6_IRQn 0 */ /* USER CODE END DMA2_Stream6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_uart8_tx);
/* USER CODE BEGIN DMA2_Stream6_IRQn 1 */ /* USER CODE BEGIN DMA2_Stream6_IRQn 1 */
/* USER CODE END DMA2_Stream6_IRQn 1 */ /* USER CODE END DMA2_Stream6_IRQn 1 */
@@ -515,6 +530,7 @@ void DMA2_Stream7_IRQHandler(void)
/* USER CODE BEGIN DMA2_Stream7_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream7_IRQn 0 */
/* USER CODE END DMA2_Stream7_IRQn 0 */ /* USER CODE END DMA2_Stream7_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_uart8_rx);
/* USER CODE BEGIN DMA2_Stream7_IRQn 1 */ /* USER CODE BEGIN DMA2_Stream7_IRQn 1 */
/* USER CODE END DMA2_Stream7_IRQn 1 */ /* USER CODE END DMA2_Stream7_IRQn 1 */
@@ -528,6 +544,7 @@ void OTG_HS_IRQHandler(void)
/* USER CODE BEGIN OTG_HS_IRQn 0 */ /* USER CODE BEGIN OTG_HS_IRQn 0 */
/* USER CODE END OTG_HS_IRQn 0 */ /* USER CODE END OTG_HS_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_OTG_HS);
/* USER CODE BEGIN OTG_HS_IRQn 1 */ /* USER CODE BEGIN OTG_HS_IRQn 1 */
/* USER CODE END OTG_HS_IRQn 1 */ /* USER CODE END OTG_HS_IRQn 1 */
@@ -597,6 +614,7 @@ void TIM23_IRQHandler(void)
/* USER CODE BEGIN TIM23_IRQn 0 */ /* USER CODE BEGIN TIM23_IRQn 0 */
/* USER CODE END TIM23_IRQn 0 */ /* USER CODE END TIM23_IRQn 0 */
HAL_TIM_IRQHandler(&htim23);
/* USER CODE BEGIN TIM23_IRQn 1 */ /* USER CODE BEGIN TIM23_IRQn 1 */
/* USER CODE END TIM23_IRQn 1 */ /* USER CODE END TIM23_IRQn 1 */
+4 -4
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2018 Arm Limited. All rights reserved. * Copyright (c) 2013-2020 Arm Limited. All rights reserved.
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
@@ -17,7 +17,7 @@
* *
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* *
* $Date: 18. June 2018 * $Date: 12. June 2020
* $Revision: V2.1.3 * $Revision: V2.1.3
* *
* Project: CMSIS-RTOS2 API * Project: CMSIS-RTOS2 API
@@ -86,7 +86,7 @@ typedef enum {
osKernelLocked = 3, ///< Locked. osKernelLocked = 3, ///< Locked.
osKernelSuspended = 4, ///< Suspended. osKernelSuspended = 4, ///< Suspended.
osKernelError = -1, ///< Error. osKernelError = -1, ///< Error.
osKernelReserved = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization. osKernelReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
} osKernelState_t; } osKernelState_t;
/// Thread state. /// Thread state.
@@ -723,7 +723,7 @@ osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *
/// \return maximum number of messages. /// \return maximum number of messages.
uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id);
/// Get maximum message size in a Memory Pool. /// Get maximum message size in a Message Queue.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \return maximum message size in bytes. /// \return maximum message size in bytes.
uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id);
+12 -3
View File
@@ -1,11 +1,11 @@
/**************************************************************************//** /**************************************************************************//**
* @file os_tick.h * @file os_tick.h
* @brief CMSIS OS Tick header file * @brief CMSIS OS Tick header file
* @version V1.0.1 * @version V1.0.2
* @date 24. November 2017 * @date 19. March 2021
******************************************************************************/ ******************************************************************************/
/* /*
* Copyright (c) 2017-2017 ARM Limited. All rights reserved. * Copyright (c) 2017-2021 ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
@@ -27,6 +27,11 @@
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/// IRQ Handler. /// IRQ Handler.
#ifndef IRQHANDLER_T #ifndef IRQHANDLER_T
#define IRQHANDLER_T #define IRQHANDLER_T
@@ -68,4 +73,8 @@ uint32_t OS_Tick_GetCount (void);
/// \return OS Tick overflow status (1 - overflow, 0 - no overflow). /// \return OS Tick overflow status (1 - overflow, 0 - no overflow).
uint32_t OS_Tick_GetOverflow (void); uint32_t OS_Tick_GetOverflow (void);
#ifdef __cplusplus
}
#endif
#endif /* OS_TICK_H */ #endif /* OS_TICK_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2013-2019 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 10. January 2017
* $Revision: V2.1.0
*
* Project: CMSIS-RTOS API
* Title: cmsis_os.h FreeRTOS header file
*---------------------------------------------------------------------------*/
#ifndef CMSIS_OS_H_
#define CMSIS_OS_H_
#define osCMSIS 0x20001U ///< API version (main[31:16].sub[15:0])
#include "cmsis_os2.h"
#endif // CMSIS_OS_H_
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,63 @@
/* --------------------------------------------------------------------------
* Copyright (c) 2013-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Name: freertos_mpool.h
* Purpose: CMSIS RTOS2 wrapper for FreeRTOS
*
*---------------------------------------------------------------------------*/
#ifndef FREERTOS_MPOOL_H_
#define FREERTOS_MPOOL_H_
#include <stdint.h>
#include "FreeRTOS.h"
#include "semphr.h"
/* Memory Pool implementation definitions */
#define MPOOL_STATUS 0x5EED0000U
/* Memory Block header */
typedef struct {
void *next; /* Pointer to next block */
} MemPoolBlock_t;
/* Memory Pool control block */
typedef struct MemPoolDef_t {
MemPoolBlock_t *head; /* Pointer to head block */
SemaphoreHandle_t sem; /* Pool semaphore handle */
uint8_t *mem_arr; /* Pool memory array */
uint32_t mem_sz; /* Pool memory array size */
const char *name; /* Pointer to name string */
uint32_t bl_sz; /* Size of a single block */
uint32_t bl_cnt; /* Number of blocks */
uint32_t n; /* Block allocation index */
volatile uint32_t status; /* Object status flags */
#if (configSUPPORT_STATIC_ALLOCATION == 1)
StaticSemaphore_t mem_sem; /* Semaphore object memory */
#endif
} MemPool_t;
/* No need to hide static object type, just align to coding style */
#define StaticMemPool_t MemPool_t
/* Define memory pool control block size */
#define MEMPOOL_CB_SIZE (sizeof(StaticMemPool_t))
/* Define size of the byte array required to create count of blocks of given size */
#define MEMPOOL_ARR_SIZE(bl_count, bl_size) (((((bl_size) + (4 - 1)) / 4) * 4)*(bl_count))
#endif /* FREERTOS_MPOOL_H_ */
@@ -0,0 +1,310 @@
/* --------------------------------------------------------------------------
* Copyright (c) 2013-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Name: freertos_os2.h
* Purpose: CMSIS RTOS2 wrapper for FreeRTOS
*
*---------------------------------------------------------------------------*/
#ifndef FREERTOS_OS2_H_
#define FREERTOS_OS2_H_
#include <string.h>
#include <stdint.h>
#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core
#include CMSIS_device_header
/*
CMSIS-RTOS2 FreeRTOS image size optimization definitions.
Note: Definitions configUSE_OS2 can be used to optimize FreeRTOS image size when
certain functionality is not required when using CMSIS-RTOS2 API.
In general optimization decisions are left to the tool chain but in cases
when coding style prevents it to optimize the code following optional
definitions can be used.
*/
/*
Option to exclude CMSIS-RTOS2 functions osThreadSuspend and osThreadResume from
the application image.
*/
#ifndef configUSE_OS2_THREAD_SUSPEND_RESUME
#define configUSE_OS2_THREAD_SUSPEND_RESUME 1
#endif
/*
Option to exclude CMSIS-RTOS2 function osThreadEnumerate from the application image.
*/
#ifndef configUSE_OS2_THREAD_ENUMERATE
#define configUSE_OS2_THREAD_ENUMERATE 1
#endif
/*
Option to disable CMSIS-RTOS2 function osEventFlagsSet and osEventFlagsClear
operation from ISR.
*/
#ifndef configUSE_OS2_EVENTFLAGS_FROM_ISR
#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1
#endif
/*
Option to exclude CMSIS-RTOS2 Thread Flags API functions from the application image.
*/
#ifndef configUSE_OS2_THREAD_FLAGS
#define configUSE_OS2_THREAD_FLAGS configUSE_TASK_NOTIFICATIONS
#endif
/*
Option to exclude CMSIS-RTOS2 Timer API functions from the application image.
*/
#ifndef configUSE_OS2_TIMER
#define configUSE_OS2_TIMER configUSE_TIMERS
#endif
/*
Option to exclude CMSIS-RTOS2 Mutex API functions from the application image.
*/
#ifndef configUSE_OS2_MUTEX
#define configUSE_OS2_MUTEX configUSE_MUTEXES
#endif
/*
CMSIS-RTOS2 FreeRTOS configuration check (FreeRTOSConfig.h).
Note: CMSIS-RTOS API requires functions included by using following definitions.
In case if certain API function is not used compiler will optimize it away.
*/
#if (INCLUDE_xSemaphoreGetMutexHolder == 0)
/*
CMSIS-RTOS2 function osMutexGetOwner uses FreeRTOS function xSemaphoreGetMutexHolder. In case if
osMutexGetOwner is not used in the application image, compiler will optimize it away.
Set #define INCLUDE_xSemaphoreGetMutexHolder 1 to fix this error.
*/
#error "Definition INCLUDE_xSemaphoreGetMutexHolder must equal 1 to implement Mutex Management API."
#endif
#if (INCLUDE_vTaskDelay == 0)
/*
CMSIS-RTOS2 function osDelay uses FreeRTOS function vTaskDelay. In case if
osDelay is not used in the application image, compiler will optimize it away.
Set #define INCLUDE_vTaskDelay 1 to fix this error.
*/
#error "Definition INCLUDE_vTaskDelay must equal 1 to implement Generic Wait Functions API."
#endif
#if (INCLUDE_xTaskDelayUntil == 0)
/*
CMSIS-RTOS2 function osDelayUntil uses FreeRTOS function xTaskDelayUntil. In case if
osDelayUntil is not used in the application image, compiler will optimize it away.
Set #define INCLUDE_xTaskDelayUntil 1 to fix this error.
*/
#error "Definition INCLUDE_xTaskDelayUntil must equal 1 to implement Generic Wait Functions API."
#endif
#if (INCLUDE_vTaskDelete == 0)
/*
CMSIS-RTOS2 function osThreadTerminate and osThreadExit uses FreeRTOS function
vTaskDelete. In case if they are not used in the application image, compiler
will optimize them away.
Set #define INCLUDE_vTaskDelete 1 to fix this error.
*/
#error "Definition INCLUDE_vTaskDelete must equal 1 to implement Thread Management API."
#endif
#if (INCLUDE_xTaskGetCurrentTaskHandle == 0)
/*
CMSIS-RTOS2 API uses FreeRTOS function xTaskGetCurrentTaskHandle to implement
functions osThreadGetId, osThreadFlagsClear and osThreadFlagsGet. In case if these
functions are not used in the application image, compiler will optimize them away.
Set #define INCLUDE_xTaskGetCurrentTaskHandle 1 to fix this error.
*/
#error "Definition INCLUDE_xTaskGetCurrentTaskHandle must equal 1 to implement Thread Management API."
#endif
#if (INCLUDE_xTaskGetSchedulerState == 0)
/*
CMSIS-RTOS2 API uses FreeRTOS function xTaskGetSchedulerState to implement Kernel
tick handling and therefore it is vital that xTaskGetSchedulerState is included into
the application image.
Set #define INCLUDE_xTaskGetSchedulerState 1 to fix this error.
*/
#error "Definition INCLUDE_xTaskGetSchedulerState must equal 1 to implement Kernel Information and Control API."
#endif
#if (INCLUDE_uxTaskGetStackHighWaterMark == 0)
/*
CMSIS-RTOS2 function osThreadGetStackSpace uses FreeRTOS function uxTaskGetStackHighWaterMark.
In case if osThreadGetStackSpace is not used in the application image, compiler will
optimize it away.
Set #define INCLUDE_uxTaskGetStackHighWaterMark 1 to fix this error.
*/
#error "Definition INCLUDE_uxTaskGetStackHighWaterMark must equal 1 to implement Thread Management API."
#endif
#if (INCLUDE_uxTaskPriorityGet == 0)
/*
CMSIS-RTOS2 function osThreadGetPriority uses FreeRTOS function uxTaskPriorityGet. In case if
osThreadGetPriority is not used in the application image, compiler will optimize it away.
Set #define INCLUDE_uxTaskPriorityGet 1 to fix this error.
*/
#error "Definition INCLUDE_uxTaskPriorityGet must equal 1 to implement Thread Management API."
#endif
#if (INCLUDE_vTaskPrioritySet == 0)
/*
CMSIS-RTOS2 function osThreadSetPriority uses FreeRTOS function vTaskPrioritySet. In case if
osThreadSetPriority is not used in the application image, compiler will optimize it away.
Set #define INCLUDE_vTaskPrioritySet 1 to fix this error.
*/
#error "Definition INCLUDE_vTaskPrioritySet must equal 1 to implement Thread Management API."
#endif
#if (INCLUDE_eTaskGetState == 0)
/*
CMSIS-RTOS2 API uses FreeRTOS function vTaskDelayUntil to implement functions osThreadGetState
and osThreadTerminate. In case if these functions are not used in the application image,
compiler will optimize them away.
Set #define INCLUDE_eTaskGetState 1 to fix this error.
*/
#error "Definition INCLUDE_eTaskGetState must equal 1 to implement Thread Management API."
#endif
#if (INCLUDE_vTaskSuspend == 0)
/*
CMSIS-RTOS2 API uses FreeRTOS functions vTaskSuspend and vTaskResume to implement
functions osThreadSuspend and osThreadResume. In case if these functions are not
used in the application image, compiler will optimize them away.
Set #define INCLUDE_vTaskSuspend 1 to fix this error.
Alternatively, if the application does not use osThreadSuspend and
osThreadResume they can be excluded from the image code by setting:
#define configUSE_OS2_THREAD_SUSPEND_RESUME 0 (in FreeRTOSConfig.h)
*/
#if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1)
#error "Definition INCLUDE_vTaskSuspend must equal 1 to implement Kernel Information and Control API."
#endif
#endif
#if (INCLUDE_xTimerPendFunctionCall == 0)
/*
CMSIS-RTOS2 function osEventFlagsSet and osEventFlagsClear, when called from
the ISR, call FreeRTOS functions xEventGroupSetBitsFromISR and
xEventGroupClearBitsFromISR which are only enabled if timers are operational and
xTimerPendFunctionCall in enabled.
Set #define INCLUDE_xTimerPendFunctionCall 1 and #define configUSE_TIMERS 1
to fix this error.
Alternatively, if the application does not use osEventFlagsSet and osEventFlagsClear
from the ISR their operation from ISR can be restricted by setting:
#define configUSE_OS2_EVENTFLAGS_FROM_ISR 0 (in FreeRTOSConfig.h)
*/
#if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 1)
#error "Definition INCLUDE_xTimerPendFunctionCall must equal 1 to implement Event Flags API."
#endif
#endif
#if (configUSE_TIMERS == 0)
/*
CMSIS-RTOS2 Timer Management API functions use FreeRTOS timer functions to implement
timer management. In case if these functions are not used in the application image,
compiler will optimize them away.
Set #define configUSE_TIMERS 1 to fix this error.
Alternatively, if the application does not use timer functions they can be
excluded from the image code by setting:
#define configUSE_OS2_TIMER 0 (in FreeRTOSConfig.h)
*/
#if (configUSE_OS2_TIMER == 1)
#error "Definition configUSE_TIMERS must equal 1 to implement Timer Management API."
#endif
#endif
#if (configUSE_MUTEXES == 0)
/*
CMSIS-RTOS2 Mutex Management API functions use FreeRTOS mutex functions to implement
mutex management. In case if these functions are not used in the application image,
compiler will optimize them away.
Set #define configUSE_MUTEXES 1 to fix this error.
Alternatively, if the application does not use mutex functions they can be
excluded from the image code by setting:
#define configUSE_OS2_MUTEX 0 (in FreeRTOSConfig.h)
*/
#if (configUSE_OS2_MUTEX == 1)
#error "Definition configUSE_MUTEXES must equal 1 to implement Mutex Management API."
#endif
#endif
#if (configUSE_COUNTING_SEMAPHORES == 0)
/*
CMSIS-RTOS2 Memory Pool functions use FreeRTOS function xSemaphoreCreateCounting
to implement memory pools. In case if these functions are not used in the application image,
compiler will optimize them away.
Set #define configUSE_COUNTING_SEMAPHORES 1 to fix this error.
*/
#error "Definition configUSE_COUNTING_SEMAPHORES must equal 1 to implement Memory Pool API."
#endif
#if (configUSE_TASK_NOTIFICATIONS == 0)
/*
CMSIS-RTOS2 Thread Flags API functions use FreeRTOS Task Notification functions to implement
thread flag management. In case if these functions are not used in the application image,
compiler will optimize them away.
Set #define configUSE_TASK_NOTIFICATIONS 1 to fix this error.
Alternatively, if the application does not use thread flags functions they can be
excluded from the image code by setting:
#define configUSE_OS2_THREAD_FLAGS 0 (in FreeRTOSConfig.h)
*/
#if (configUSE_OS2_THREAD_FLAGS == 1)
#error "Definition configUSE_TASK_NOTIFICATIONS must equal 1 to implement Thread Flags API."
#endif
#endif
#if (configUSE_TRACE_FACILITY == 0)
/*
CMSIS-RTOS2 function osThreadEnumerate requires FreeRTOS function uxTaskGetSystemState
which is only enabled if configUSE_TRACE_FACILITY == 1.
Set #define configUSE_TRACE_FACILITY 1 to fix this error.
Alternatively, if the application does not use osThreadEnumerate it can be
excluded from the image code by setting:
#define configUSE_OS2_THREAD_ENUMERATE 0 (in FreeRTOSConfig.h)
*/
#if (configUSE_OS2_THREAD_ENUMERATE == 1)
#error "Definition configUSE_TRACE_FACILITY must equal 1 to implement osThreadEnumerate."
#endif
#endif
#if (configUSE_16_BIT_TICKS == 1)
/*
CMSIS-RTOS2 wrapper for FreeRTOS relies on 32-bit tick timer which is also optimal on
a 32-bit CPU architectures.
Set #define configUSE_16_BIT_TICKS 0 to fix this error.
*/
#error "Definition configUSE_16_BIT_TICKS must be zero to implement CMSIS-RTOS2 API."
#endif
#if (configMAX_PRIORITIES != 56)
/*
CMSIS-RTOS2 defines 56 different priorities (see osPriority_t) and portable CMSIS-RTOS2
implementation should implement the same number of priorities.
Set #define configMAX_PRIORITIES 56 to fix this error.
*/
#error "Definition configMAX_PRIORITIES must equal 56 to implement Thread Management API."
#endif
#if (configUSE_PORT_OPTIMISED_TASK_SELECTION != 0)
/*
CMSIS-RTOS2 requires handling of 56 different priorities (see osPriority_t) while FreeRTOS port
optimised selection for Cortex core only handles 32 different priorities.
Set #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 to fix this error.
*/
#error "Definition configUSE_PORT_OPTIMISED_TASK_SELECTION must be zero to implement Thread Management API."
#endif
#endif /* FREERTOS_OS2_H_ */
File diff suppressed because it is too large Load Diff
+14 -13
View File
@@ -1,18 +1,19 @@
Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in Permission is hereby granted, free of charge, to any person obtaining a copy
the Software without restriction, including without limitation the rights to of this software and associated documentation files (the "Software"), to deal
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of in the Software without restriction, including without limitation the rights
the Software, and to permit persons to whom the Software is furnished to do so, to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
subject to the following conditions: copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+242 -232
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#include "FreeRTOS.h" #include "FreeRTOS.h"
@@ -30,32 +31,32 @@
#include "croutine.h" #include "croutine.h"
/* Remove the whole file is co-routines are not being used. */ /* Remove the whole file is co-routines are not being used. */
#if( configUSE_CO_ROUTINES != 0 ) #if ( configUSE_CO_ROUTINES != 0 )
/* /*
* Some kernel aware debuggers require data to be viewed to be global, rather * Some kernel aware debuggers require data to be viewed to be global, rather
* than file scope. * than file scope.
*/ */
#ifdef portREMOVE_STATIC_QUALIFIER #ifdef portREMOVE_STATIC_QUALIFIER
#define static #define static
#endif #endif
/* Lists for ready and blocked co-routines. --------------------*/ /* Lists for ready and blocked co-routines. --------------------*/
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ static List_t * pxDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used. */
static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
/* Other file private variables. --------------------------------*/ /* Other file private variables. --------------------------------*/
CRCB_t * pxCurrentCoRoutine = NULL; CRCB_t * pxCurrentCoRoutine = NULL;
static UBaseType_t uxTopCoRoutineReadyPriority = 0; static UBaseType_t uxTopCoRoutineReadyPriority = 0;
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
/* The initial state of the co-routine when it is created. */ /* The initial state of the co-routine when it is created. */
#define corINITIAL_STATE ( 0 ) #define corINITIAL_STATE ( 0 )
/* /*
* Place the co-routine represented by pxCRCB into the appropriate ready queue * Place the co-routine represented by pxCRCB into the appropriate ready queue
@@ -64,20 +65,20 @@ static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
* This macro accesses the co-routine ready lists and therefore must not be * This macro accesses the co-routine ready lists and therefore must not be
* used from within an ISR. * used from within an ISR.
*/ */
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ #define prvAddCoRoutineToReadyQueue( pxCRCB ) \
{ \ do { \
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ if( ( pxCRCB )->uxPriority > uxTopCoRoutineReadyPriority ) \
{ \ { \
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ uxTopCoRoutineReadyPriority = ( pxCRCB )->uxPriority; \
} \ } \
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ ( pxCRCB )->uxPriority ] ), &( ( pxCRCB )->xGenericListItem ) ); \
} } while( 0 )
/* /*
* Utility to ready all the lists used by the scheduler. This is called * Utility to ready all the lists used by the scheduler. This is called
* automatically upon the creation of the first co-routine. * automatically upon the creation of the first co-routine.
*/ */
static void prvInitialiseCoRoutineLists( void ); static void prvInitialiseCoRoutineLists( void );
/* /*
* Co-routines that are readied by an interrupt cannot be placed directly into * Co-routines that are readied by an interrupt cannot be placed directly into
@@ -85,7 +86,7 @@ static void prvInitialiseCoRoutineLists( void );
* in the pending ready list in order that they can later be moved to the ready * in the pending ready list in order that they can later be moved to the ready
* list by the co-routine scheduler. * list by the co-routine scheduler.
*/ */
static void prvCheckPendingReadyList( void ); static void prvCheckPendingReadyList( void );
/* /*
* Macro that looks at the list of co-routines that are currently delayed to * Macro that looks at the list of co-routines that are currently delayed to
@@ -95,259 +96,268 @@ static void prvCheckPendingReadyList( void );
* meaning once one co-routine has been found whose timer has not expired * meaning once one co-routine has been found whose timer has not expired
* we need not look any further down the list. * we need not look any further down the list.
*/ */
static void prvCheckDelayedList( void ); static void prvCheckDelayedList( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
{ UBaseType_t uxPriority,
BaseType_t xReturn; UBaseType_t uxIndex )
CRCB_t *pxCoRoutine; {
BaseType_t xReturn;
CRCB_t * pxCoRoutine;
/* Allocate the memory that will store the co-routine control block. */ /* Allocate the memory that will store the co-routine control block. */
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
if( pxCoRoutine )
{
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
be created and the co-routine data structures need initialising. */
if( pxCurrentCoRoutine == NULL )
{
pxCurrentCoRoutine = pxCoRoutine;
prvInitialiseCoRoutineLists();
}
/* Check the priority is within limits. */ if( pxCoRoutine )
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) {
{ /* If pxCurrentCoRoutine is NULL then this is the first co-routine to
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; * be created and the co-routine data structures need initialising. */
} if( pxCurrentCoRoutine == NULL )
{
pxCurrentCoRoutine = pxCoRoutine;
prvInitialiseCoRoutineLists();
}
/* Fill out the co-routine control block from the function parameters. */ /* Check the priority is within limits. */
pxCoRoutine->uxState = corINITIAL_STATE; if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
pxCoRoutine->uxPriority = uxPriority; {
pxCoRoutine->uxIndex = uxIndex; uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; }
/* Initialise all the other co-routine control block parameters. */ /* Fill out the co-routine control block from the function parameters. */
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); pxCoRoutine->uxState = corINITIAL_STATE;
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); pxCoRoutine->uxPriority = uxPriority;
pxCoRoutine->uxIndex = uxIndex;
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
/* Set the co-routine control block as a link back from the ListItem_t. /* Initialise all the other co-routine control block parameters. */
This is so we can get back to the containing CRCB from a generic item vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
in a list. */ vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
/* Event lists are always in priority order. */ /* Set the co-routine control block as a link back from the ListItem_t.
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); * This is so we can get back to the containing CRCB from a generic item
* in a list. */
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
/* Now the co-routine has been initialised it can be added to the ready /* Event lists are always in priority order. */
list at the correct priority. */ listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
prvAddCoRoutineToReadyQueue( pxCoRoutine );
xReturn = pdPASS; /* Now the co-routine has been initialised it can be added to the ready
} * list at the correct priority. */
else prvAddCoRoutineToReadyQueue( pxCoRoutine );
{
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
return xReturn; xReturn = pdPASS;
} }
else
{
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
return xReturn;
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
{ List_t * pxEventList )
TickType_t xTimeToWake; {
TickType_t xTimeToWake;
/* Calculate the time to wake - this may overflow but this is /* Calculate the time to wake - this may overflow but this is
not a problem. */ * not a problem. */
xTimeToWake = xCoRoutineTickCount + xTicksToDelay; xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
/* We must remove ourselves from the ready list before adding /* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for * ourselves to the blocked list as the same list item is used for
both lists. */ * both lists. */
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
/* The list item will be inserted in wake time order. */ /* The list item will be inserted in wake time order. */
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xCoRoutineTickCount ) if( xTimeToWake < xCoRoutineTickCount )
{ {
/* Wake time has overflowed. Place this item in the /* Wake time has overflowed. Place this item in the
overflow list. */ * overflow list. */
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
} }
else else
{ {
/* The wake time has not overflowed, so we can use the /* The wake time has not overflowed, so we can use the
current block list. */ * current block list. */
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
} }
if( pxEventList ) if( pxEventList )
{ {
/* Also add the co-routine to an event list. If this is done then the /* Also add the co-routine to an event list. If this is done then the
function must be called with interrupts disabled. */ * function must be called with interrupts disabled. */
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckPendingReadyList( void ) static void prvCheckPendingReadyList( void )
{ {
/* Are there any co-routines waiting to get moved to the ready list? These /* Are there any co-routines waiting to get moved to the ready list? These
are co-routines that have been readied by an ISR. The ISR cannot access * are co-routines that have been readied by an ISR. The ISR cannot access
the ready lists itself. */ * the ready lists itself. */
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
{ {
CRCB_t *pxUnblockedCRCB; CRCB_t * pxUnblockedCRCB;
/* The pending ready list can be accessed by an ISR. */ /* The pending ready list can be accessed by an ISR. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
{ {
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyCoRoutineList ) );
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckDelayedList( void ) static void prvCheckDelayedList( void )
{ {
CRCB_t *pxCRCB; CRCB_t * pxCRCB;
xPassedTicks = xTaskGetTickCount() - xLastTickCount; xPassedTicks = xTaskGetTickCount() - xLastTickCount;
while( xPassedTicks )
{
xCoRoutineTickCount++;
xPassedTicks--;
/* If the tick count has overflowed we need to swap the ready lists. */ while( xPassedTicks )
if( xCoRoutineTickCount == 0 ) {
{ xCoRoutineTickCount++;
List_t * pxTemp; xPassedTicks--;
/* Tick count has overflowed so we need to swap the delay lists. If there are /* If the tick count has overflowed we need to swap the ready lists. */
any items in pxDelayedCoRoutineList here then there is an error! */ if( xCoRoutineTickCount == 0 )
pxTemp = pxDelayedCoRoutineList; {
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; List_t * pxTemp;
pxOverflowDelayedCoRoutineList = pxTemp;
}
/* See if this tick has made a timeout expire. */ /* Tick count has overflowed so we need to swap the delay lists. If there are
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) * any items in pxDelayedCoRoutineList here then there is an error! */
{ pxTemp = pxDelayedCoRoutineList;
pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
pxOverflowDelayedCoRoutineList = pxTemp;
}
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) /* See if this tick has made a timeout expire. */
{ while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
/* Timeout not yet expired. */ {
break; pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
}
portDISABLE_INTERRUPTS(); if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
{ {
/* The event could have occurred just before this critical /* Timeout not yet expired. */
section. If this is the case then the generic list item will break;
have been moved to the pending ready list and the following }
line is still valid. Also the pvContainer parameter will have
been set to NULL so the following lines are also valid. */
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
/* Is the co-routine waiting on an event also? */ portDISABLE_INTERRUPTS();
if( pxCRCB->xEventListItem.pxContainer ) {
{ /* The event could have occurred just before this critical
( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); * section. If this is the case then the generic list item will
} * have been moved to the pending ready list and the following
} * line is still valid. Also the pvContainer parameter will have
portENABLE_INTERRUPTS(); * been set to NULL so the following lines are also valid. */
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
prvAddCoRoutineToReadyQueue( pxCRCB ); /* Is the co-routine waiting on an event also? */
} if( pxCRCB->xEventListItem.pxContainer )
} {
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
}
}
portENABLE_INTERRUPTS();
xLastTickCount = xCoRoutineTickCount; prvAddCoRoutineToReadyQueue( pxCRCB );
} }
}
xLastTickCount = xCoRoutineTickCount;
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vCoRoutineSchedule( void ) void vCoRoutineSchedule( void )
{ {
/* See if any co-routines readied by events need moving to the ready lists. */ /* Only run a co-routine after prvInitialiseCoRoutineLists() has been
prvCheckPendingReadyList(); * called. prvInitialiseCoRoutineLists() is called automatically when a
* co-routine is created. */
if( pxDelayedCoRoutineList != NULL )
{
/* See if any co-routines readied by events need moving to the ready lists. */
prvCheckPendingReadyList();
/* See if any delayed co-routines have timed out. */ /* See if any delayed co-routines have timed out. */
prvCheckDelayedList(); prvCheckDelayedList();
/* Find the highest priority queue that contains ready co-routines. */ /* Find the highest priority queue that contains ready co-routines. */
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
{ {
if( uxTopCoRoutineReadyPriority == 0 ) if( uxTopCoRoutineReadyPriority == 0 )
{ {
/* No more co-routines to check. */ /* No more co-routines to check. */
return; return;
} }
--uxTopCoRoutineReadyPriority;
}
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines --uxTopCoRoutineReadyPriority;
of the same priority get an equal share of the processor time. */ }
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
/* Call the co-routine. */ /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); * of the same priority get an equal share of the processor time. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
return; /* Call the co-routine. */
} ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
}
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvInitialiseCoRoutineLists( void ) static void prvInitialiseCoRoutineLists( void )
{ {
UBaseType_t uxPriority; UBaseType_t uxPriority;
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
{ {
vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
} }
vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
/* Start with pxDelayedCoRoutineList using list1 and the /* Start with pxDelayedCoRoutineList using list1 and the
pxOverflowDelayedCoRoutineList using list2. */ * pxOverflowDelayedCoRoutineList using list2. */
pxDelayedCoRoutineList = &xDelayedCoRoutineList1; pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList )
{ {
CRCB_t *pxUnblockedCRCB; CRCB_t * pxUnblockedCRCB;
BaseType_t xReturn; BaseType_t xReturn;
/* This function is called from within an interrupt. It can only access /* This function is called from within an interrupt. It can only access
event lists and the pending ready list. This function assumes that a * event lists and the pending ready list. This function assumes that a
check has already been made to ensure pxEventList is not empty. */ * check has already been made to ensure pxEventList is not empty. */
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
{ {
xReturn = pdTRUE; xReturn = pdTRUE;
} }
else else
{ {
xReturn = pdFALSE; xReturn = pdFALSE;
} }
return xReturn; return xReturn;
} }
#endif /* configUSE_CO_ROUTINES == 0 */ #endif /* configUSE_CO_ROUTINES == 0 */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,162 +0,0 @@
/*
* FreeRTOS Kernel V10.2.1
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* this is a template configuration files
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* These parameters and more are described within the 'configuration' section of the
* FreeRTOS API documentation available on the FreeRTOS.org web site.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
/* CMSIS-RTOSv2 defines 56 levels of priorities. To be able to use them
* all and avoid application misbehavior, configUSE_PORT_OPTIMISED_TASK_SELECTION
* must be set to 0 and configMAX_PRIORITIES to 56
*
*/
/* #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0*/
/* #define configMAX_PRIORITIES ( 56 ) */
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configMAX_PRIORITIES (7)
#define configSUPPORT_STATIC_ALLOCATION 0
#define configCPU_CLOCK_HZ (SystemCoreClock)
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)(15 * 1024))
#define configMAX_TASK_NAME_LEN (16)
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES (2)
/* Software timer definitions. */
#define configUSE_TIMERS 0
#define configTIMER_TASK_PRIORITY (2)
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 0
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
/*------------- CMSIS-RTOS V2 specific defines -----------*/
/* When using CMSIS-RTOSv2 set configSUPPORT_STATIC_ALLOCATION to 1
* is mandatory to avoid compile errors.
* CMSIS-RTOS V2 implmentation requires the following defines
*
#define configSUPPORT_STATIC_ALLOCATION 1 <-- cmsis_os threads are created using xTaskCreateStatic() API
#define configMAX_PRIORITIES (56) <-- Priority range in CMSIS-RTOS V2 is [0 .. 56]
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 <-- when set to 1, configMAX_PRIORITIES can't be more than 32 which is not suitable for the new CMSIS-RTOS v2 priority range
*/
/* the CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
* by the application thus the correct define need to be enabled from the list
* below
*
//define USE_FreeRTOS_HEAP_1
//define USE_FreeRTOS_HEAP_2
//define USE_FreeRTOS_HEAP_3
//define USE_FreeRTOS_HEAP_4
//define USE_FreeRTOS_HEAP_5
*/
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4 /* 15 priority levels */
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
/* IMPORTANT: FreeRTOS is using the SysTick as internal time base, thus make sure the system and peripherials are
using a different time base (TIM based for example).
*/
#define xPortSysTickHandler SysTick_Handler
#endif /* FREERTOS_CONFIG_H */
+8 -107
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,115 +21,14 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#ifndef STACK_MACROS_H
#define STACK_MACROS_H
#ifndef _MSC_VER /* Visual Studio doesn't support #warning. */ #ifndef _MSC_VER /* Visual Studio doesn't support #warning. */
#warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in future released. #warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in a future release.
#endif #endif
/* #include "stack_macros.h"
* Call the stack overflow hook function if the stack of the task being swapped
* out is currently overflowed, or looks like it might have overflowed in the
* past.
*
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
* the current stack state only - comparing the current top of stack value to
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
* will also cause the last few stack bytes to be checked to ensure the value
* to which the bytes were set when the task was created have not been
* overwritten. Note this second test does not guarantee that an overflowed
* stack will always be recognised.
*/
/*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
/* Only the current stack state is to be checked. */
#define taskCHECK_FOR_STACK_OVERFLOW() \
{ \
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
{ \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
/*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
/* Only the current stack state is to be checked. */
#define taskCHECK_FOR_STACK_OVERFLOW() \
{ \
\
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
{ \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
/*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \
{ \
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
\
if( ( pulStack[ 0 ] != ulCheckValue ) || \
( pulStack[ 1 ] != ulCheckValue ) || \
( pulStack[ 2 ] != ulCheckValue ) || \
( pulStack[ 3 ] != ulCheckValue ) ) \
{ \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \
{ \
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
\
\
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
\
/* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/
/* Remove stack overflow macro if not being used. */
#ifndef taskCHECK_FOR_STACK_OVERFLOW
#define taskCHECK_FOR_STACK_OVERFLOW()
#endif
#endif /* STACK_MACROS_H */
+133 -128
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/** /**
@@ -38,15 +39,17 @@
#define ATOMIC_H #define ATOMIC_H
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include atomic.h" #error "include FreeRTOS.h must appear in source files before include atomic.h"
#endif #endif
/* Standard includes. */ /* Standard includes. */
#include <stdint.h> #include <stdint.h>
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/* /*
* Port specific definitions -- entering/exiting critical section. * Port specific definitions -- entering/exiting critical section.
@@ -58,18 +61,18 @@ extern "C" {
*/ */
#if defined( portSET_INTERRUPT_MASK_FROM_ISR ) #if defined( portSET_INTERRUPT_MASK_FROM_ISR )
/* Nested interrupt scheme is supported in this port. */ /* Nested interrupt scheme is supported in this port. */
#define ATOMIC_ENTER_CRITICAL() \ #define ATOMIC_ENTER_CRITICAL() \
UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR() UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
#define ATOMIC_EXIT_CRITICAL() \ #define ATOMIC_EXIT_CRITICAL() \
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType ) portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
#else #else
/* Nested interrupt scheme is NOT supported in this port. */ /* Nested interrupt scheme is NOT supported in this port. */
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL() #define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL() #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */ #endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
@@ -81,11 +84,11 @@ extern "C" {
* instead of resulting error, simply define it away. * instead of resulting error, simply define it away.
*/ */
#ifndef portFORCE_INLINE #ifndef portFORCE_INLINE
#define portFORCE_INLINE #define portFORCE_INLINE
#endif #endif
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */ #define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */
#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */ #define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */
/*----------------------------- Swap && CAS ------------------------------*/ /*----------------------------- Swap && CAS ------------------------------*/
@@ -105,26 +108,26 @@ extern "C" {
* *pulDestination value equals ulComparand. * *pulDestination value equals ulComparand.
*/ */
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
uint32_t ulExchange, uint32_t ulExchange,
uint32_t ulComparand ) uint32_t ulComparand )
{ {
uint32_t ulReturnValue; uint32_t ulReturnValue;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
if( *pulDestination == ulComparand ) if( *pulDestination == ulComparand )
{ {
*pulDestination = ulExchange; *pulDestination = ulExchange;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
} }
else else
{ {
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
} }
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulReturnValue; return ulReturnValue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -141,18 +144,18 @@ uint32_t ulReturnValue;
* @return The initial value of *ppvDestination. * @return The initial value of *ppvDestination.
*/ */
static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination, static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
void * pvExchange ) void * pvExchange )
{ {
void * pReturnValue; void * pReturnValue;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
pReturnValue = *ppvDestination; pReturnValue = *ppvDestination;
*ppvDestination = pvExchange; *ppvDestination = pvExchange;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return pReturnValue; return pReturnValue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -173,22 +176,22 @@ void * pReturnValue;
* *ppvDestination value equals pvComparand. * *ppvDestination value equals pvComparand.
*/ */
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination, static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
void * pvExchange, void * pvExchange,
void * pvComparand ) void * pvComparand )
{ {
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
if( *ppvDestination == pvComparand ) if( *ppvDestination == pvComparand )
{ {
*ppvDestination = pvExchange; *ppvDestination = pvExchange;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
} }
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulReturnValue; return ulReturnValue;
} }
@@ -206,18 +209,18 @@ uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
* @return previous *pulAddend value. * @return previous *pulAddend value.
*/ */
static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend, static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
uint32_t ulCount ) uint32_t ulCount )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulAddend; ulCurrent = *pulAddend;
*pulAddend += ulCount; *pulAddend += ulCount;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -234,18 +237,18 @@ static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
* @return previous *pulAddend value. * @return previous *pulAddend value.
*/ */
static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend, static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
uint32_t ulCount ) uint32_t ulCount )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulAddend; ulCurrent = *pulAddend;
*pulAddend -= ulCount; *pulAddend -= ulCount;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -261,16 +264,16 @@ static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAdd
*/ */
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend ) static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulAddend; ulCurrent = *pulAddend;
*pulAddend += 1; *pulAddend += 1;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -286,16 +289,16 @@ uint32_t ulCurrent;
*/ */
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend ) static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulAddend; ulCurrent = *pulAddend;
*pulAddend -= 1; *pulAddend -= 1;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*----------------------------- Bitwise Logical ------------------------------*/ /*----------------------------- Bitwise Logical ------------------------------*/
@@ -312,18 +315,18 @@ uint32_t ulCurrent;
* @return The original value of *pulDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
uint32_t ulValue ) uint32_t ulValue )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulDestination; ulCurrent = *pulDestination;
*pulDestination |= ulValue; *pulDestination |= ulValue;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -339,18 +342,18 @@ uint32_t ulCurrent;
* @return The original value of *pulDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
uint32_t ulValue ) uint32_t ulValue )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulDestination; ulCurrent = *pulDestination;
*pulDestination &= ulValue; *pulDestination &= ulValue;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -366,18 +369,18 @@ uint32_t ulCurrent;
* @return The original value of *pulDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
uint32_t ulValue ) uint32_t ulValue )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulDestination; ulCurrent = *pulDestination;
*pulDestination = ~( ulCurrent & ulValue ); *pulDestination = ~( ulCurrent & ulValue );
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -393,22 +396,24 @@ uint32_t ulCurrent;
* @return The original value of *pulDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
uint32_t ulValue ) uint32_t ulValue )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulDestination; ulCurrent = *pulDestination;
*pulDestination ^= ulValue; *pulDestination ^= ulValue;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */
#endif /* ATOMIC_H */ #endif /* ATOMIC_H */
+430 -395
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,51 +21,54 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#ifndef CO_ROUTINE_H #ifndef CO_ROUTINE_H
#define CO_ROUTINE_H #define CO_ROUTINE_H
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include croutine.h" #error "include FreeRTOS.h must appear in source files before include croutine.h"
#endif #endif
#include "list.h" #include "list.h"
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/* Used to hide the implementation of the co-routine control block. The /* Used to hide the implementation of the co-routine control block. The
control block structure however has to be included in the header due to * control block structure however has to be included in the header due to
the macro implementation of the co-routine functionality. */ * the macro implementation of the co-routine functionality. */
typedef void * CoRoutineHandle_t; typedef void * CoRoutineHandle_t;
/* Defines the prototype to which co-routine functions must conform. */ /* Defines the prototype to which co-routine functions must conform. */
typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t,
UBaseType_t );
typedef struct corCoRoutineControlBlock typedef struct corCoRoutineControlBlock
{ {
crCOROUTINE_CODE pxCoRoutineFunction; crCOROUTINE_CODE pxCoRoutineFunction;
ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ ListItem_t xGenericListItem; /**< List item used to place the CRCB in ready and blocked queues. */
ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ ListItem_t xEventListItem; /**< List item used to place the CRCB in event lists. */
UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ UBaseType_t uxPriority; /**< The priority of the co-routine in relation to other co-routines. */
UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ UBaseType_t uxIndex; /**< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
uint16_t uxState; /*< Used internally by the co-routine implementation. */ uint16_t uxState; /**< Used internally by the co-routine implementation. */
} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ } CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */
/** /**
* croutine. h * croutine. h
*<pre> * @code{c}
BaseType_t xCoRoutineCreate( * BaseType_t xCoRoutineCreate(
crCOROUTINE_CODE pxCoRoutineCode, * crCOROUTINE_CODE pxCoRoutineCode,
UBaseType_t uxPriority, * UBaseType_t uxPriority,
UBaseType_t uxIndex * UBaseType_t uxIndex
);</pre> * );
* @endcode
* *
* Create a new co-routine and add it to the list of co-routines that are * Create a new co-routine and add it to the list of co-routines that are
* ready to run. * ready to run.
@@ -83,58 +88,61 @@ typedef struct corCoRoutineControlBlock
* list, otherwise an error code defined with ProjDefs.h. * list, otherwise an error code defined with ProjDefs.h.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// Co-routine to be created. * // Co-routine to be created.
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
// This may not be necessary for const variables. * // This may not be necessary for const variables.
static const char cLedToFlash[ 2 ] = { 5, 6 }; * static const char cLedToFlash[ 2 ] = { 5, 6 };
static const TickType_t uxFlashRates[ 2 ] = { 200, 400 }; * static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
*
// Must start every co-routine with a call to crSTART(); * // Must start every co-routine with a call to crSTART();
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// This co-routine just delays for a fixed period, then toggles * // This co-routine just delays for a fixed period, then toggles
// an LED. Two co-routines are created using this function, so * // an LED. Two co-routines are created using this function, so
// the uxIndex parameter is used to tell the co-routine which * // the uxIndex parameter is used to tell the co-routine which
// LED to flash and how int32_t to delay. This assumes xQueue has * // LED to flash and how int32_t to delay. This assumes xQueue has
// already been created. * // already been created.
vParTestToggleLED( cLedToFlash[ uxIndex ] ); * vParTestToggleLED( cLedToFlash[ uxIndex ] );
crDELAY( xHandle, uxFlashRates[ uxIndex ] ); * crDELAY( xHandle, uxFlashRates[ uxIndex ] );
} * }
*
// Must end every co-routine with a call to crEND(); * // Must end every co-routine with a call to crEND();
crEND(); * crEND();
} * }
*
// Function that creates two co-routines. * // Function that creates two co-routines.
void vOtherFunction( void ) * void vOtherFunction( void )
{ * {
uint8_t ucParameterToPass; * uint8_t ucParameterToPass;
TaskHandle_t xHandle; * TaskHandle_t xHandle;
*
// Create two co-routines at priority 0. The first is given index 0 * // Create two co-routines at priority 0. The first is given index 0
// so (from the code above) toggles LED 5 every 200 ticks. The second * // so (from the code above) toggles LED 5 every 200 ticks. The second
// is given index 1 so toggles LED 6 every 400 ticks. * // is given index 1 so toggles LED 6 every 400 ticks.
for( uxIndex = 0; uxIndex < 2; uxIndex++ ) * for( uxIndex = 0; uxIndex < 2; uxIndex++ )
{ * {
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex ); * xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
} * }
} * }
</pre> * @endcode
* \defgroup xCoRoutineCreate xCoRoutineCreate * \defgroup xCoRoutineCreate xCoRoutineCreate
* \ingroup Tasks * \ingroup Tasks
*/ */
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
UBaseType_t uxPriority,
UBaseType_t uxIndex );
/** /**
* croutine. h * croutine. h
*<pre> * @code{c}
void vCoRoutineSchedule( void );</pre> * void vCoRoutineSchedule( void );
* @endcode
* *
* Run a co-routine. * Run a co-routine.
* *
@@ -148,25 +156,25 @@ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPri
* hook). * hook).
* *
* Example usage: * Example usage:
<pre> * @code{c}
// This idle task hook will schedule a co-routine each time it is called. * // This idle task hook will schedule a co-routine each time it is called.
// The rest of the idle task will execute between co-routine calls. * // The rest of the idle task will execute between co-routine calls.
void vApplicationIdleHook( void ) * void vApplicationIdleHook( void )
{ * {
vCoRoutineSchedule(); * vCoRoutineSchedule();
} * }
*
// Alternatively, if you do not require any other part of the idle task to * // Alternatively, if you do not require any other part of the idle task to
// execute, the idle task hook can call vCoRoutineSchedule() within an * // execute, the idle task hook can call vCoRoutineSchedule() within an
// infinite loop. * // infinite loop.
void vApplicationIdleHook( void ) * void vApplicationIdleHook( void )
{ * {
for( ;; ) * for( ;; )
{ * {
vCoRoutineSchedule(); * vCoRoutineSchedule();
} * }
} * }
</pre> * @endcode
* \defgroup vCoRoutineSchedule vCoRoutineSchedule * \defgroup vCoRoutineSchedule vCoRoutineSchedule
* \ingroup Tasks * \ingroup Tasks
*/ */
@@ -174,77 +182,88 @@ void vCoRoutineSchedule( void );
/** /**
* croutine. h * croutine. h
* <pre> * @code{c}
crSTART( CoRoutineHandle_t xHandle );</pre> * crSTART( CoRoutineHandle_t xHandle );
* @endcode
* *
* This macro MUST always be called at the start of a co-routine function. * This macro MUST always be called at the start of a co-routine function.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// Co-routine to be created. * // Co-routine to be created.
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
static int32_t ulAVariable; * static int32_t ulAVariable;
*
// Must start every co-routine with a call to crSTART(); * // Must start every co-routine with a call to crSTART();
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Co-routine functionality goes here. * // Co-routine functionality goes here.
} * }
*
// Must end every co-routine with a call to crEND(); * // Must end every co-routine with a call to crEND();
crEND(); * crEND();
}</pre> * }
* @endcode
* \defgroup crSTART crSTART * \defgroup crSTART crSTART
* \ingroup Tasks * \ingroup Tasks
*/ */
#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: #define crSTART( pxCRCB ) \
switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \
case 0:
/** /**
* croutine. h * croutine. h
* <pre> * @code{c}
crEND();</pre> * crEND();
* @endcode
* *
* This macro MUST always be called at the end of a co-routine function. * This macro MUST always be called at the end of a co-routine function.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// Co-routine to be created. * // Co-routine to be created.
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
static int32_t ulAVariable; * static int32_t ulAVariable;
*
// Must start every co-routine with a call to crSTART(); * // Must start every co-routine with a call to crSTART();
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Co-routine functionality goes here. * // Co-routine functionality goes here.
} * }
*
// Must end every co-routine with a call to crEND(); * // Must end every co-routine with a call to crEND();
crEND(); * crEND();
}</pre> * }
* @endcode
* \defgroup crSTART crSTART * \defgroup crSTART crSTART
* \ingroup Tasks * \ingroup Tasks
*/ */
#define crEND() } #define crEND() }
/* /*
* These macros are intended for internal use by the co-routine implementation * These macros are intended for internal use by the co-routine implementation
* only. The macros should not be used directly by application writers. * only. The macros should not be used directly by application writers.
*/ */
#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): #define crSET_STATE0( xHandle ) \
#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): ( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \
case ( __LINE__ * 2 ):
#define crSET_STATE1( xHandle ) \
( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \
case ( ( __LINE__ * 2 ) + 1 ):
/** /**
* croutine. h * croutine. h
*<pre> * @code{c}
crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre> * crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
* @endcode
* *
* Delay a co-routine for a fixed period of time. * Delay a co-routine for a fixed period of time.
* *
@@ -261,48 +280,52 @@ void vCoRoutineSchedule( void );
* can be used to convert ticks to milliseconds. * can be used to convert ticks to milliseconds.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// Co-routine to be created. * // Co-routine to be created.
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
// This may not be necessary for const variables. * // This may not be necessary for const variables.
// We are to delay for 200ms. * // We are to delay for 200ms.
static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS; * static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
*
// Must start every co-routine with a call to crSTART(); * // Must start every co-routine with a call to crSTART();
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Delay for 200ms. * // Delay for 200ms.
crDELAY( xHandle, xDelayTime ); * crDELAY( xHandle, xDelayTime );
*
// Do something here. * // Do something here.
} * }
*
// Must end every co-routine with a call to crEND(); * // Must end every co-routine with a call to crEND();
crEND(); * crEND();
}</pre> * }
* @endcode
* \defgroup crDELAY crDELAY * \defgroup crDELAY crDELAY
* \ingroup Tasks * \ingroup Tasks
*/ */
#define crDELAY( xHandle, xTicksToDelay ) \ #define crDELAY( xHandle, xTicksToDelay ) \
if( ( xTicksToDelay ) > 0 ) \ do { \
{ \ if( ( xTicksToDelay ) > 0 ) \
vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ { \
} \ vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
crSET_STATE0( ( xHandle ) ); } \
crSET_STATE0( ( xHandle ) ); \
} while( 0 )
/** /**
* <pre> * @code{c}
crQUEUE_SEND( * crQUEUE_SEND(
CoRoutineHandle_t xHandle, * CoRoutineHandle_t xHandle,
QueueHandle_t pxQueue, * QueueHandle_t pxQueue,
void *pvItemToQueue, * void *pvItemToQueue,
TickType_t xTicksToWait, * TickType_t xTicksToWait,
BaseType_t *pxResult * BaseType_t *pxResult
)</pre> * )
* @endcode
* *
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
@@ -342,66 +365,68 @@ void vCoRoutineSchedule( void );
* error defined within ProjDefs.h. * error defined within ProjDefs.h.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// Co-routine function that blocks for a fixed period then posts a number onto * // Co-routine function that blocks for a fixed period then posts a number onto
// a queue. * // a queue.
static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
static BaseType_t xNumberToPost = 0; * static BaseType_t xNumberToPost = 0;
static BaseType_t xResult; * static BaseType_t xResult;
*
// Co-routines must begin with a call to crSTART(). * // Co-routines must begin with a call to crSTART().
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// This assumes the queue has already been created. * // This assumes the queue has already been created.
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult ); * crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
*
if( xResult != pdPASS ) * if( xResult != pdPASS )
{ * {
// The message was not posted! * // The message was not posted!
} * }
*
// Increment the number to be posted onto the queue. * // Increment the number to be posted onto the queue.
xNumberToPost++; * xNumberToPost++;
*
// Delay for 100 ticks. * // Delay for 100 ticks.
crDELAY( xHandle, 100 ); * crDELAY( xHandle, 100 );
} * }
*
// Co-routines must end with a call to crEND(). * // Co-routines must end with a call to crEND().
crEND(); * crEND();
}</pre> * }
* @endcode
* \defgroup crQUEUE_SEND crQUEUE_SEND * \defgroup crQUEUE_SEND crQUEUE_SEND
* \ingroup Tasks * \ingroup Tasks
*/ */
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ #define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
{ \ do { \
*( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ *( pxResult ) = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), ( xTicksToWait ) ); \
if( *( pxResult ) == errQUEUE_BLOCKED ) \ if( *( pxResult ) == errQUEUE_BLOCKED ) \
{ \ { \
crSET_STATE0( ( xHandle ) ); \ crSET_STATE0( ( xHandle ) ); \
*pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \
} \ } \
if( *pxResult == errQUEUE_YIELD ) \ if( *pxResult == errQUEUE_YIELD ) \
{ \ { \
crSET_STATE1( ( xHandle ) ); \ crSET_STATE1( ( xHandle ) ); \
*pxResult = pdPASS; \ *pxResult = pdPASS; \
} \ } \
} } while( 0 )
/** /**
* croutine. h * croutine. h
* <pre> * @code{c}
crQUEUE_RECEIVE( * crQUEUE_RECEIVE(
CoRoutineHandle_t xHandle, * CoRoutineHandle_t xHandle,
QueueHandle_t pxQueue, * QueueHandle_t pxQueue,
void *pvBuffer, * void *pvBuffer,
TickType_t xTicksToWait, * TickType_t xTicksToWait,
BaseType_t *pxResult * BaseType_t *pxResult
)</pre> * )
* @endcode
* *
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
@@ -440,58 +465,60 @@ void vCoRoutineSchedule( void );
* an error code as defined within ProjDefs.h. * an error code as defined within ProjDefs.h.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// A co-routine receives the number of an LED to flash from a queue. It * // A co-routine receives the number of an LED to flash from a queue. It
// blocks on the queue until the number is received. * // blocks on the queue until the number is received.
static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
static BaseType_t xResult; * static BaseType_t xResult;
static UBaseType_t uxLEDToFlash; * static UBaseType_t uxLEDToFlash;
*
// All co-routines must start with a call to crSTART(). * // All co-routines must start with a call to crSTART().
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Wait for data to become available on the queue. * // Wait for data to become available on the queue.
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); * crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
*
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// We received the LED to flash - flash it! * // We received the LED to flash - flash it!
vParTestToggleLED( uxLEDToFlash ); * vParTestToggleLED( uxLEDToFlash );
} * }
} * }
*
crEND(); * crEND();
}</pre> * }
* @endcode
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
* \ingroup Tasks * \ingroup Tasks
*/ */
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ #define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
{ \ do { \
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), ( xTicksToWait ) ); \
if( *( pxResult ) == errQUEUE_BLOCKED ) \ if( *( pxResult ) == errQUEUE_BLOCKED ) \
{ \ { \
crSET_STATE0( ( xHandle ) ); \ crSET_STATE0( ( xHandle ) ); \
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), 0 ); \
} \ } \
if( *( pxResult ) == errQUEUE_YIELD ) \ if( *( pxResult ) == errQUEUE_YIELD ) \
{ \ { \
crSET_STATE1( ( xHandle ) ); \ crSET_STATE1( ( xHandle ) ); \
*( pxResult ) = pdPASS; \ *( pxResult ) = pdPASS; \
} \ } \
} } while( 0 )
/** /**
* croutine. h * croutine. h
* <pre> * @code{c}
crQUEUE_SEND_FROM_ISR( * crQUEUE_SEND_FROM_ISR(
QueueHandle_t pxQueue, * QueueHandle_t pxQueue,
void *pvItemToQueue, * void *pvItemToQueue,
BaseType_t xCoRoutinePreviouslyWoken * BaseType_t xCoRoutinePreviouslyWoken
)</pre> * )
* @endcode
* *
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
@@ -526,69 +553,72 @@ void vCoRoutineSchedule( void );
* the ISR. * the ISR.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// A co-routine that blocks on a queue waiting for characters to be received. * // A co-routine that blocks on a queue waiting for characters to be received.
static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
char cRxedChar; * char cRxedChar;
BaseType_t xResult; * BaseType_t xResult;
*
// All co-routines must start with a call to crSTART(). * // All co-routines must start with a call to crSTART().
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Wait for data to become available on the queue. This assumes the * // Wait for data to become available on the queue. This assumes the
// queue xCommsRxQueue has already been created! * // queue xCommsRxQueue has already been created!
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); * crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
*
// Was a character received? * // Was a character received?
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// Process the character here. * // Process the character here.
} * }
} * }
*
// All co-routines must end with a call to crEND(). * // All co-routines must end with a call to crEND().
crEND(); * crEND();
} * }
*
// An ISR that uses a queue to send characters received on a serial port to * // An ISR that uses a queue to send characters received on a serial port to
// a co-routine. * // a co-routine.
void vUART_ISR( void ) * void vUART_ISR( void )
{ * {
char cRxedChar; * char cRxedChar;
BaseType_t xCRWokenByPost = pdFALSE; * BaseType_t xCRWokenByPost = pdFALSE;
*
// We loop around reading characters until there are none left in the UART. * // We loop around reading characters until there are none left in the UART.
while( UART_RX_REG_NOT_EMPTY() ) * while( UART_RX_REG_NOT_EMPTY() )
{ * {
// Obtain the character from the UART. * // Obtain the character from the UART.
cRxedChar = UART_RX_REG; * cRxedChar = UART_RX_REG;
*
// Post the character onto a queue. xCRWokenByPost will be pdFALSE * // Post the character onto a queue. xCRWokenByPost will be pdFALSE
// the first time around the loop. If the post causes a co-routine * // the first time around the loop. If the post causes a co-routine
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE. * // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
// In this manner we can ensure that if more than one co-routine is * // In this manner we can ensure that if more than one co-routine is
// blocked on the queue only one is woken by this ISR no matter how * // blocked on the queue only one is woken by this ISR no matter how
// many characters are posted to the queue. * // many characters are posted to the queue.
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost ); * xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
} * }
}</pre> * }
* @endcode
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
* \ingroup Tasks * \ingroup Tasks
*/ */
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) #define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) \
xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
/** /**
* croutine. h * croutine. h
* <pre> * @code{c}
crQUEUE_SEND_FROM_ISR( * crQUEUE_SEND_FROM_ISR(
QueueHandle_t pxQueue, * QueueHandle_t pxQueue,
void *pvBuffer, * void *pvBuffer,
BaseType_t * pxCoRoutineWoken * BaseType_t * pxCoRoutineWoken
)</pre> * )
* @endcode
* *
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
@@ -623,75 +653,77 @@ void vCoRoutineSchedule( void );
* pdFALSE. * pdFALSE.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// A co-routine that posts a character to a queue then blocks for a fixed * // A co-routine that posts a character to a queue then blocks for a fixed
// period. The character is incremented each time. * // period. The character is incremented each time.
static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// cChar holds its value while this co-routine is blocked and must therefore * // cChar holds its value while this co-routine is blocked and must therefore
// be declared static. * // be declared static.
static char cCharToTx = 'a'; * static char cCharToTx = 'a';
BaseType_t xResult; * BaseType_t xResult;
*
// All co-routines must start with a call to crSTART(). * // All co-routines must start with a call to crSTART().
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Send the next character to the queue. * // Send the next character to the queue.
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult ); * crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
*
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// The character was successfully posted to the queue. * // The character was successfully posted to the queue.
} * }
else * else
{ * {
// Could not post the character to the queue. * // Could not post the character to the queue.
} * }
*
// Enable the UART Tx interrupt to cause an interrupt in this * // Enable the UART Tx interrupt to cause an interrupt in this
// hypothetical UART. The interrupt will obtain the character * // hypothetical UART. The interrupt will obtain the character
// from the queue and send it. * // from the queue and send it.
ENABLE_RX_INTERRUPT(); * ENABLE_RX_INTERRUPT();
*
// Increment to the next character then block for a fixed period. * // Increment to the next character then block for a fixed period.
// cCharToTx will maintain its value across the delay as it is * // cCharToTx will maintain its value across the delay as it is
// declared static. * // declared static.
cCharToTx++; * cCharToTx++;
if( cCharToTx > 'x' ) * if( cCharToTx > 'x' )
{ * {
cCharToTx = 'a'; * cCharToTx = 'a';
} * }
crDELAY( 100 ); * crDELAY( 100 );
} * }
*
// All co-routines must end with a call to crEND(). * // All co-routines must end with a call to crEND().
crEND(); * crEND();
} * }
*
// An ISR that uses a queue to receive characters to send on a UART. * // An ISR that uses a queue to receive characters to send on a UART.
void vUART_ISR( void ) * void vUART_ISR( void )
{ * {
char cCharToTx; * char cCharToTx;
BaseType_t xCRWokenByPost = pdFALSE; * BaseType_t xCRWokenByPost = pdFALSE;
*
while( UART_TX_REG_EMPTY() ) * while( UART_TX_REG_EMPTY() )
{ * {
// Are there any characters in the queue waiting to be sent? * // Are there any characters in the queue waiting to be sent?
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine * // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
// is woken by the post - ensuring that only a single co-routine is * // is woken by the post - ensuring that only a single co-routine is
// woken no matter how many times we go around this loop. * // woken no matter how many times we go around this loop.
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) ) * if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
{ * {
SEND_CHARACTER( cCharToTx ); * SEND_CHARACTER( cCharToTx );
} * }
} * }
}</pre> * }
* @endcode
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
* \ingroup Tasks * \ingroup Tasks
*/ */
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) #define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) \
xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
/* /*
* This function is intended for internal use by the co-routine macros only. * This function is intended for internal use by the co-routine macros only.
@@ -702,7 +734,8 @@ void vCoRoutineSchedule( void );
* Removes the current co-routine from its ready list and places it in the * Removes the current co-routine from its ready list and places it in the
* appropriate delayed list. * appropriate delayed list.
*/ */
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
List_t * pxEventList );
/* /*
* This function is intended for internal use by the queue implementation only. * This function is intended for internal use by the queue implementation only.
@@ -711,10 +744,12 @@ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
* Removes the highest priority co-routine from the event list and places it in * Removes the highest priority co-routine from the event list and places it in
* the pending ready list. * the pending ready list.
*/ */
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList );
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */
#endif /* CO_ROUTINE_H */ #endif /* CO_ROUTINE_H */
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#ifndef DEPRECATED_DEFINITIONS_H #ifndef DEPRECATED_DEFINITIONS_H
@@ -30,158 +31,158 @@
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a /* Each FreeRTOS port has a unique portmacro.h header file. Originally a
pre-processor definition was used to ensure the pre-processor found the correct * pre-processor definition was used to ensure the pre-processor found the correct
portmacro.h file for the port being used. That scheme was deprecated in favour * portmacro.h file for the port being used. That scheme was deprecated in favour
of setting the compiler's include path such that it found the correct * of setting the compiler's include path such that it found the correct
portmacro.h file - removing the need for the constant and allowing the * portmacro.h file - removing the need for the constant and allowing the
portmacro.h file to be located anywhere in relation to the port being used. The * portmacro.h file to be located anywhere in relation to the port being used. The
definitions below remain in the code for backward compatibility only. New * definitions below remain in the code for backward compatibility only. New
projects should not use them. */ * projects should not use them. */
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
typedef void ( __interrupt __far *pxISR )(); typedef void ( __interrupt __far * pxISR )();
#endif #endif
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
typedef void ( __interrupt __far *pxISR )(); typedef void ( __interrupt __far * pxISR )();
#endif #endif
#ifdef GCC_MEGA_AVR #ifdef GCC_MEGA_AVR
#include "../portable/GCC/ATMega323/portmacro.h" #include "../portable/GCC/ATMega323/portmacro.h"
#endif #endif
#ifdef IAR_MEGA_AVR #ifdef IAR_MEGA_AVR
#include "../portable/IAR/ATMega323/portmacro.h" #include "../portable/IAR/ATMega323/portmacro.h"
#endif #endif
#ifdef MPLAB_PIC24_PORT #ifdef MPLAB_PIC24_PORT
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
#endif #endif
#ifdef MPLAB_DSPIC_PORT #ifdef MPLAB_DSPIC_PORT
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
#endif #endif
#ifdef MPLAB_PIC18F_PORT #ifdef MPLAB_PIC18F_PORT
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h" #include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
#endif #endif
#ifdef MPLAB_PIC32MX_PORT #ifdef MPLAB_PIC32MX_PORT
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
#endif #endif
#ifdef _FEDPICC #ifdef _FEDPICC
#include "libFreeRTOS/Include/portmacro.h" #include "libFreeRTOS/Include/portmacro.h"
#endif #endif
#ifdef SDCC_CYGNAL #ifdef SDCC_CYGNAL
#include "../../Source/portable/SDCC/Cygnal/portmacro.h" #include "../../Source/portable/SDCC/Cygnal/portmacro.h"
#endif #endif
#ifdef GCC_ARM7 #ifdef GCC_ARM7
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
#endif #endif
#ifdef GCC_ARM7_ECLIPSE #ifdef GCC_ARM7_ECLIPSE
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#ifdef ROWLEY_LPC23xx #ifdef ROWLEY_LPC23xx
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
#endif #endif
#ifdef IAR_MSP430 #ifdef IAR_MSP430
#include "..\..\Source\portable\IAR\MSP430\portmacro.h" #include "..\..\Source\portable\IAR\MSP430\portmacro.h"
#endif #endif
#ifdef GCC_MSP430 #ifdef GCC_MSP430
#include "../../Source/portable/GCC/MSP430F449/portmacro.h" #include "../../Source/portable/GCC/MSP430F449/portmacro.h"
#endif #endif
#ifdef ROWLEY_MSP430 #ifdef ROWLEY_MSP430
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h" #include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
#endif #endif
#ifdef ARM7_LPC21xx_KEIL_RVDS #ifdef ARM7_LPC21xx_KEIL_RVDS
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
#endif #endif
#ifdef SAM7_GCC #ifdef SAM7_GCC
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
#endif #endif
#ifdef SAM7_IAR #ifdef SAM7_IAR
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
#endif #endif
#ifdef SAM9XE_IAR #ifdef SAM9XE_IAR
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
#endif #endif
#ifdef LPC2000_IAR #ifdef LPC2000_IAR
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h" #include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
#endif #endif
#ifdef STR71X_IAR #ifdef STR71X_IAR
#include "..\..\Source\portable\IAR\STR71x\portmacro.h" #include "..\..\Source\portable\IAR\STR71x\portmacro.h"
#endif #endif
#ifdef STR75X_IAR #ifdef STR75X_IAR
#include "..\..\Source\portable\IAR\STR75x\portmacro.h" #include "..\..\Source\portable\IAR\STR75x\portmacro.h"
#endif #endif
#ifdef STR75X_GCC #ifdef STR75X_GCC
#include "..\..\Source\portable\GCC\STR75x\portmacro.h" #include "..\..\Source\portable\GCC\STR75x\portmacro.h"
#endif #endif
#ifdef STR91X_IAR #ifdef STR91X_IAR
#include "..\..\Source\portable\IAR\STR91x\portmacro.h" #include "..\..\Source\portable\IAR\STR91x\portmacro.h"
#endif #endif
#ifdef GCC_H8S #ifdef GCC_H8S
#include "../../Source/portable/GCC/H8S2329/portmacro.h" #include "../../Source/portable/GCC/H8S2329/portmacro.h"
#endif #endif
#ifdef GCC_AT91FR40008 #ifdef GCC_AT91FR40008
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
#endif #endif
#ifdef RVDS_ARMCM3_LM3S102 #ifdef RVDS_ARMCM3_LM3S102
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
#endif #endif
#ifdef GCC_ARMCM3_LM3S102 #ifdef GCC_ARMCM3_LM3S102
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h" #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
#endif #endif
#ifdef GCC_ARMCM3 #ifdef GCC_ARMCM3
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h" #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
#endif #endif
#ifdef IAR_ARM_CM3 #ifdef IAR_ARM_CM3
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h" #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
#endif #endif
#ifdef IAR_ARMCM3_LM #ifdef IAR_ARMCM3_LM
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h" #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
#endif #endif
#ifdef HCS12_CODE_WARRIOR #ifdef HCS12_CODE_WARRIOR
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
#endif #endif
#ifdef MICROBLAZE_GCC #ifdef MICROBLAZE_GCC
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h" #include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
#endif #endif
#ifdef TERN_EE #ifdef TERN_EE
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
#endif #endif
#ifdef GCC_HCS12 #ifdef GCC_HCS12
#include "../../Source/portable/GCC/HCS12/portmacro.h" #include "../../Source/portable/GCC/HCS12/portmacro.h"
#endif #endif
#ifdef GCC_MCF5235 #ifdef GCC_MCF5235
@@ -189,91 +190,92 @@ projects should not use them. */
#endif #endif
#ifdef COLDFIRE_V2_GCC #ifdef COLDFIRE_V2_GCC
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
#endif #endif
#ifdef COLDFIRE_V2_CODEWARRIOR #ifdef COLDFIRE_V2_CODEWARRIOR
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
#endif #endif
#ifdef GCC_PPC405 #ifdef GCC_PPC405
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
#endif #endif
#ifdef GCC_PPC440 #ifdef GCC_PPC440
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
#endif #endif
#ifdef _16FX_SOFTUNE #ifdef _16FX_SOFTUNE
#include "..\..\Source\portable\Softune\MB96340\portmacro.h" #include "..\..\Source\portable\Softune\MB96340\portmacro.h"
#endif #endif
#ifdef BCC_INDUSTRIAL_PC_PORT #ifdef BCC_INDUSTRIAL_PC_PORT
/* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */ /* A short file name has to be used in place of the normal
#include "frconfig.h" * FreeRTOSConfig.h when using the Borland compiler. */
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h" #include "frconfig.h"
typedef void ( __interrupt __far *pxISR )(); #include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
typedef void ( __interrupt __far * pxISR )();
#endif #endif
#ifdef BCC_FLASH_LITE_186_PORT #ifdef BCC_FLASH_LITE_186_PORT
/* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */ /* A short file name has to be used in place of the normal
#include "frconfig.h" * FreeRTOSConfig.h when using the Borland compiler. */
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" #include "frconfig.h"
typedef void ( __interrupt __far *pxISR )(); #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
typedef void ( __interrupt __far * pxISR )();
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
#ifdef __AVR32_AVR32A__ #ifdef __AVR32_AVR32A__
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#endif #endif
#ifdef __ICCAVR32__ #ifdef __ICCAVR32__
#ifdef __CORE__ #ifdef __CORE__
#if __CORE__ == __AVR32A__ #if __CORE__ == __AVR32A__
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#endif #endif
#endif #endif
#ifdef __91467D #ifdef __91467D
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#ifdef __96340 #ifdef __96340
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Fx3__ #ifdef __IAR_V850ES_Fx3__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Jx3__ #ifdef __IAR_V850ES_Jx3__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Jx3_L__ #ifdef __IAR_V850ES_Jx3_L__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Jx2__ #ifdef __IAR_V850ES_Jx2__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Hx2__ #ifdef __IAR_V850ES_Hx2__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_78K0R_Kx3__ #ifdef __IAR_78K0R_Kx3__
#include "../../Source/portable/IAR/78K0R/portmacro.h" #include "../../Source/portable/IAR/78K0R/portmacro.h"
#endif #endif
#ifdef __IAR_78K0R_Kx3L__ #ifdef __IAR_78K0R_Kx3L__
#include "../../Source/portable/IAR/78K0R/portmacro.h" #include "../../Source/portable/IAR/78K0R/portmacro.h"
#endif #endif
#endif /* DEPRECATED_DEFINITIONS_H */ #endif /* DEPRECATED_DEFINITIONS_H */
File diff suppressed because it is too large Load Diff
+187 -96
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/* /*
@@ -32,7 +33,7 @@
* *
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
* numeric value (xItemValue). Most of the time the lists are sorted in * numeric value (xItemValue). Most of the time the lists are sorted in
* descending item value order. * ascending item value order.
* *
* Lists are created already containing one list item. The value of this * Lists are created already containing one list item. The value of this
* item is the maximum possible that can be stored, it is therefore always at * item is the maximum possible that can be stored, it is therefore always at
@@ -53,13 +54,14 @@
* \ingroup FreeRTOSIntro * \ingroup FreeRTOSIntro
*/ */
#ifndef INC_FREERTOS_H
#error FreeRTOS.h must be included before list.h
#endif
#ifndef LIST_H #ifndef LIST_H
#define LIST_H #define LIST_H
#ifndef INC_FREERTOS_H
#error "FreeRTOS.h must be included before list.h"
#endif
/* /*
* The list structure members are modified from within interrupts, and therefore * The list structure members are modified from within interrupts, and therefore
* by rights should be declared volatile. However, they are only modified in a * by rights should be declared volatile. However, they are only modified in a
@@ -89,47 +91,49 @@
* "#define configLIST_VOLATILE volatile" * "#define configLIST_VOLATILE volatile"
*/ */
#ifndef configLIST_VOLATILE #ifndef configLIST_VOLATILE
#define configLIST_VOLATILE #define configLIST_VOLATILE
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ #endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/* Macros that can be used to place known values within the list structures, /* Macros that can be used to place known values within the list structures,
then check that the known values do not get corrupted during the execution of * then check that the known values do not get corrupted during the execution of
the application. These may catch the list data structures being overwritten in * the application. These may catch the list data structures being overwritten in
memory. They will not catch data errors caused by incorrect configuration or * memory. They will not catch data errors caused by incorrect configuration or
use of FreeRTOS.*/ * use of FreeRTOS.*/
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
/* Define the macros to do nothing. */ /* Define the macros to do nothing. */
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE #define listFIRST_LIST_INTEGRITY_CHECK_VALUE
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE #define listSECOND_LIST_INTEGRITY_CHECK_VALUE
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) #define listTEST_LIST_ITEM_INTEGRITY( pxItem )
#define listTEST_LIST_INTEGRITY( pxList ) #define listTEST_LIST_INTEGRITY( pxList )
#else #else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
/* Define macros that add new members into the list structures. */ /* Define macros that add new members into the list structures. */
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
/* Define macros that set the new structure members to known values. */ /* Define macros that set the new structure members to known values. */
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
/* Define macros that will assert if one of the structure members does not /* Define macros that will assert if one of the structure members does not
contain its expected value. */ * contain its expected value. */
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
@@ -139,35 +143,39 @@ use of FreeRTOS.*/
struct xLIST; struct xLIST;
struct xLIST_ITEM struct xLIST_ITEM
{ {
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ configLIST_VOLATILE TickType_t xItemValue; /**< The value being listed. In most cases this is used to sort the list in ascending order. */
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxNext; /**< Pointer to the next ListItem_t in the list. */
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /**< Pointer to the previous ListItem_t in the list. */
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ void * pvOwner; /**< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ struct xLIST * configLIST_VOLATILE pxContainer; /**< Pointer to the list in which this list item is placed (if any). */
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
}; };
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
struct xMINI_LIST_ITEM #if ( configUSE_MINI_LIST_ITEM == 1 )
{ struct xMINI_LIST_ITEM
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ {
configLIST_VOLATILE TickType_t xItemValue; listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
struct xLIST_ITEM * configLIST_VOLATILE pxNext; configLIST_VOLATILE TickType_t xItemValue;
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; struct xLIST_ITEM * configLIST_VOLATILE pxNext;
}; struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
typedef struct xMINI_LIST_ITEM MiniListItem_t; };
typedef struct xMINI_LIST_ITEM MiniListItem_t;
#else
typedef struct xLIST_ITEM MiniListItem_t;
#endif
/* /*
* Definition of the type of queue used by the scheduler. * Definition of the type of queue used by the scheduler.
*/ */
typedef struct xLIST typedef struct xLIST
{ {
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listFIRST_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
volatile UBaseType_t uxNumberOfItems; volatile UBaseType_t uxNumberOfItems;
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ ListItem_t * configLIST_VOLATILE pxIndex; /**< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ MiniListItem_t xListEnd; /**< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listSECOND_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
} List_t; } List_t;
/* /*
@@ -177,7 +185,7 @@ typedef struct xLIST
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
/* /*
* Access macro to get the owner of a list item. The owner of a list item * Access macro to get the owner of a list item. The owner of a list item
@@ -186,16 +194,16 @@ typedef struct xLIST
* \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER * \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) #define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
/* /*
* Access macro to set the value of the list item. In most cases the value is * Access macro to set the value of the list item. In most cases the value is
* used to sort the list in descending order. * used to sort the list in ascending order.
* *
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) #define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
/* /*
* Access macro to retrieve the value of the list item. The value can * Access macro to retrieve the value of the list item. The value can
@@ -205,7 +213,7 @@ typedef struct xLIST
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) #define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
/* /*
* Access macro to retrieve the value of the list item at the head of a given * Access macro to retrieve the value of the list item at the head of a given
@@ -214,7 +222,7 @@ typedef struct xLIST
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
/* /*
* Return the list item at the head of the list. * Return the list item at the head of the list.
@@ -222,7 +230,7 @@ typedef struct xLIST
* \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) #define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
/* /*
* Return the next list item. * Return the next list item.
@@ -230,7 +238,7 @@ typedef struct xLIST
* \page listGET_NEXT listGET_NEXT * \page listGET_NEXT listGET_NEXT
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) #define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
/* /*
* Return the list item that marks the end of the list * Return the list item that marks the end of the list
@@ -238,7 +246,7 @@ typedef struct xLIST
* \page listGET_END_MARKER listGET_END_MARKER * \page listGET_END_MARKER listGET_END_MARKER
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) #define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
/* /*
* Access macro to determine if a list contains any items. The macro will * Access macro to determine if a list contains any items. The macro will
@@ -247,12 +255,12 @@ typedef struct xLIST
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) #define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
/* /*
* Access macro to return the number of items in the list. * Access macro to return the number of items in the list.
*/ */
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) #define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
/* /*
* Access function to obtain the owner of the next entry in a list. * Access function to obtain the owner of the next entry in a list.
@@ -274,19 +282,99 @@ typedef struct xLIST
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
{ \ do { \
List_t * const pxConstList = ( pxList ); \ List_t * const pxConstList = ( pxList ); \
/* Increment the index to the next item and return the item, ensuring */ \ /* Increment the index to the next item and return the item, ensuring */ \
/* we don't return the marker used at the end of the list. */ \ /* we don't return the marker used at the end of the list. */ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
{ \ { \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ ( pxConstList )->pxIndex = ( pxConstList )->xListEnd.pxNext; \
} \ } \
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
} } while( 0 )
/*
* Version of uxListRemove() that does not return a value. Provided as a slight
* optimisation for xTaskIncrementTick() by being inline.
*
* Remove an item from a list. The list item has a pointer to the list that
* it is in, so only the list item need be passed into the function.
*
* @param uxListRemove The item to be removed. The item will remove itself from
* the list pointed to by it's pxContainer parameter.
*
* @return The number of items that remain in the list after the list item has
* been removed.
*
* \page listREMOVE_ITEM listREMOVE_ITEM
* \ingroup LinkedList
*/
#define listREMOVE_ITEM( pxItemToRemove ) \
do { \
/* The list item knows which list it is in. Obtain the list from the list \
* item. */ \
List_t * const pxList = ( pxItemToRemove )->pxContainer; \
\
( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \
( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext; \
/* Make sure the index is left pointing to a valid item. */ \
if( pxList->pxIndex == ( pxItemToRemove ) ) \
{ \
pxList->pxIndex = ( pxItemToRemove )->pxPrevious; \
} \
\
( pxItemToRemove )->pxContainer = NULL; \
( pxList->uxNumberOfItems )--; \
} while( 0 )
/*
* Inline version of vListInsertEnd() to provide slight optimisation for
* xTaskIncrementTick().
*
* Insert a list item into a list. The item will be inserted in a position
* such that it will be the last item within the list returned by multiple
* calls to listGET_OWNER_OF_NEXT_ENTRY.
*
* The list member pxIndex is used to walk through a list. Calling
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
* Placing an item in a list using vListInsertEnd effectively places the item
* in the list position pointed to by pxIndex. This means that every other
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
* the pxIndex parameter again points to the item being inserted.
*
* @param pxList The list into which the item is to be inserted.
*
* @param pxNewListItem The list item to be inserted into the list.
*
* \page listINSERT_END listINSERT_END
* \ingroup LinkedList
*/
#define listINSERT_END( pxList, pxNewListItem ) \
do { \
ListItem_t * const pxIndex = ( pxList )->pxIndex; \
\
/* Only effective when configASSERT() is also defined, these tests may catch \
* the list data structures being overwritten in memory. They will not catch \
* data errors caused by incorrect configuration or use of FreeRTOS. */ \
listTEST_LIST_INTEGRITY( ( pxList ) ); \
listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) ); \
\
/* Insert a new list item into ( pxList ), but rather than sort the list, \
* makes the new list item the last item to be removed by a call to \
* listGET_OWNER_OF_NEXT_ENTRY(). */ \
( pxNewListItem )->pxNext = pxIndex; \
( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \
\
pxIndex->pxPrevious->pxNext = ( pxNewListItem ); \
pxIndex->pxPrevious = ( pxNewListItem ); \
\
/* Remember which list the item is in. */ \
( pxNewListItem )->pxContainer = ( pxList ); \
\
( ( pxList )->uxNumberOfItems )++; \
} while( 0 )
/* /*
* Access function to obtain the owner of the first entry in a list. Lists * Access function to obtain the owner of the first entry in a list. Lists
@@ -304,7 +392,7 @@ List_t * const pxConstList = ( pxList ); \
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
* \ingroup LinkedList * \ingroup LinkedList
*/ */
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) #define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner )
/* /*
* Check to see if a list item is within a list. The list item maintains a * Check to see if a list item is within a list. The list item maintains a
@@ -315,7 +403,7 @@ List_t * const pxConstList = ( pxList ); \
* @param pxListItem The list item we want to know if is in the list. * @param pxListItem The list item we want to know if is in the list.
* @return pdTRUE if the list item is in the list, otherwise pdFALSE. * @return pdTRUE if the list item is in the list, otherwise pdFALSE.
*/ */
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
/* /*
* Return the list a list item is contained within (referenced from). * Return the list a list item is contained within (referenced from).
@@ -323,14 +411,14 @@ List_t * const pxConstList = ( pxList ); \
* @param pxListItem The list item being queried. * @param pxListItem The list item being queried.
* @return A pointer to the List_t object that references the pxListItem * @return A pointer to the List_t object that references the pxListItem
*/ */
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) #define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
/* /*
* This provides a crude means of knowing if a list has been initialised, as * This provides a crude means of knowing if a list has been initialised, as
* pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
* function. * function.
*/ */
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) #define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
/* /*
* Must be called before a list is used! This initialises all the members * Must be called before a list is used! This initialises all the members
@@ -357,7 +445,7 @@ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
/* /*
* Insert a list item into a list. The item will be inserted into the list in * Insert a list item into a list. The item will be inserted into the list in
* a position determined by its item value (descending item value order). * a position determined by its item value (ascending item value order).
* *
* @param pxList The list into which the item is to be inserted. * @param pxList The list into which the item is to be inserted.
* *
@@ -366,7 +454,8 @@ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
* \page vListInsert vListInsert * \page vListInsert vListInsert
* \ingroup LinkedList * \ingroup LinkedList
*/ */
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; void vListInsert( List_t * const pxList,
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
/* /*
* Insert a list item into a list. The item will be inserted in a position * Insert a list item into a list. The item will be inserted in a position
@@ -387,7 +476,8 @@ void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIV
* \page vListInsertEnd vListInsertEnd * \page vListInsertEnd vListInsertEnd
* \ingroup LinkedList * \ingroup LinkedList
*/ */
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
/* /*
* Remove an item from a list. The list item has a pointer to the list that * Remove an item from a list. The list item has a pointer to the list that
@@ -404,9 +494,10 @@ void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) P
*/ */
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif
#endif #endif
/* *INDENT-ON* */
#endif /* ifndef LIST_H */
+339 -255
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
@@ -63,32 +64,35 @@
#define FREERTOS_MESSAGE_BUFFER_H #define FREERTOS_MESSAGE_BUFFER_H
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include message_buffer.h" #error "include FreeRTOS.h must appear in source files before include message_buffer.h"
#endif #endif
/* Message buffers are built onto of stream buffers. */ /* Message buffers are built onto of stream buffers. */
#include "stream_buffer.h" #include "stream_buffer.h"
/* *INDENT-OFF* */
#if defined( __cplusplus ) #if defined( __cplusplus )
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/** /**
* Type by which message buffers are referenced. For example, a call to * Type by which message buffers are referenced. For example, a call to
* xMessageBufferCreate() returns an MessageBufferHandle_t variable that can * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can
* then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
* etc. * etc. Message buffer is essentially built as a stream buffer hence its handle
* is also set to same type as a stream buffer handle.
*/ */
typedef void * MessageBufferHandle_t; typedef StreamBufferHandle_t MessageBufferHandle_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes ); * MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
</pre> * @endcode
* *
* Creates a new message buffer using dynamically allocated memory. See * Creates a new message buffer using dynamically allocated memory. See
* xMessageBufferCreateStatic() for a version that uses statically allocated * xMessageBufferCreateStatic() for a version that uses statically allocated
@@ -104,6 +108,18 @@ MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
* 32-bit architecture, so on most 32-bit architectures a 10 byte message will * 32-bit architecture, so on most 32-bit architectures a 10 byte message will
* take up 14 bytes of message buffer space. * take up 14 bytes of message buffer space.
* *
* @param pxSendCompletedCallback Callback invoked when a send operation to the
* message buffer is complete. If the parameter is NULL or xMessageBufferCreate()
* is called without the parameter, then it will use the default implementation
* provided by sbSEND_COMPLETED macro. To enable the callback,
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
*
* @param pxReceiveCompletedCallback Callback invoked when a receive operation from
* the message buffer is complete. If the parameter is NULL or xMessageBufferCreate()
* is called without the parameter, it will use the default implementation provided
* by sbRECEIVE_COMPLETED macro. To enable the callback,
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
*
* @return If NULL is returned, then the message buffer cannot be created * @return If NULL is returned, then the message buffer cannot be created
* because there is insufficient heap memory available for FreeRTOS to allocate * because there is insufficient heap memory available for FreeRTOS to allocate
* the message buffer data structures and storage area. A non-NULL value being * the message buffer data structures and storage area. A non-NULL value being
@@ -112,43 +128,49 @@ MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
* buffer. * buffer.
* *
* Example use: * Example use:
<pre> * @code{c}
*
void vAFunction( void ) * void vAFunction( void )
{ * {
MessageBufferHandle_t xMessageBuffer; * MessageBufferHandle_t xMessageBuffer;
const size_t xMessageBufferSizeBytes = 100; * const size_t xMessageBufferSizeBytes = 100;
*
// Create a message buffer that can hold 100 bytes. The memory used to hold * // Create a message buffer that can hold 100 bytes. The memory used to hold
// both the message buffer structure and the messages themselves is allocated * // both the message buffer structure and the messages themselves is allocated
// dynamically. Each message added to the buffer consumes an additional 4 * // dynamically. Each message added to the buffer consumes an additional 4
// bytes which are used to hold the lengh of the message. * // bytes which are used to hold the length of the message.
xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes ); * xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
*
if( xMessageBuffer == NULL ) * if( xMessageBuffer == NULL )
{ * {
// There was not enough heap memory space available to create the * // There was not enough heap memory space available to create the
// message buffer. * // message buffer.
} * }
else * else
{ * {
// The message buffer was created successfully and can now be used. * // The message buffer was created successfully and can now be used.
} * }
*
</pre> * @endcode
* \defgroup xMessageBufferCreate xMessageBufferCreate * \defgroup xMessageBufferCreate xMessageBufferCreate
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) #define xMessageBufferCreate( xBufferSizeBytes ) \
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, NULL, NULL )
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
#define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
#endif
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes, * MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
uint8_t *pucMessageBufferStorageArea, * uint8_t *pucMessageBufferStorageArea,
StaticMessageBuffer_t *pxStaticMessageBuffer ); * StaticMessageBuffer_t *pxStaticMessageBuffer );
</pre> * @endcode
* Creates a new message buffer using statically allocated memory. See * Creates a new message buffer using statically allocated memory. See
* xMessageBufferCreate() for a version that uses dynamically allocated memory. * xMessageBufferCreate() for a version that uses dynamically allocated memory.
* *
@@ -161,61 +183,108 @@ MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
* stored in the message buffer is actually (xBufferSizeBytes - 1). * stored in the message buffer is actually (xBufferSizeBytes - 1).
* *
* @param pucMessageBufferStorageArea Must point to a uint8_t array that is at * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at
* least xBufferSizeBytes + 1 big. This is the array to which messages are * least xBufferSizeBytes big. This is the array to which messages are
* copied when they are written to the message buffer. * copied when they are written to the message buffer.
* *
* @param pxStaticMessageBuffer Must point to a variable of type * @param pxStaticMessageBuffer Must point to a variable of type
* StaticMessageBuffer_t, which will be used to hold the message buffer's data * StaticMessageBuffer_t, which will be used to hold the message buffer's data
* structure. * structure.
* *
* @param pxSendCompletedCallback Callback invoked when a new message is sent to the message buffer.
* If the parameter is NULL or xMessageBufferCreate() is called without the parameter, then it will use the default
* implementation provided by sbSEND_COMPLETED macro. To enable the callback,
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
*
* @param pxReceiveCompletedCallback Callback invoked when a message is read from a
* message buffer. If the parameter is NULL or xMessageBufferCreate() is called without the parameter, it will
* use the default implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback,
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
*
* @return If the message buffer is created successfully then a handle to the * @return If the message buffer is created successfully then a handle to the
* created message buffer is returned. If either pucMessageBufferStorageArea or * created message buffer is returned. If either pucMessageBufferStorageArea or
* pxStaticmessageBuffer are NULL then NULL is returned. * pxStaticmessageBuffer are NULL then NULL is returned.
* *
* Example use: * Example use:
<pre> * @code{c}
*
// Used to dimension the array used to hold the messages. The available space * // Used to dimension the array used to hold the messages. The available space
// will actually be one less than this, so 999. * // will actually be one less than this, so 999.
#define STORAGE_SIZE_BYTES 1000 #define STORAGE_SIZE_BYTES 1000
*
// Defines the memory that will actually hold the messages within the message * // Defines the memory that will actually hold the messages within the message
// buffer. * // buffer.
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
*
// The variable used to hold the message buffer structure. * // The variable used to hold the message buffer structure.
StaticMessageBuffer_t xMessageBufferStruct; * StaticMessageBuffer_t xMessageBufferStruct;
*
void MyFunction( void ) * void MyFunction( void )
{ * {
MessageBufferHandle_t xMessageBuffer; * MessageBufferHandle_t xMessageBuffer;
*
xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ), * xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucStorageBuffer ),
ucBufferStorage, * ucStorageBuffer,
&xMessageBufferStruct ); * &xMessageBufferStruct );
*
// As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer * // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
// parameters were NULL, xMessageBuffer will not be NULL, and can be used to * // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
// reference the created message buffer in other message buffer API calls. * // reference the created message buffer in other message buffer API calls.
*
// Other code that uses the message buffer can go here. * // Other code that uses the message buffer can go here.
} * }
*
</pre> * @endcode
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) #define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL )
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
#define xMessageBufferCreateStaticWithCallback( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
#endif
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer, * BaseType_t xMessageBufferGetStaticBuffers( MessageBufferHandle_t xMessageBuffer,
const void *pvTxData, * uint8_t ** ppucMessageBufferStorageArea,
size_t xDataLengthBytes, * StaticMessageBuffer_t ** ppxStaticMessageBuffer );
TickType_t xTicksToWait ); * @endcode
<pre> *
* Retrieve pointers to a statically created message buffer's data structure
* buffer and storage area buffer. These are the same buffers that are supplied
* at the time of creation.
*
* @param xMessageBuffer The message buffer for which to retrieve the buffers.
*
* @param ppucMessageBufferStorageArea Used to return a pointer to the
* message buffer's storage area buffer.
*
* @param ppxStaticMessageBuffer Used to return a pointer to the message
* buffer's data structure buffer.
*
* @return pdTRUE if buffers were retrieved, pdFALSE otherwise..
*
* \defgroup xMessageBufferGetStaticBuffers xMessageBufferGetStaticBuffers
* \ingroup MessageBufferManagement
*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
#define xMessageBufferGetStaticBuffers( xMessageBuffer, ppucMessageBufferStorageArea, ppxStaticMessageBuffer ) \
xStreamBufferGetStaticBuffers( ( xMessageBuffer ), ( ppucMessageBufferStorageArea ), ( ppxStaticMessageBuffer ) )
#endif /* configSUPPORT_STATIC_ALLOCATION */
/**
* message_buffer.h
*
* @code{c}
* size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
* const void *pvTxData,
* size_t xDataLengthBytes,
* TickType_t xTicksToWait );
* @endcode
* *
* Sends a discrete message to the message buffer. The message can be any * Sends a discrete message to the message buffer. The message can be any
* length that fits within the buffer's free space, and is copied into the * length that fits within the buffer's free space, and is copied into the
@@ -272,49 +341,50 @@ size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
* time out then xDataLengthBytes is returned. * time out then xDataLengthBytes is returned.
* *
* Example use: * Example use:
<pre> * @code{c}
void vAFunction( MessageBufferHandle_t xMessageBuffer ) * void vAFunction( MessageBufferHandle_t xMessageBuffer )
{ * {
size_t xBytesSent; * size_t xBytesSent;
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
char *pcStringToSend = "String to send"; * char *pcStringToSend = "String to send";
const TickType_t x100ms = pdMS_TO_TICKS( 100 ); * const TickType_t x100ms = pdMS_TO_TICKS( 100 );
*
// Send an array to the message buffer, blocking for a maximum of 100ms to * // Send an array to the message buffer, blocking for a maximum of 100ms to
// wait for enough space to be available in the message buffer. * // wait for enough space to be available in the message buffer.
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); * xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
*
if( xBytesSent != sizeof( ucArrayToSend ) ) * if( xBytesSent != sizeof( ucArrayToSend ) )
{ * {
// The call to xMessageBufferSend() times out before there was enough * // The call to xMessageBufferSend() times out before there was enough
// space in the buffer for the data to be written. * // space in the buffer for the data to be written.
} * }
*
// Send the string to the message buffer. Return immediately if there is * // Send the string to the message buffer. Return immediately if there is
// not enough space in the buffer. * // not enough space in the buffer.
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); * xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
*
if( xBytesSent != strlen( pcStringToSend ) ) * if( xBytesSent != strlen( pcStringToSend ) )
{ * {
// The string could not be added to the message buffer because there was * // The string could not be added to the message buffer because there was
// not enough free space in the buffer. * // not enough free space in the buffer.
} * }
} * }
</pre> * @endcode
* \defgroup xMessageBufferSend xMessageBufferSend * \defgroup xMessageBufferSend xMessageBufferSend
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) #define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) \
xStreamBufferSend( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( xTicksToWait ) )
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer, * size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
const void *pvTxData, * const void *pvTxData,
size_t xDataLengthBytes, * size_t xDataLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
<pre> * @endcode
* *
* Interrupt safe version of the API function that sends a discrete message to * Interrupt safe version of the API function that sends a discrete message to
* the message buffer. The message can be any length that fits within the * the message buffer. The message can be any length that fits within the
@@ -372,53 +442,54 @@ size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
* then 0 is returned, otherwise xDataLengthBytes is returned. * then 0 is returned, otherwise xDataLengthBytes is returned.
* *
* Example use: * Example use:
<pre> * @code{c}
// A message buffer that has already been created. * // A message buffer that has already been created.
MessageBufferHandle_t xMessageBuffer; * MessageBufferHandle_t xMessageBuffer;
*
void vAnInterruptServiceRoutine( void ) * void vAnInterruptServiceRoutine( void )
{ * {
size_t xBytesSent; * size_t xBytesSent;
char *pcStringToSend = "String to send"; * char *pcStringToSend = "String to send";
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
*
// Attempt to send the string to the message buffer. * // Attempt to send the string to the message buffer.
xBytesSent = xMessageBufferSendFromISR( xMessageBuffer, * xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
( void * ) pcStringToSend, * ( void * ) pcStringToSend,
strlen( pcStringToSend ), * strlen( pcStringToSend ),
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
if( xBytesSent != strlen( pcStringToSend ) ) * if( xBytesSent != strlen( pcStringToSend ) )
{ * {
// The string could not be added to the message buffer because there was * // The string could not be added to the message buffer because there was
// not enough free space in the buffer. * // not enough free space in the buffer.
} * }
*
// If xHigherPriorityTaskWoken was set to pdTRUE inside * // If xHigherPriorityTaskWoken was set to pdTRUE inside
// xMessageBufferSendFromISR() then a task that has a priority above the * // xMessageBufferSendFromISR() then a task that has a priority above the
// priority of the currently executing task was unblocked and a context * // priority of the currently executing task was unblocked and a context
// switch should be performed to ensure the ISR returns to the unblocked * // switch should be performed to ensure the ISR returns to the unblocked
// task. In most FreeRTOS ports this is done by simply passing * // task. In most FreeRTOS ports this is done by simply passing
// xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
// variables value, and perform the context switch if necessary. Check the * // variables value, and perform the context switch if necessary. Check the
// documentation for the port in use for port specific instructions. * // documentation for the port in use for port specific instructions.
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
</pre> * @endcode
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) #define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) \
xStreamBufferSendFromISR( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( pxHigherPriorityTaskWoken ) )
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer, * size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
void *pvRxData, * void *pvRxData,
size_t xBufferLengthBytes, * size_t xBufferLengthBytes,
TickType_t xTicksToWait ); * TickType_t xTicksToWait );
</pre> * @endcode
* *
* Receives a discrete message from a message buffer. Messages can be of * Receives a discrete message from a message buffer. Messages can be of
* variable length and are copied out of the buffer. * variable length and are copied out of the buffer.
@@ -471,43 +542,44 @@ size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
* zero is returned. * zero is returned.
* *
* Example use: * Example use:
<pre> * @code{c}
void vAFunction( MessageBuffer_t xMessageBuffer ) * void vAFunction( MessageBuffer_t xMessageBuffer )
{ * {
uint8_t ucRxData[ 20 ]; * uint8_t ucRxData[ 20 ];
size_t xReceivedBytes; * size_t xReceivedBytes;
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
*
// Receive the next message from the message buffer. Wait in the Blocked * // Receive the next message from the message buffer. Wait in the Blocked
// state (so not using any CPU processing time) for a maximum of 100ms for * // state (so not using any CPU processing time) for a maximum of 100ms for
// a message to become available. * // a message to become available.
xReceivedBytes = xMessageBufferReceive( xMessageBuffer, * xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
( void * ) ucRxData, * ( void * ) ucRxData,
sizeof( ucRxData ), * sizeof( ucRxData ),
xBlockTime ); * xBlockTime );
*
if( xReceivedBytes > 0 ) * if( xReceivedBytes > 0 )
{ * {
// A ucRxData contains a message that is xReceivedBytes long. Process * // A ucRxData contains a message that is xReceivedBytes long. Process
// the message here.... * // the message here....
} * }
} * }
</pre> * @endcode
* \defgroup xMessageBufferReceive xMessageBufferReceive * \defgroup xMessageBufferReceive xMessageBufferReceive
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) #define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) \
xStreamBufferReceive( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( xTicksToWait ) )
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer, * size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
void *pvRxData, * void *pvRxData,
size_t xBufferLengthBytes, * size_t xBufferLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
</pre> * @endcode
* *
* An interrupt safe version of the API function that receives a discrete * An interrupt safe version of the API function that receives a discrete
* message from a message buffer. Messages can be of variable length and are * message from a message buffer. Messages can be of variable length and are
@@ -561,50 +633,51 @@ size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
* any. * any.
* *
* Example use: * Example use:
<pre> * @code{c}
// A message buffer that has already been created. * // A message buffer that has already been created.
MessageBuffer_t xMessageBuffer; * MessageBuffer_t xMessageBuffer;
*
void vAnInterruptServiceRoutine( void ) * void vAnInterruptServiceRoutine( void )
{ * {
uint8_t ucRxData[ 20 ]; * uint8_t ucRxData[ 20 ];
size_t xReceivedBytes; * size_t xReceivedBytes;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
*
// Receive the next message from the message buffer. * // Receive the next message from the message buffer.
xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer, * xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
( void * ) ucRxData, * ( void * ) ucRxData,
sizeof( ucRxData ), * sizeof( ucRxData ),
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
if( xReceivedBytes > 0 ) * if( xReceivedBytes > 0 )
{ * {
// A ucRxData contains a message that is xReceivedBytes long. Process * // A ucRxData contains a message that is xReceivedBytes long. Process
// the message here.... * // the message here....
} * }
*
// If xHigherPriorityTaskWoken was set to pdTRUE inside * // If xHigherPriorityTaskWoken was set to pdTRUE inside
// xMessageBufferReceiveFromISR() then a task that has a priority above the * // xMessageBufferReceiveFromISR() then a task that has a priority above the
// priority of the currently executing task was unblocked and a context * // priority of the currently executing task was unblocked and a context
// switch should be performed to ensure the ISR returns to the unblocked * // switch should be performed to ensure the ISR returns to the unblocked
// task. In most FreeRTOS ports this is done by simply passing * // task. In most FreeRTOS ports this is done by simply passing
// xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
// variables value, and perform the context switch if necessary. Check the * // variables value, and perform the context switch if necessary. Check the
// documentation for the port in use for port specific instructions. * // documentation for the port in use for port specific instructions.
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
</pre> * @endcode
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) #define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) \
xStreamBufferReceiveFromISR( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( pxHigherPriorityTaskWoken ) )
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer ); * void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
</pre> * @endcode
* *
* Deletes a message buffer that was previously created using a call to * Deletes a message buffer that was previously created using a call to
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
@@ -617,13 +690,14 @@ void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
* @param xMessageBuffer The handle of the message buffer to be deleted. * @param xMessageBuffer The handle of the message buffer to be deleted.
* *
*/ */
#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) #define vMessageBufferDelete( xMessageBuffer ) \
vStreamBufferDelete( xMessageBuffer )
/** /**
* message_buffer.h * message_buffer.h
<pre> * @code{c}
BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) ); * BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer );
</pre> * @endcode
* *
* Tests to see if a message buffer is full. A message buffer is full if it * Tests to see if a message buffer is full. A message buffer is full if it
* cannot accept any more messages, of any size, until space is made available * cannot accept any more messages, of any size, until space is made available
@@ -634,13 +708,14 @@ BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
* @return If the message buffer referenced by xMessageBuffer is full then * @return If the message buffer referenced by xMessageBuffer is full then
* pdTRUE is returned. Otherwise pdFALSE is returned. * pdTRUE is returned. Otherwise pdFALSE is returned.
*/ */
#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) #define xMessageBufferIsFull( xMessageBuffer ) \
xStreamBufferIsFull( xMessageBuffer )
/** /**
* message_buffer.h * message_buffer.h
<pre> * @code{c}
BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) ); * BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer );
</pre> * @endcode
* *
* Tests to see if a message buffer is empty (does not contain any messages). * Tests to see if a message buffer is empty (does not contain any messages).
* *
@@ -650,13 +725,14 @@ BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
* pdTRUE is returned. Otherwise pdFALSE is returned. * pdTRUE is returned. Otherwise pdFALSE is returned.
* *
*/ */
#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) #define xMessageBufferIsEmpty( xMessageBuffer ) \
xStreamBufferIsEmpty( xMessageBuffer )
/** /**
* message_buffer.h * message_buffer.h
<pre> * @code{c}
BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer ); * BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
</pre> * @endcode
* *
* Resets a message buffer to its initial empty state, discarding any message it * Resets a message buffer to its initial empty state, discarding any message it
* contained. * contained.
@@ -673,14 +749,15 @@ BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
* \defgroup xMessageBufferReset xMessageBufferReset * \defgroup xMessageBufferReset xMessageBufferReset
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer ) #define xMessageBufferReset( xMessageBuffer ) \
xStreamBufferReset( xMessageBuffer )
/** /**
* message_buffer.h * message_buffer.h
<pre> * @code{c}
size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) ); * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer );
</pre> * @endcode
* Returns the number of bytes of free space in the message buffer. * Returns the number of bytes of free space in the message buffer.
* *
* @param xMessageBuffer The handle of the message buffer being queried. * @param xMessageBuffer The handle of the message buffer being queried.
@@ -695,14 +772,16 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
* \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) #define xMessageBufferSpaceAvailable( xMessageBuffer ) \
#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ xStreamBufferSpacesAvailable( xMessageBuffer )
#define xMessageBufferSpacesAvailable( xMessageBuffer ) \
xStreamBufferSpacesAvailable( xMessageBuffer ) /* Corrects typo in original macro name. */
/** /**
* message_buffer.h * message_buffer.h
<pre> * @code{c}
size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) ); * size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer );
</pre> * @endcode
* Returns the length (in bytes) of the next message in a message buffer. * Returns the length (in bytes) of the next message in a message buffer.
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer * Useful if xMessageBufferReceive() returned 0 because the size of the buffer
* passed into xMessageBufferReceive() was too small to hold the next message. * passed into xMessageBufferReceive() was too small to hold the next message.
@@ -715,14 +794,15 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; #define xMessageBufferNextLengthBytes( xMessageBuffer ) \
xStreamBufferNextMessageLengthBytes( xMessageBuffer ) PRIVILEGED_FUNCTION;
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * @endcode
* *
* For advanced users only. * For advanced users only.
* *
@@ -737,7 +817,7 @@ BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuff
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
* additional information. * additional information.
* *
* @param xStreamBuffer The handle of the stream buffer to which data was * @param xMessageBuffer The handle of the stream buffer to which data was
* written. * written.
* *
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
@@ -754,14 +834,15 @@ BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuff
* \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) #define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \
xStreamBufferSendCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) )
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * @code{c}
BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * @endcode
* *
* For advanced users only. * For advanced users only.
* *
@@ -777,7 +858,7 @@ BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamB
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
* additional information. * additional information.
* *
* @param xStreamBuffer The handle of the stream buffer from which data was * @param xMessageBuffer The handle of the stream buffer from which data was
* read. * read.
* *
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
@@ -794,10 +875,13 @@ BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamB
* \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) #define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \
xStreamBufferReceiveCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) )
/* *INDENT-OFF* */
#if defined( __cplusplus ) #if defined( __cplusplus )
} /* extern "C" */ } /* extern "C" */
#endif #endif
/* *INDENT-ON* */
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ #endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/* /*
@@ -37,124 +38,439 @@
#ifndef MPU_PROTOTYPES_H #ifndef MPU_PROTOTYPES_H
#define MPU_PROTOTYPES_H #define MPU_PROTOTYPES_H
/* MPU versions of tasks.h API functions. */ typedef struct xTaskGenericNotifyParams
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; {
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; TaskHandle_t xTaskToNotify;
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; UBaseType_t uxIndexToNotify;
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; uint32_t ulValue;
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL; eNotifyAction eAction;
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; uint32_t * pulPreviousNotificationValue;
} xTaskGenericNotifyParams_t;
typedef struct xTaskGenericNotifyWaitParams
{
UBaseType_t uxIndexToWaitOn;
uint32_t ulBitsToClearOnEntry;
uint32_t ulBitsToClearOnExit;
uint32_t * pulNotificationValue;
TickType_t xTicksToWait;
} xTaskGenericNotifyWaitParams_t;
typedef struct xTimerGenericCommandParams
{
TimerHandle_t xTimer;
BaseType_t xCommandID;
TickType_t xOptionalValue;
BaseType_t * pxHigherPriorityTaskWoken;
TickType_t xTicksToWait;
} xTimerGenericCommandParams_t;
typedef struct xEventGroupWaitBitsParams
{
EventGroupHandle_t xEventGroup;
EventBits_t uxBitsToWaitFor;
BaseType_t xClearOnExit;
BaseType_t xWaitForAllBits;
TickType_t xTicksToWait;
} xEventGroupWaitBitsParams_t;
/* MPU versions of task.h API functions. */
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; void MPU_vTaskGetInfo( TaskHandle_t xTask,
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; TaskStatus_t * pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; BaseType_t xIndex,
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL; void * pvValue ) FREERTOS_SYSTEM_CALL;
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
uint32_t MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; const UBaseType_t uxArraySize,
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
uint32_t MPU_ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL; UBaseType_t uxIndexToNotify,
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; uint32_t ulValue,
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; eNotifyAction eAction,
uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t * pulNotificationValue,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
BaseType_t xClearCountOnExit,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
UBaseType_t uxIndexToClear,
uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
/* Privileged only wrappers for Task APIs. These are needed so that
* the application can use opaque handles maintained in mpu_wrappers.c
* with all the APIs. */
#if ( configUSE_MPU_WRAPPERS_V1 == 1 )
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskPrioritySet( TaskHandle_t xTask,
UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
void * pvParameter ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL;
#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION;
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION;
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
void MPU_vTaskPrioritySet( TaskHandle_t xTask,
UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION;
TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
void * pvParameter ) PRIVILEGED_FUNCTION;
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify,
const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask,
StackType_t ** ppuxStackBuffer,
StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION;
UBaseType_t MPU_uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
TaskHookFunction_t MPU_xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify,
UBaseType_t uxIndexToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t * pulPreviousNotificationValue,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
void MPU_vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify,
UBaseType_t uxIndexToNotify,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/* MPU versions of queue.h API functions. */ /* MPU versions of queue.h API functions. */
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const void * const pvItemToQueue,
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait,
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL; void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
const char * pcName ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue,
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
/* Privileged only wrappers for Queue APIs. These are needed so that
* the application can use opaque handles maintained in mpu_wrappers.c
* with all the APIs. */
#if ( configUSE_MPU_WRAPPERS_V1 == 1 )
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount,
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize,
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
void MPU_vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION;
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount,
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize,
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
BaseType_t xNewQueue ) PRIVILEGED_FUNCTION;
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
BaseType_t MPU_xQueueGenericGetStaticBuffers( QueueHandle_t xQueue,
uint8_t ** ppucQueueStorage,
StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueGenericSendFromISR( QueueHandle_t xQueue,
const void * const pvItemToQueue,
BaseType_t * const pxHigherPriorityTaskWoken,
const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueGiveFromISR( QueueHandle_t xQueue,
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t xQueue,
void * const pvBuffer ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueReceiveFromISR( QueueHandle_t xQueue,
void * const pvBuffer,
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
UBaseType_t MPU_uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
TaskHandle_t MPU_xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
QueueSetMemberHandle_t MPU_xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
/* MPU versions of timers.h API functions. */ /* MPU versions of timers.h API functions. */
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL;
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL;
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
void * pvNewID ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer,
const BaseType_t xCommandID,
const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerGenericCommandEntry( const xTimerGenericCommandParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; /* Privileged only wrappers for Timer APIs. These are needed so that
* the application can use opaque handles maintained in mpu_wrappers.c
* with all the APIs. */
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xTimerGetStaticBuffer( TimerHandle_t xTimer,
StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION;
/* MPU versions of event_group.h API functions. */ /* MPU versions of event_group.h API functions. */
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; const EventBits_t uxBitsToWaitFor,
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const BaseType_t xClearOnExit,
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; const BaseType_t xWaitForAllBits,
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL; const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL;
void MPU_vEventGroupSetNumber( void * xEventGroup,
UBaseType_t uxEventGroupNumber ) FREERTOS_SYSTEM_CALL;
#endif /* #if ( configUSE_TRACE_FACILITY == 1 ) */
/* Privileged only wrappers for Event Group APIs. These are needed so that
* the application can use opaque handles maintained in mpu_wrappers.c
* with all the APIs. */
#if ( configUSE_MPU_WRAPPERS_V1 == 1 )
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
EventGroupHandle_t MPU_xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
/* MPU versions of message/stream_buffer.h API functions. */ /* MPU versions of message/stream_buffer.h API functions. */
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const void * pvTxData,
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t xDataLengthBytes,
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
void * pvRxData,
size_t xBufferLengthBytes,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
/* Privileged only wrappers for Stream Buffer APIs. These are needed so that
* the application can use opaque handles maintained in mpu_wrappers.c
* with all the APIs. */
#if ( configUSE_MPU_WRAPPERS_V1 == 1 )
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xStreamBufferType,
StreamBufferCallbackFunction_t pxSendCompletedCallback,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL;
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xStreamBufferType,
uint8_t * const pucStreamBufferStorageArea,
StaticStreamBuffer_t * const pxStaticStreamBuffer,
StreamBufferCallbackFunction_t pxSendCompletedCallback,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL;
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xStreamBufferType,
StreamBufferCallbackFunction_t pxSendCompletedCallback,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xStreamBufferType,
uint8_t * const pucStreamBufferStorageArea,
StaticStreamBuffer_t * const pxStaticStreamBuffer,
StreamBufferCallbackFunction_t pxSendCompletedCallback,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers,
uint8_t * ppucStreamBufferStorageArea,
StaticStreamBuffer_t * ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
const void * pvTxData,
size_t xDataLengthBytes,
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
void * pvRxData,
size_t xBufferLengthBytes,
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
#endif /* MPU_PROTOTYPES_H */ #endif /* MPU_PROTOTYPES_H */
@@ -0,0 +1,106 @@
/*
* FreeRTOS Kernel V10.6.2
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef MPU_SYSCALL_NUMBERS_H
#define MPU_SYSCALL_NUMBERS_H
/* Numbers assigned to various system calls. */
#define SYSTEM_CALL_xTaskGenericNotify 0
#define SYSTEM_CALL_xTaskGenericNotifyWait 1
#define SYSTEM_CALL_xTimerGenericCommand 2
#define SYSTEM_CALL_xEventGroupWaitBits 3
#define SYSTEM_CALL_xTaskDelayUntil 4
#define SYSTEM_CALL_xTaskAbortDelay 5
#define SYSTEM_CALL_vTaskDelay 6
#define SYSTEM_CALL_uxTaskPriorityGet 7
#define SYSTEM_CALL_eTaskGetState 8
#define SYSTEM_CALL_vTaskGetInfo 9
#define SYSTEM_CALL_xTaskGetIdleTaskHandle 10
#define SYSTEM_CALL_vTaskSuspend 11
#define SYSTEM_CALL_vTaskResume 12
#define SYSTEM_CALL_xTaskGetTickCount 13
#define SYSTEM_CALL_uxTaskGetNumberOfTasks 14
#define SYSTEM_CALL_pcTaskGetName 15
#define SYSTEM_CALL_ulTaskGetRunTimeCounter 16
#define SYSTEM_CALL_ulTaskGetRunTimePercent 17
#define SYSTEM_CALL_ulTaskGetIdleRunTimePercent 18
#define SYSTEM_CALL_ulTaskGetIdleRunTimeCounter 19
#define SYSTEM_CALL_vTaskSetApplicationTaskTag 20
#define SYSTEM_CALL_xTaskGetApplicationTaskTag 21
#define SYSTEM_CALL_vTaskSetThreadLocalStoragePointer 22
#define SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer 23
#define SYSTEM_CALL_uxTaskGetSystemState 24
#define SYSTEM_CALL_uxTaskGetStackHighWaterMark 25
#define SYSTEM_CALL_uxTaskGetStackHighWaterMark2 26
#define SYSTEM_CALL_xTaskGetCurrentTaskHandle 27
#define SYSTEM_CALL_xTaskGetSchedulerState 28
#define SYSTEM_CALL_vTaskSetTimeOutState 29
#define SYSTEM_CALL_xTaskCheckForTimeOut 30
#define SYSTEM_CALL_ulTaskGenericNotifyTake 31
#define SYSTEM_CALL_xTaskGenericNotifyStateClear 32
#define SYSTEM_CALL_ulTaskGenericNotifyValueClear 33
#define SYSTEM_CALL_xQueueGenericSend 34
#define SYSTEM_CALL_uxQueueMessagesWaiting 35
#define SYSTEM_CALL_uxQueueSpacesAvailable 36
#define SYSTEM_CALL_xQueueReceive 37
#define SYSTEM_CALL_xQueuePeek 38
#define SYSTEM_CALL_xQueueSemaphoreTake 39
#define SYSTEM_CALL_xQueueGetMutexHolder 40
#define SYSTEM_CALL_xQueueTakeMutexRecursive 41
#define SYSTEM_CALL_xQueueGiveMutexRecursive 42
#define SYSTEM_CALL_xQueueSelectFromSet 43
#define SYSTEM_CALL_xQueueAddToSet 44
#define SYSTEM_CALL_vQueueAddToRegistry 45
#define SYSTEM_CALL_vQueueUnregisterQueue 46
#define SYSTEM_CALL_pcQueueGetName 47
#define SYSTEM_CALL_pvTimerGetTimerID 48
#define SYSTEM_CALL_vTimerSetTimerID 49
#define SYSTEM_CALL_xTimerIsTimerActive 50
#define SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle 51
#define SYSTEM_CALL_pcTimerGetName 52
#define SYSTEM_CALL_vTimerSetReloadMode 53
#define SYSTEM_CALL_xTimerGetReloadMode 54
#define SYSTEM_CALL_uxTimerGetReloadMode 55
#define SYSTEM_CALL_xTimerGetPeriod 56
#define SYSTEM_CALL_xTimerGetExpiryTime 57
#define SYSTEM_CALL_xEventGroupClearBits 58
#define SYSTEM_CALL_xEventGroupSetBits 59
#define SYSTEM_CALL_xEventGroupSync 60
#define SYSTEM_CALL_uxEventGroupGetNumber 61
#define SYSTEM_CALL_vEventGroupSetNumber 62
#define SYSTEM_CALL_xStreamBufferSend 63
#define SYSTEM_CALL_xStreamBufferReceive 64
#define SYSTEM_CALL_xStreamBufferIsFull 65
#define SYSTEM_CALL_xStreamBufferIsEmpty 66
#define SYSTEM_CALL_xStreamBufferSpacesAvailable 67
#define SYSTEM_CALL_xStreamBufferBytesAvailable 68
#define SYSTEM_CALL_xStreamBufferSetTriggerLevel 69
#define SYSTEM_CALL_xStreamBufferNextMessageLengthBytes 70
#define NUM_SYSTEM_CALLS 71 /* Total number of system calls. */
#endif /* MPU_SYSCALL_NUMBERS_H */
+249 -141
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,171 +21,277 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#ifndef MPU_WRAPPERS_H #ifndef MPU_WRAPPERS_H
#define MPU_WRAPPERS_H #define MPU_WRAPPERS_H
/* This file redefines API functions to be called through a wrapper macro, but /* This file redefines API functions to be called through a wrapper macro, but
only for ports that are using the MPU. */ * only for ports that are using the MPU. */
#ifdef portUSING_MPU_WRAPPERS #if ( portUSING_MPU_WRAPPERS == 1 )
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
included from queue.c or task.c to prevent it from having an effect within * included from queue.c or task.c to prevent it from having an effect within
those files. */ * those files. */
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* /*
* Map standard (non MPU) API functions to equivalents that start * Map standard (non MPU) API functions to equivalents that start
* "MPU_". This will cause the application code to call the MPU_ * "MPU_". This will cause the application code to call the MPU_
* version, which wraps the non-MPU version with privilege promoting * version, which wraps the non-MPU version with privilege promoting
* then demoting code, so the kernel code always runs will full * then demoting code, so the kernel code always runs will full
* privileges. * privileges.
*/ */
/* Map standard tasks.h API functions to the MPU equivalents. */ /* Map standard task.h API functions to the MPU equivalents. */
#define xTaskCreate MPU_xTaskCreate #define vTaskDelay MPU_vTaskDelay
#define xTaskCreateStatic MPU_xTaskCreateStatic #define xTaskDelayUntil MPU_xTaskDelayUntil
#define xTaskCreateRestricted MPU_xTaskCreateRestricted #define xTaskAbortDelay MPU_xTaskAbortDelay
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions #define uxTaskPriorityGet MPU_uxTaskPriorityGet
#define vTaskDelete MPU_vTaskDelete #define eTaskGetState MPU_eTaskGetState
#define vTaskDelay MPU_vTaskDelay #define vTaskGetInfo MPU_vTaskGetInfo
#define vTaskDelayUntil MPU_vTaskDelayUntil #define vTaskSuspend MPU_vTaskSuspend
#define xTaskAbortDelay MPU_xTaskAbortDelay #define vTaskResume MPU_vTaskResume
#define uxTaskPriorityGet MPU_uxTaskPriorityGet #define xTaskGetTickCount MPU_xTaskGetTickCount
#define eTaskGetState MPU_eTaskGetState #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
#define vTaskGetInfo MPU_vTaskGetInfo #define pcTaskGetName MPU_pcTaskGetName
#define vTaskPrioritySet MPU_vTaskPrioritySet #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
#define vTaskSuspend MPU_vTaskSuspend #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
#define vTaskResume MPU_vTaskResume #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
#define vTaskSuspendAll MPU_vTaskSuspendAll #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
#define xTaskResumeAll MPU_xTaskResumeAll #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
#define xTaskGetTickCount MPU_xTaskGetTickCount #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
#define pcTaskGetName MPU_pcTaskGetName #define uxTaskGetSystemState MPU_uxTaskGetSystemState
#define xTaskGetHandle MPU_xTaskGetHandle #define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark #define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 #define xTaskGenericNotify MPU_xTaskGenericNotify
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag #define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag #define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer #define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear
#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer #define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
#define uxTaskGetSystemState MPU_uxTaskGetSystemState #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define vTaskList MPU_vTaskList #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
#define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter
#define xTaskGenericNotify MPU_xTaskGenericNotify
#define xTaskNotifyWait MPU_xTaskNotifyWait
#define ulTaskNotifyTake MPU_ulTaskNotifyTake
#define xTaskNotifyStateClear MPU_xTaskNotifyStateClear
#define ulTaskNotifyValueClear MPU_ulTaskNotifyValueClear
#define xTaskCatchUpTicks MPU_xTaskCatchUpTicks
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState #define ulTaskGetRunTimeCounter MPU_ulTaskGetRunTimeCounter
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut #define ulTaskGetRunTimePercent MPU_ulTaskGetRunTimePercent
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/* Map standard queue.h API functions to the MPU equivalents. */ /* Privileged only wrappers for Task APIs. These are needed so that
#define xQueueGenericSend MPU_xQueueGenericSend * the application can use opaque handles maintained in mpu_wrappers.c
#define xQueueReceive MPU_xQueueReceive * with all the APIs. */
#define xQueuePeek MPU_xQueuePeek #if ( configUSE_MPU_WRAPPERS_V1 == 1 )
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake /* These are not needed in v2 because they do not take a task
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting * handle and therefore, no lookup is needed. Needed in v1 because
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable * these are available as system calls in v1. */
#define vQueueDelete MPU_vQueueDelete #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
#define xQueueCreateMutex MPU_xQueueCreateMutex #define vTaskList MPU_vTaskList
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic #define vTaskSuspendAll MPU_vTaskSuspendAll
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore #define xTaskCatchUpTicks MPU_xTaskCatchUpTicks
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic #define xTaskResumeAll MPU_xTaskResumeAll
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
#define xQueueGenericCreate MPU_xQueueGenericCreate
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
#define xQueueCreateSet MPU_xQueueCreateSet
#define xQueueAddToSet MPU_xQueueAddToSet
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
#define xQueueGenericReset MPU_xQueueGenericReset
#if( configQUEUE_REGISTRY_SIZE > 0 ) #define xTaskCreate MPU_xTaskCreate
#define vQueueAddToRegistry MPU_vQueueAddToRegistry #define xTaskCreateStatic MPU_xTaskCreateStatic
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue #define vTaskDelete MPU_vTaskDelete
#define pcQueueGetName MPU_pcQueueGetName #define vTaskPrioritySet MPU_vTaskPrioritySet
#endif #define xTaskGetHandle MPU_xTaskGetHandle
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
/* Map standard timer.h API functions to the MPU equivalents. */ #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define xTimerCreate MPU_xTimerCreate #define xTaskCreateRestricted MPU_xTaskCreateRestricted
#define xTimerCreateStatic MPU_xTimerCreateStatic #define xTaskCreateRestrictedStatic MPU_xTaskCreateRestrictedStatic
#define pvTimerGetTimerID MPU_pvTimerGetTimerID #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
#define vTimerSetTimerID MPU_vTimerSetTimerID #define xTaskGetStaticBuffers MPU_xTaskGetStaticBuffers
#define xTimerIsTimerActive MPU_xTimerIsTimerActive #define uxTaskPriorityGetFromISR MPU_uxTaskPriorityGetFromISR
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle #define xTaskResumeFromISR MPU_xTaskResumeFromISR
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall #define xTaskGetApplicationTaskTagFromISR MPU_xTaskGetApplicationTaskTagFromISR
#define pcTimerGetName MPU_pcTimerGetName #define xTaskGenericNotifyFromISR MPU_xTaskGenericNotifyFromISR
#define vTimerSetReloadMode MPU_vTimerSetReloadMode #define vTaskGenericNotifyGiveFromISR MPU_vTaskGenericNotifyGiveFromISR
#define uxTimerGetReloadMode MPU_uxTimerGetReloadMode #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
#define xTimerGetPeriod MPU_xTimerGetPeriod
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
#define xTimerGenericCommand MPU_xTimerGenericCommand
/* Map standard event_group.h API functions to the MPU equivalents. */ /* Map standard queue.h API functions to the MPU equivalents. */
#define xEventGroupCreate MPU_xEventGroupCreate #define xQueueGenericSend MPU_xQueueGenericSend
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic #define xQueueReceive MPU_xQueueReceive
#define xEventGroupWaitBits MPU_xEventGroupWaitBits #define xQueuePeek MPU_xQueuePeek
#define xEventGroupClearBits MPU_xEventGroupClearBits #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
#define xEventGroupSetBits MPU_xEventGroupSetBits #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
#define xEventGroupSync MPU_xEventGroupSync #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
#define vEventGroupDelete MPU_vEventGroupDelete #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
#define xQueueAddToSet MPU_xQueueAddToSet
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
/* Map standard message/stream_buffer.h API functions to the MPU #if ( configQUEUE_REGISTRY_SIZE > 0 )
equivalents. */ #define vQueueAddToRegistry MPU_vQueueAddToRegistry
#define xStreamBufferSend MPU_xStreamBufferSend #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
#define xStreamBufferReceive MPU_xStreamBufferReceive #define pcQueueGetName MPU_pcQueueGetName
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes #endif /* #if ( configQUEUE_REGISTRY_SIZE > 0 ) */
#define vStreamBufferDelete MPU_vStreamBufferDelete
#define xStreamBufferIsFull MPU_xStreamBufferIsFull /* Privileged only wrappers for Queue APIs. These are needed so that
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty * the application can use opaque handles maintained in mpu_wrappers.c
#define xStreamBufferReset MPU_xStreamBufferReset * with all the APIs. */
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable #define vQueueDelete MPU_vQueueDelete
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable #define xQueueCreateMutex MPU_xQueueCreateMutex
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
#define xQueueGenericCreate MPU_xQueueGenericCreate
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
#define xQueueGenericReset MPU_xQueueGenericReset
#define xQueueCreateSet MPU_xQueueCreateSet
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define xQueueGenericGetStaticBuffers MPU_xQueueGenericGetStaticBuffers
#define xQueueGenericSendFromISR MPU_xQueueGenericSendFromISR
#define xQueueGiveFromISR MPU_xQueueGiveFromISR
#define xQueuePeekFromISR MPU_xQueuePeekFromISR
#define xQueueReceiveFromISR MPU_xQueueReceiveFromISR
#define xQueueIsQueueEmptyFromISR MPU_xQueueIsQueueEmptyFromISR
#define xQueueIsQueueFullFromISR MPU_xQueueIsQueueFullFromISR
#define uxQueueMessagesWaitingFromISR MPU_uxQueueMessagesWaitingFromISR
#define xQueueGetMutexHolderFromISR MPU_xQueueGetMutexHolderFromISR
#define xQueueSelectFromSetFromISR MPU_xQueueSelectFromSetFromISR
#endif /* if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/* Map standard timer.h API functions to the MPU equivalents. */
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
#define vTimerSetTimerID MPU_vTimerSetTimerID
#define xTimerIsTimerActive MPU_xTimerIsTimerActive
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
#define xTimerGenericCommand MPU_xTimerGenericCommand
#define pcTimerGetName MPU_pcTimerGetName
#define vTimerSetReloadMode MPU_vTimerSetReloadMode
#define uxTimerGetReloadMode MPU_uxTimerGetReloadMode
#define xTimerGetPeriod MPU_xTimerGetPeriod
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define xTimerGetReloadMode MPU_xTimerGetReloadMode
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/* Privileged only wrappers for Timer APIs. These are needed so that
* the application can use opaque handles maintained in mpu_wrappers.c
* with all the APIs. */
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define xTimerCreate MPU_xTimerCreate
#define xTimerCreateStatic MPU_xTimerCreateStatic
#define xTimerGetStaticBuffer MPU_xTimerGetStaticBuffer
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/* Map standard event_group.h API functions to the MPU equivalents. */
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
#define xEventGroupClearBits MPU_xEventGroupClearBits
#define xEventGroupSetBits MPU_xEventGroupSetBits
#define xEventGroupSync MPU_xEventGroupSync
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
#define uxEventGroupGetNumber MPU_uxEventGroupGetNumber
#define vEventGroupSetNumber MPU_vEventGroupSetNumber
#endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */
/* Privileged only wrappers for Event Group APIs. These are needed so that
* the application can use opaque handles maintained in mpu_wrappers.c
* with all the APIs. */
#define xEventGroupCreate MPU_xEventGroupCreate
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
#define vEventGroupDelete MPU_vEventGroupDelete
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define xEventGroupGetStaticBuffer MPU_xEventGroupGetStaticBuffer
#define xEventGroupClearBitsFromISR MPU_xEventGroupClearBitsFromISR
#define xEventGroupSetBitsFromISR MPU_xEventGroupSetBitsFromISR
#define xEventGroupGetBitsFromISR MPU_xEventGroupGetBitsFromISR
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/* Map standard message/stream_buffer.h API functions to the MPU
* equivalents. */
#define xStreamBufferSend MPU_xStreamBufferSend
#define xStreamBufferReceive MPU_xStreamBufferReceive
#define xStreamBufferIsFull MPU_xStreamBufferIsFull
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
/* Privileged only wrappers for Stream Buffer APIs. These are needed so that
* the application can use opaque handles maintained in mpu_wrappers.c
* with all the APIs. */
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
#define vStreamBufferDelete MPU_vStreamBufferDelete
#define xStreamBufferReset MPU_xStreamBufferReset
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define xStreamBufferGetStaticBuffers MPU_xStreamBufferGetStaticBuffers
#define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR
#define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR
#define xStreamBufferSendCompletedFromISR MPU_xStreamBufferSendCompletedFromISR
#define xStreamBufferReceiveCompletedFromISR MPU_xStreamBufferReceiveCompletedFromISR
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
* macro so applications can place data in privileged access sections
* (useful when using statically allocated objects). */
#define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
#define FREERTOS_SYSTEM_CALL
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
macro so applications can place data in privileged access sections
(useful when using statically allocated objects). */
#define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
#define FREERTOS_SYSTEM_CALL
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #define vGrantAccessToTask( xTask, xTaskToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) )
#define vRevokeAccessToTask( xTask, xTaskToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToRevokeAccess ) )
/* Ensure API functions go in the privileged execution section. */ #define vGrantAccessToSemaphore( xTask, xSemaphoreToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToGrantAccess ) )
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) #define vRevokeAccessToSemaphore( xTask, xSemaphoreToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToRevokeAccess ) )
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls")))
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #define vGrantAccessToQueue( xTask, xQueueToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToGrantAccess ) )
#define vRevokeAccessToQueue( xTask, xQueueToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToRevokeAccess ) )
#define vGrantAccessToQueueSet( xTask, xQueueSetToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToGrantAccess ) )
#define vRevokeAccessToQueueSet( xTask, xQueueSetToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToRevokeAccess ) )
#define vGrantAccessToEventGroup( xTask, xEventGroupToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToGrantAccess ) )
#define vRevokeAccessToEventGroup( xTask, xEventGroupToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToRevokeAccess ) )
#define vGrantAccessToStreamBuffer( xTask, xStreamBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToGrantAccess ) )
#define vRevokeAccessToStreamBuffer( xTask, xStreamBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToRevokeAccess ) )
#define vGrantAccessToMessageBuffer( xTask, xMessageBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToGrantAccess ) )
#define vRevokeAccessToMessageBuffer( xTask, xMessageBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToRevokeAccess ) )
#define vGrantAccessToTimer( xTask, xTimerToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToGrantAccess ) )
#define vRevokeAccessToTimer( xTask, xTimerToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToRevokeAccess ) )
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
/* Ensure API functions go in the privileged execution section. */
#define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) )
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
#define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) )
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
#else /* portUSING_MPU_WRAPPERS */ #else /* portUSING_MPU_WRAPPERS */
#define PRIVILEGED_FUNCTION #define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA #define PRIVILEGED_DATA
#define FREERTOS_SYSTEM_CALL #define FREERTOS_SYSTEM_CALL
#define portUSING_MPU_WRAPPERS 0
#endif /* portUSING_MPU_WRAPPERS */ #endif /* portUSING_MPU_WRAPPERS */
#endif /* MPU_WRAPPERS_H */ #endif /* MPU_WRAPPERS_H */
@@ -0,0 +1,62 @@
/*
* FreeRTOS Kernel V10.6.2
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef INC_NEWLIB_FREERTOS_H
#define INC_NEWLIB_FREERTOS_H
/* Note Newlib support has been included by popular demand, but is not
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
* responsible for resulting newlib operation. User must be familiar with
* newlib and must provide system-wide implementations of the necessary
* stubs. Be warned that (at the time of writing) the current newlib design
* implements a system-wide malloc() that must be provided with locks.
*
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
* for additional information. */
#include <reent.h>
#define configUSE_C_RUNTIME_TLS_SUPPORT 1
#ifndef configTLS_BLOCK_TYPE
#define configTLS_BLOCK_TYPE struct _reent
#endif
#ifndef configINIT_TLS_BLOCK
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) _REENT_INIT_PTR( &( xTLSBlock ) )
#endif
#ifndef configSET_TLS_BLOCK
#define configSET_TLS_BLOCK( xTLSBlock ) ( _impure_ptr = &( xTLSBlock ) )
#endif
#ifndef configDEINIT_TLS_BLOCK
#define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) )
#endif
#endif /* INC_NEWLIB_FREERTOS_H */
@@ -0,0 +1,90 @@
/*
* FreeRTOS Kernel V10.6.2
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef INC_PICOLIBC_FREERTOS_H
#define INC_PICOLIBC_FREERTOS_H
/* Use picolibc TLS support to allocate space for __thread variables,
* initialize them at thread creation and set the TLS context at
* thread switch time.
*
* See the picolibc TLS docs:
* https://github.com/picolibc/picolibc/blob/main/doc/tls.md
* for additional information. */
#include <picotls.h>
#define configUSE_C_RUNTIME_TLS_SUPPORT 1
#define configTLS_BLOCK_TYPE void *
#define picolibcTLS_SIZE ( ( portPOINTER_SIZE_TYPE ) _tls_size() )
#define picolibcSTACK_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK )
#if __PICOLIBC_MAJOR__ > 1 || __PICOLIBC_MINOR__ >= 8
/* Picolibc 1.8 and newer have explicit alignment values provided
* by the _tls_align() inline */
#define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) ( _tls_align() - 1 ) )
#else
/* For older Picolibc versions, use the general port alignment value */
#define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK )
#endif
/* Allocate thread local storage block off the end of the
* stack. The _tls_size() function returns the size (in
* bytes) of the total TLS area used by the application */
#if ( portSTACK_GROWTH < 0 )
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \
do { \
pxTopOfStack = ( StackType_t * ) ( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) \
- picolibcTLS_SIZE ) & ~ \
configMAX( picolibcSTACK_ALIGNMENT_MASK, \
picolibcTLS_ALIGNMENT_MASK ) ); \
xTLSBlock = pxTopOfStack; \
_init_tls( xTLSBlock ); \
} while( 0 )
#else /* portSTACK_GROWTH */
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \
do { \
xTLSBlock = ( void * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack + \
picolibcTLS_ALIGNMENT_MASK ) & ~picolibcTLS_ALIGNMENT_MASK ); \
pxTopOfStack = ( StackType_t * ) ( ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) + \
picolibcTLS_SIZE ) + picolibcSTACK_ALIGNMENT_MASK ) & \
~picolibcSTACK_ALIGNMENT_MASK ); \
_init_tls( xTLSBlock ); \
} while( 0 )
#endif /* portSTACK_GROWTH */
#define configSET_TLS_BLOCK( xTLSBlock ) _set_tls( xTLSBlock )
#define configDEINIT_TLS_BLOCK( xTLSBlock )
#endif /* INC_PICOLIBC_FREERTOS_H */
+153 -81
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,83 +21,81 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Portable layer API. Each function must be defined for each port. * Portable layer API. Each function must be defined for each port.
*----------------------------------------------------------*/ *----------------------------------------------------------*/
#ifndef PORTABLE_H #ifndef PORTABLE_H
#define PORTABLE_H #define PORTABLE_H
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a /* Each FreeRTOS port has a unique portmacro.h header file. Originally a
pre-processor definition was used to ensure the pre-processor found the correct * pre-processor definition was used to ensure the pre-processor found the correct
portmacro.h file for the port being used. That scheme was deprecated in favour * portmacro.h file for the port being used. That scheme was deprecated in favour
of setting the compiler's include path such that it found the correct * of setting the compiler's include path such that it found the correct
portmacro.h file - removing the need for the constant and allowing the * portmacro.h file - removing the need for the constant and allowing the
portmacro.h file to be located anywhere in relation to the port being used. * portmacro.h file to be located anywhere in relation to the port being used.
Purely for reasons of backward compatibility the old method is still valid, but * Purely for reasons of backward compatibility the old method is still valid, but
to make it clear that new projects should not use it, support for the port * to make it clear that new projects should not use it, support for the port
specific constants has been moved into the deprecated_definitions.h header * specific constants has been moved into the deprecated_definitions.h header
file. */ * file. */
#include "deprecated_definitions.h" #include "deprecated_definitions.h"
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
did not result in a portmacro.h header file being included - and it should be * did not result in a portmacro.h header file being included - and it should be
included here. In this case the path to the correct portmacro.h header file * included here. In this case the path to the correct portmacro.h header file
must be set in the compiler's include path. */ * must be set in the compiler's include path. */
#ifndef portENTER_CRITICAL #ifndef portENTER_CRITICAL
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#if portBYTE_ALIGNMENT == 32 #if portBYTE_ALIGNMENT == 32
#define portBYTE_ALIGNMENT_MASK ( 0x001f ) #define portBYTE_ALIGNMENT_MASK ( 0x001f )
#endif #elif portBYTE_ALIGNMENT == 16
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
#elif portBYTE_ALIGNMENT == 8
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
#elif portBYTE_ALIGNMENT == 4
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
#elif portBYTE_ALIGNMENT == 2
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
#elif portBYTE_ALIGNMENT == 1
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
#else /* if portBYTE_ALIGNMENT == 32 */
#error "Invalid portBYTE_ALIGNMENT definition"
#endif /* if portBYTE_ALIGNMENT == 32 */
#if portBYTE_ALIGNMENT == 16 #ifndef portUSING_MPU_WRAPPERS
#define portBYTE_ALIGNMENT_MASK ( 0x000f ) #define portUSING_MPU_WRAPPERS 0
#endif
#if portBYTE_ALIGNMENT == 8
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
#endif
#if portBYTE_ALIGNMENT == 4
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
#endif
#if portBYTE_ALIGNMENT == 2
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
#endif
#if portBYTE_ALIGNMENT == 1
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
#endif
#ifndef portBYTE_ALIGNMENT_MASK
#error "Invalid portBYTE_ALIGNMENT definition"
#endif #endif
#ifndef portNUM_CONFIGURABLE_REGIONS #ifndef portNUM_CONFIGURABLE_REGIONS
#define portNUM_CONFIGURABLE_REGIONS 1 #define portNUM_CONFIGURABLE_REGIONS 1
#endif #endif
#ifndef portHAS_STACK_OVERFLOW_CHECKING #ifndef portHAS_STACK_OVERFLOW_CHECKING
#define portHAS_STACK_OVERFLOW_CHECKING 0 #define portHAS_STACK_OVERFLOW_CHECKING 0
#endif #endif
#ifndef portARCH_NAME #ifndef portARCH_NAME
#define portARCH_NAME NULL #define portARCH_NAME NULL
#endif #endif
#ifdef __cplusplus #ifndef configSTACK_ALLOCATION_FROM_SEPARATE_HEAP
extern "C" { /* Defaults to 0 for backward compatibility. */
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#endif #endif
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#include "mpu_wrappers.h" #include "mpu_wrappers.h"
/* /*
@@ -104,38 +104,52 @@ extern "C" {
* the order that the port expects to find them. * the order that the port expects to find them.
* *
*/ */
#if( portUSING_MPU_WRAPPERS == 1 ) #if ( portUSING_MPU_WRAPPERS == 1 )
#if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
#else StackType_t * pxEndOfStack,
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; TaskFunction_t pxCode,
#endif void * pvParameters,
#else BaseType_t xRunPrivileged,
#if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION;
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; #else
#else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; TaskFunction_t pxCode,
#endif void * pvParameters,
#endif BaseType_t xRunPrivileged,
xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION;
#endif /* if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) */
#else /* if ( portUSING_MPU_WRAPPERS == 1 ) */
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters ) PRIVILEGED_FUNCTION;
#else
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters ) PRIVILEGED_FUNCTION;
#endif
#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */
/* Used by heap_5.c to define the start address and size of each memory region /* Used by heap_5.c to define the start address and size of each memory region
that together comprise the total FreeRTOS heap space. */ * that together comprise the total FreeRTOS heap space. */
typedef struct HeapRegion typedef struct HeapRegion
{ {
uint8_t *pucStartAddress; uint8_t * pucStartAddress;
size_t xSizeInBytes; size_t xSizeInBytes;
} HeapRegion_t; } HeapRegion_t;
/* Used to pass information about the heap out of vPortGetHeapStats(). */ /* Used to pass information about the heap out of vPortGetHeapStats(). */
typedef struct xHeapStats typedef struct xHeapStats
{ {
size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */ size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */
size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */ size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */
size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */ size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */
size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */ size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */
} HeapStats_t; } HeapStats_t;
/* /*
@@ -155,17 +169,40 @@ void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEG
* Returns a HeapStats_t structure filled with information about the current * Returns a HeapStats_t structure filled with information about the current
* heap state. * heap state.
*/ */
void vPortGetHeapStats( HeapStats_t *pxHeapStats ); void vPortGetHeapStats( HeapStats_t * pxHeapStats );
/* /*
* Map to the memory management routines required for the port. * Map to the memory management routines required for the port.
*/ */
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; void * pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFree( void *pv ) PRIVILEGED_FUNCTION; void * pvPortCalloc( size_t xNum,
size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFree( void * pv ) PRIVILEGED_FUNCTION;
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
#if ( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 )
void * pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFreeStack( void * pv ) PRIVILEGED_FUNCTION;
#else
#define pvPortMallocStack pvPortMalloc
#define vPortFreeStack vPortFree
#endif
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
/**
* task.h
* @code{c}
* void vApplicationMallocFailedHook( void )
* @endcode
*
* This hook function is called when allocation failed.
*/
void vApplicationMallocFailedHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */
#endif
/* /*
* Setup the hardware ready for the scheduler to take control. This generally * Setup the hardware ready for the scheduler to take control. This generally
* sets up a tick interrupt and sets timers for the correct tick frequency. * sets up a tick interrupt and sets timers for the correct tick frequency.
@@ -186,14 +223,49 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
* Fills the xMPUSettings structure with the memory region information * Fills the xMPUSettings structure with the memory region information
* contained in xRegions. * contained in xRegions.
*/ */
#if( portUSING_MPU_WRAPPERS == 1 ) #if ( portUSING_MPU_WRAPPERS == 1 )
struct xMEMORY_REGION; struct xMEMORY_REGION;
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
#endif #endif
#ifdef __cplusplus /**
} * @brief Checks if the calling task is authorized to access the given buffer.
*
* @param pvBuffer The buffer which the calling task wants to access.
* @param ulBufferLength The length of the pvBuffer.
* @param ulAccessRequested The permissions that the calling task wants.
*
* @return pdTRUE if the calling task is authorized to access the buffer,
* pdFALSE otherwise.
*/
#if ( portUSING_MPU_WRAPPERS == 1 )
BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
uint32_t ulBufferLength,
uint32_t ulAccessRequested ) PRIVILEGED_FUNCTION;
#endif #endif
/**
* @brief Checks if the calling task is authorized to access the given kernel object.
*
* @param lInternalIndexOfKernelObject The index of the kernel object in the kernel
* object handle pool.
*
* @return pdTRUE if the calling task is authorized to access the kernel object,
* pdFALSE otherwise.
*/
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION;
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* PORTABLE_H */ #endif /* PORTABLE_H */
+78 -71
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#ifndef PROJDEFS_H #ifndef PROJDEFS_H
@@ -32,93 +33,99 @@
* Defines the prototype to which task functions must conform. Defined in this * Defines the prototype to which task functions must conform. Defined in this
* file to ensure the type is known before portable.h is included. * file to ensure the type is known before portable.h is included.
*/ */
typedef void (*TaskFunction_t)( void * ); typedef void (* TaskFunction_t)( void * );
/* Converts a time in milliseconds to a time in ticks. This macro can be /* Converts a time in milliseconds to a time in ticks. This macro can be
overridden by a macro of the same name defined in FreeRTOSConfig.h in case the * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
definition here is not suitable for your application. */ * definition here is not suitable for your application. */
#ifndef pdMS_TO_TICKS #ifndef pdMS_TO_TICKS
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000U ) )
#endif #endif
#define pdFALSE ( ( BaseType_t ) 0 ) #define pdFALSE ( ( BaseType_t ) 0 )
#define pdTRUE ( ( BaseType_t ) 1 ) #define pdTRUE ( ( BaseType_t ) 1 )
#define pdFALSE_SIGNED ( ( BaseType_t ) 0 )
#define pdTRUE_SIGNED ( ( BaseType_t ) 1 )
#define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0 )
#define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1 )
#define pdPASS ( pdTRUE ) #define pdPASS ( pdTRUE )
#define pdFAIL ( pdFALSE ) #define pdFAIL ( pdFALSE )
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) #define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
#define errQUEUE_FULL ( ( BaseType_t ) 0 ) #define errQUEUE_FULL ( ( BaseType_t ) 0 )
/* FreeRTOS error definitions. */ /* FreeRTOS error definitions. */
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
#define errQUEUE_BLOCKED ( -4 ) #define errQUEUE_BLOCKED ( -4 )
#define errQUEUE_YIELD ( -5 ) #define errQUEUE_YIELD ( -5 )
/* Macros used for basic data corruption checks. */ /* Macros used for basic data corruption checks. */
#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
#endif #endif
#if( configUSE_16_BIT_TICKS == 1 ) #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
#define pdINTEGRITY_CHECK_VALUE 0x5a5a #define pdINTEGRITY_CHECK_VALUE 0x5a5a
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5a5a5a5a5aULL
#else #else
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif #endif
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS /* The following errno values are used by FreeRTOS+ components, not FreeRTOS
itself. */ * itself. */
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ #define pdFREERTOS_ERRNO_NONE 0 /* No errors */
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ #define pdFREERTOS_ERRNO_EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS /* The following endian values are used by FreeRTOS+ components, not FreeRTOS
itself. */ * itself. */
#define pdFREERTOS_LITTLE_ENDIAN 0 #define pdFREERTOS_LITTLE_ENDIAN 0
#define pdFREERTOS_BIG_ENDIAN 1 #define pdFREERTOS_BIG_ENDIAN 1
/* Re-defining endian values for generic naming. */ /* Re-defining endian values for generic naming. */
#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN #define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN
#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN #define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN
#endif /* PROJDEFS_H */ #endif /* PROJDEFS_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#ifndef STACK_MACROS_H #ifndef STACK_MACROS_H
@@ -44,86 +45,93 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) /*
* portSTACK_LIMIT_PADDING is a number of extra words to consider to be in
* use on the stack.
*/
#ifndef portSTACK_LIMIT_PADDING
#define portSTACK_LIMIT_PADDING 0
#endif
/* Only the current stack state is to be checked. */ #if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \
{ \ /* Only the current stack state is to be checked. */
/* Is the currently saved stack pointer within the stack limit? */ \ #define taskCHECK_FOR_STACK_OVERFLOW() \
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ do { \
{ \ /* Is the currently saved stack pointer within the stack limit? */ \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
} \ { \
} vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
} while( 0 )
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) #if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
/* Only the current stack state is to be checked. */ /* Only the current stack state is to be checked. */
#define taskCHECK_FOR_STACK_OVERFLOW() \ #define taskCHECK_FOR_STACK_OVERFLOW() \
{ \ do { \
\ \
/* Is the currently saved stack pointer within the stack limit? */ \ /* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} } while( 0 )
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \ #define taskCHECK_FOR_STACK_OVERFLOW() \
{ \ do { \
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
\ \
if( ( pulStack[ 0 ] != ulCheckValue ) || \ if( ( pulStack[ 0 ] != ulCheckValue ) || \
( pulStack[ 1 ] != ulCheckValue ) || \ ( pulStack[ 1 ] != ulCheckValue ) || \
( pulStack[ 2 ] != ulCheckValue ) || \ ( pulStack[ 2 ] != ulCheckValue ) || \
( pulStack[ 3 ] != ulCheckValue ) ) \ ( pulStack[ 3 ] != ulCheckValue ) ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} } while( 0 )
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \ #define taskCHECK_FOR_STACK_OVERFLOW() \
{ \ do { \
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
\ \
\ \
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
\ \
/* Has the extremity of the task stack ever been written over? */ \ /* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} } while( 0 )
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Remove stack overflow macro if not being used. */ /* Remove stack overflow macro if not being used. */
#ifndef taskCHECK_FOR_STACK_OVERFLOW #ifndef taskCHECK_FOR_STACK_OVERFLOW
#define taskCHECK_FOR_STACK_OVERFLOW() #define taskCHECK_FOR_STACK_OVERFLOW()
#endif #endif
#endif /* STACK_MACROS_H */ #endif /* STACK_MACROS_H */
+358 -272
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/* /*
@@ -52,12 +53,14 @@
#define STREAM_BUFFER_H #define STREAM_BUFFER_H
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include stream_buffer.h" #error "include FreeRTOS.h must appear in source files before include stream_buffer.h"
#endif #endif
/* *INDENT-OFF* */
#if defined( __cplusplus ) #if defined( __cplusplus )
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/** /**
* Type by which stream buffers are referenced. For example, a call to * Type by which stream buffers are referenced. For example, a call to
@@ -68,13 +71,19 @@ extern "C" {
struct StreamBufferDef_t; struct StreamBufferDef_t;
typedef struct StreamBufferDef_t * StreamBufferHandle_t; typedef struct StreamBufferDef_t * StreamBufferHandle_t;
/**
* Type used as a stream buffer's optional callback.
*/
typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuffer,
BaseType_t xIsInsideISR,
BaseType_t * const pxHigherPriorityTaskWoken );
/** /**
* message_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes ); * StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
</pre> * @endcode
* *
* Creates a new stream buffer using dynamically allocated memory. See * Creates a new stream buffer using dynamically allocated memory. See
* xStreamBufferCreateStatic() for a version that uses statically allocated * xStreamBufferCreateStatic() for a version that uses statically allocated
@@ -100,6 +109,16 @@ StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTrigg
* trigger level of 1 being used. It is not valid to specify a trigger level * trigger level of 1 being used. It is not valid to specify a trigger level
* that is greater than the buffer size. * that is greater than the buffer size.
* *
* @param pxSendCompletedCallback Callback invoked when number of bytes at least equal to
* trigger level is sent to the stream buffer. If the parameter is NULL, it will use the default
* implementation provided by sbSEND_COMPLETED macro. To enable the callback,
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
*
* @param pxReceiveCompletedCallback Callback invoked when more than zero bytes are read from a
* stream buffer. If the parameter is NULL, it will use the default
* implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback,
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
*
* @return If NULL is returned, then the stream buffer cannot be created * @return If NULL is returned, then the stream buffer cannot be created
* because there is insufficient heap memory available for FreeRTOS to allocate * because there is insufficient heap memory available for FreeRTOS to allocate
* the stream buffer data structures and storage area. A non-NULL value being * the stream buffer data structures and storage area. A non-NULL value being
@@ -108,43 +127,50 @@ StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTrigg
* buffer. * buffer.
* *
* Example use: * Example use:
<pre> * @code{c}
*
void vAFunction( void ) * void vAFunction( void )
{ * {
StreamBufferHandle_t xStreamBuffer; * StreamBufferHandle_t xStreamBuffer;
const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10; * const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
*
// Create a stream buffer that can hold 100 bytes. The memory used to hold * // Create a stream buffer that can hold 100 bytes. The memory used to hold
// both the stream buffer structure and the data in the stream buffer is * // both the stream buffer structure and the data in the stream buffer is
// allocated dynamically. * // allocated dynamically.
xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); * xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
*
if( xStreamBuffer == NULL ) * if( xStreamBuffer == NULL )
{ * {
// There was not enough heap memory space available to create the * // There was not enough heap memory space available to create the
// stream buffer. * // stream buffer.
} * }
else * else
{ * {
// The stream buffer was created successfully and can now be used. * // The stream buffer was created successfully and can now be used.
} * }
} * }
</pre> * @endcode
* \defgroup xStreamBufferCreate xStreamBufferCreate * \defgroup xStreamBufferCreate xStreamBufferCreate
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE )
#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) \
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, NULL, NULL )
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
#define xStreamBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
#endif
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes, * StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes, * size_t xTriggerLevelBytes,
uint8_t *pucStreamBufferStorageArea, * uint8_t *pucStreamBufferStorageArea,
StaticStreamBuffer_t *pxStaticStreamBuffer ); * StaticStreamBuffer_t *pxStaticStreamBuffer );
</pre> * @endcode
* Creates a new stream buffer using statically allocated memory. See * Creates a new stream buffer using statically allocated memory. See
* xStreamBufferCreate() for a version that uses dynamically allocated memory. * xStreamBufferCreate() for a version that uses dynamically allocated memory.
* *
@@ -169,63 +195,112 @@ StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
* that is greater than the buffer size. * that is greater than the buffer size.
* *
* @param pucStreamBufferStorageArea Must point to a uint8_t array that is at * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at
* least xBufferSizeBytes + 1 big. This is the array to which streams are * least xBufferSizeBytes big. This is the array to which streams are
* copied when they are written to the stream buffer. * copied when they are written to the stream buffer.
* *
* @param pxStaticStreamBuffer Must point to a variable of type * @param pxStaticStreamBuffer Must point to a variable of type
* StaticStreamBuffer_t, which will be used to hold the stream buffer's data * StaticStreamBuffer_t, which will be used to hold the stream buffer's data
* structure. * structure.
* *
* @param pxSendCompletedCallback Callback invoked when number of bytes at least equal to
* trigger level is sent to the stream buffer. If the parameter is NULL, it will use the default
* implementation provided by sbSEND_COMPLETED macro. To enable the callback,
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
*
* @param pxReceiveCompletedCallback Callback invoked when more than zero bytes are read from a
* stream buffer. If the parameter is NULL, it will use the default
* implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback,
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
*
* @return If the stream buffer is created successfully then a handle to the * @return If the stream buffer is created successfully then a handle to the
* created stream buffer is returned. If either pucStreamBufferStorageArea or * created stream buffer is returned. If either pucStreamBufferStorageArea or
* pxStaticstreamBuffer are NULL then NULL is returned. * pxStaticstreamBuffer are NULL then NULL is returned.
* *
* Example use: * Example use:
<pre> * @code{c}
*
// Used to dimension the array used to hold the streams. The available space * // Used to dimension the array used to hold the streams. The available space
// will actually be one less than this, so 999. * // will actually be one less than this, so 999.
#define STORAGE_SIZE_BYTES 1000 #define STORAGE_SIZE_BYTES 1000
*
// Defines the memory that will actually hold the streams within the stream * // Defines the memory that will actually hold the streams within the stream
// buffer. * // buffer.
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
*
// The variable used to hold the stream buffer structure. * // The variable used to hold the stream buffer structure.
StaticStreamBuffer_t xStreamBufferStruct; * StaticStreamBuffer_t xStreamBufferStruct;
*
void MyFunction( void ) * void MyFunction( void )
{ * {
StreamBufferHandle_t xStreamBuffer; * StreamBufferHandle_t xStreamBuffer;
const size_t xTriggerLevel = 1; * const size_t xTriggerLevel = 1;
*
xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ), * xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucStorageBuffer ),
xTriggerLevel, * xTriggerLevel,
ucBufferStorage, * ucStorageBuffer,
&xStreamBufferStruct ); * &xStreamBufferStruct );
*
// As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer * // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
// parameters were NULL, xStreamBuffer will not be NULL, and can be used to * // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
// reference the created stream buffer in other stream buffer API calls. * // reference the created stream buffer in other stream buffer API calls.
*
// Other code that uses the stream buffer can go here. * // Other code that uses the stream buffer can go here.
} * }
*
</pre> * @endcode
* \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL )
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
#define xStreamBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
#endif
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, * BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
const void *pvTxData, * uint8_t ** ppucStreamBufferStorageArea,
size_t xDataLengthBytes, * StaticStreamBuffer_t ** ppxStaticStreamBuffer );
TickType_t xTicksToWait ); * @endcode
</pre> *
* Retrieve pointers to a statically created stream buffer's data structure
* buffer and storage area buffer. These are the same buffers that are supplied
* at the time of creation.
*
* @param xStreamBuffer The stream buffer for which to retrieve the buffers.
*
* @param ppucStreamBufferStorageArea Used to return a pointer to the stream
* buffer's storage area buffer.
*
* @param ppxStaticStreamBuffer Used to return a pointer to the stream
* buffer's data structure buffer.
*
* @return pdTRUE if buffers were retrieved, pdFALSE otherwise.
*
* \defgroup xStreamBufferGetStaticBuffers xStreamBufferGetStaticBuffers
* \ingroup StreamBufferManagement
*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
uint8_t ** ppucStreamBufferStorageArea,
StaticStreamBuffer_t ** ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
#endif /* configSUPPORT_STATIC_ALLOCATION */
/**
* stream_buffer.h
*
* @code{c}
* size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
* const void *pvTxData,
* size_t xDataLengthBytes,
* TickType_t xTicksToWait );
* @endcode
* *
* Sends bytes to a stream buffer. The bytes are copied into the stream buffer. * Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
* *
@@ -275,54 +350,54 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
* write as many bytes as possible. * write as many bytes as possible.
* *
* Example use: * Example use:
<pre> * @code{c}
void vAFunction( StreamBufferHandle_t xStreamBuffer ) * void vAFunction( StreamBufferHandle_t xStreamBuffer )
{ * {
size_t xBytesSent; * size_t xBytesSent;
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
char *pcStringToSend = "String to send"; * char *pcStringToSend = "String to send";
const TickType_t x100ms = pdMS_TO_TICKS( 100 ); * const TickType_t x100ms = pdMS_TO_TICKS( 100 );
*
// Send an array to the stream buffer, blocking for a maximum of 100ms to * // Send an array to the stream buffer, blocking for a maximum of 100ms to
// wait for enough space to be available in the stream buffer. * // wait for enough space to be available in the stream buffer.
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
*
if( xBytesSent != sizeof( ucArrayToSend ) ) * if( xBytesSent != sizeof( ucArrayToSend ) )
{ * {
// The call to xStreamBufferSend() times out before there was enough * // The call to xStreamBufferSend() times out before there was enough
// space in the buffer for the data to be written, but it did * // space in the buffer for the data to be written, but it did
// successfully write xBytesSent bytes. * // successfully write xBytesSent bytes.
} * }
*
// Send the string to the stream buffer. Return immediately if there is not * // Send the string to the stream buffer. Return immediately if there is not
// enough space in the buffer. * // enough space in the buffer.
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
*
if( xBytesSent != strlen( pcStringToSend ) ) * if( xBytesSent != strlen( pcStringToSend ) )
{ * {
// The entire string could not be added to the stream buffer because * // The entire string could not be added to the stream buffer because
// there was not enough free space in the buffer, but xBytesSent bytes * // there was not enough free space in the buffer, but xBytesSent bytes
// were sent. Could try again to send the remaining bytes. * // were sent. Could try again to send the remaining bytes.
} * }
} * }
</pre> * @endcode
* \defgroup xStreamBufferSend xStreamBufferSend * \defgroup xStreamBufferSend xStreamBufferSend
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
const void *pvTxData, const void * pvTxData,
size_t xDataLengthBytes, size_t xDataLengthBytes,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, * size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
const void *pvTxData, * const void *pvTxData,
size_t xDataLengthBytes, * size_t xDataLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
</pre> * @endcode
* *
* Interrupt safe version of the API function that sends a stream of bytes to * Interrupt safe version of the API function that sends a stream of bytes to
* the stream buffer. * the stream buffer.
@@ -374,56 +449,56 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
* space for all the bytes to be written. * space for all the bytes to be written.
* *
* Example use: * Example use:
<pre> * @code{c}
// A stream buffer that has already been created. * // A stream buffer that has already been created.
StreamBufferHandle_t xStreamBuffer; * StreamBufferHandle_t xStreamBuffer;
*
void vAnInterruptServiceRoutine( void ) * void vAnInterruptServiceRoutine( void )
{ * {
size_t xBytesSent; * size_t xBytesSent;
char *pcStringToSend = "String to send"; * char *pcStringToSend = "String to send";
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
*
// Attempt to send the string to the stream buffer. * // Attempt to send the string to the stream buffer.
xBytesSent = xStreamBufferSendFromISR( xStreamBuffer, * xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
( void * ) pcStringToSend, * ( void * ) pcStringToSend,
strlen( pcStringToSend ), * strlen( pcStringToSend ),
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
if( xBytesSent != strlen( pcStringToSend ) ) * if( xBytesSent != strlen( pcStringToSend ) )
{ * {
// There was not enough free space in the stream buffer for the entire * // There was not enough free space in the stream buffer for the entire
// string to be written, ut xBytesSent bytes were written. * // string to be written, ut xBytesSent bytes were written.
} * }
*
// If xHigherPriorityTaskWoken was set to pdTRUE inside * // If xHigherPriorityTaskWoken was set to pdTRUE inside
// xStreamBufferSendFromISR() then a task that has a priority above the * // xStreamBufferSendFromISR() then a task that has a priority above the
// priority of the currently executing task was unblocked and a context * // priority of the currently executing task was unblocked and a context
// switch should be performed to ensure the ISR returns to the unblocked * // switch should be performed to ensure the ISR returns to the unblocked
// task. In most FreeRTOS ports this is done by simply passing * // task. In most FreeRTOS ports this is done by simply passing
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
// variables value, and perform the context switch if necessary. Check the * // variables value, and perform the context switch if necessary. Check the
// documentation for the port in use for port specific instructions. * // documentation for the port in use for port specific instructions.
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
</pre> * @endcode
* \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
const void *pvTxData, const void * pvTxData,
size_t xDataLengthBytes, size_t xDataLengthBytes,
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
void *pvRxData, * void *pvRxData,
size_t xBufferLengthBytes, * size_t xBufferLengthBytes,
TickType_t xTicksToWait ); * TickType_t xTicksToWait );
</pre> * @endcode
* *
* Receives bytes from a stream buffer. * Receives bytes from a stream buffer.
* *
@@ -473,46 +548,46 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
* out before xBufferLengthBytes were available. * out before xBufferLengthBytes were available.
* *
* Example use: * Example use:
<pre> * @code{c}
void vAFunction( StreamBuffer_t xStreamBuffer ) * void vAFunction( StreamBuffer_t xStreamBuffer )
{ * {
uint8_t ucRxData[ 20 ]; * uint8_t ucRxData[ 20 ];
size_t xReceivedBytes; * size_t xReceivedBytes;
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
*
// Receive up to another sizeof( ucRxData ) bytes from the stream buffer. * // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
// Wait in the Blocked state (so not using any CPU processing time) for a * // Wait in the Blocked state (so not using any CPU processing time) for a
// maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be * // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
// available. * // available.
xReceivedBytes = xStreamBufferReceive( xStreamBuffer, * xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
( void * ) ucRxData, * ( void * ) ucRxData,
sizeof( ucRxData ), * sizeof( ucRxData ),
xBlockTime ); * xBlockTime );
*
if( xReceivedBytes > 0 ) * if( xReceivedBytes > 0 )
{ * {
// A ucRxData contains another xRecievedBytes bytes of data, which can * // A ucRxData contains another xReceivedBytes bytes of data, which can
// be processed here.... * // be processed here....
} * }
} * }
</pre> * @endcode
* \defgroup xStreamBufferReceive xStreamBufferReceive * \defgroup xStreamBufferReceive xStreamBufferReceive
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
void *pvRxData, void * pvRxData,
size_t xBufferLengthBytes, size_t xBufferLengthBytes,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, * size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
void *pvRxData, * void *pvRxData,
size_t xBufferLengthBytes, * size_t xBufferLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
</pre> * @endcode
* *
* An interrupt safe version of the API function that receives bytes from a * An interrupt safe version of the API function that receives bytes from a
* stream buffer. * stream buffer.
@@ -549,53 +624,53 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
* @return The number of bytes read from the stream buffer, if any. * @return The number of bytes read from the stream buffer, if any.
* *
* Example use: * Example use:
<pre> * @code{c}
// A stream buffer that has already been created. * // A stream buffer that has already been created.
StreamBuffer_t xStreamBuffer; * StreamBuffer_t xStreamBuffer;
*
void vAnInterruptServiceRoutine( void ) * void vAnInterruptServiceRoutine( void )
{ * {
uint8_t ucRxData[ 20 ]; * uint8_t ucRxData[ 20 ];
size_t xReceivedBytes; * size_t xReceivedBytes;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
*
// Receive the next stream from the stream buffer. * // Receive the next stream from the stream buffer.
xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, * xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
( void * ) ucRxData, * ( void * ) ucRxData,
sizeof( ucRxData ), * sizeof( ucRxData ),
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
if( xReceivedBytes > 0 ) * if( xReceivedBytes > 0 )
{ * {
// ucRxData contains xReceivedBytes read from the stream buffer. * // ucRxData contains xReceivedBytes read from the stream buffer.
// Process the stream here.... * // Process the stream here....
} * }
*
// If xHigherPriorityTaskWoken was set to pdTRUE inside * // If xHigherPriorityTaskWoken was set to pdTRUE inside
// xStreamBufferReceiveFromISR() then a task that has a priority above the * // xStreamBufferReceiveFromISR() then a task that has a priority above the
// priority of the currently executing task was unblocked and a context * // priority of the currently executing task was unblocked and a context
// switch should be performed to ensure the ISR returns to the unblocked * // switch should be performed to ensure the ISR returns to the unblocked
// task. In most FreeRTOS ports this is done by simply passing * // task. In most FreeRTOS ports this is done by simply passing
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
// variables value, and perform the context switch if necessary. Check the * // variables value, and perform the context switch if necessary. Check the
// documentation for the port in use for port specific instructions. * // documentation for the port in use for port specific instructions.
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
</pre> * @endcode
* \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
void *pvRxData, void * pvRxData,
size_t xBufferLengthBytes, size_t xBufferLengthBytes,
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ); * void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
</pre> * @endcode
* *
* Deletes a stream buffer that was previously created using a call to * Deletes a stream buffer that was previously created using a call to
* xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream
@@ -615,9 +690,9 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ); * BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
</pre> * @endcode
* *
* Queries a stream buffer to see if it is full. A stream buffer is full if it * Queries a stream buffer to see if it is full. A stream buffer is full if it
* does not have any free space, and therefore cannot accept any more data. * does not have any free space, and therefore cannot accept any more data.
@@ -635,9 +710,9 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ); * BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
</pre> * @endcode
* *
* Queries a stream buffer to see if it is empty. A stream buffer is empty if * Queries a stream buffer to see if it is empty. A stream buffer is empty if
* it does not contain any data. * it does not contain any data.
@@ -655,9 +730,9 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ); * BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
</pre> * @endcode
* *
* Resets a stream buffer to its initial, empty, state. Any data that was in * Resets a stream buffer to its initial, empty, state. Any data that was in
* the stream buffer is discarded. A stream buffer can only be reset if there * the stream buffer is discarded. A stream buffer can only be reset if there
@@ -678,9 +753,9 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ); * size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
</pre> * @endcode
* *
* Queries a stream buffer to see how much free space it contains, which is * Queries a stream buffer to see how much free space it contains, which is
* equal to the amount of data that can be sent to the stream buffer before it * equal to the amount of data that can be sent to the stream buffer before it
@@ -699,9 +774,9 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ); * size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
</pre> * @endcode
* *
* Queries a stream buffer to see how much data it contains, which is equal to * Queries a stream buffer to see how much data it contains, which is equal to
* the number of bytes that can be read from the stream buffer before the stream * the number of bytes that can be read from the stream buffer before the stream
@@ -720,9 +795,9 @@ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILE
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ); * BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
</pre> * @endcode
* *
* A stream buffer's trigger level is the number of bytes that must be in the * A stream buffer's trigger level is the number of bytes that must be in the
* stream buffer before a task that is blocked on the stream buffer to * stream buffer before a task that is blocked on the stream buffer to
@@ -752,14 +827,15 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, siz
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * @endcode
* *
* For advanced users only. * For advanced users only.
* *
@@ -791,14 +867,15 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * @code{c}
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * @endcode
* *
* For advanced users only. * For advanced users only.
* *
@@ -831,29 +908,38 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/* Functions below here are not part of the public API. */ /* Functions below here are not part of the public API. */
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes, size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION; BaseType_t xIsMessageBuffer,
StreamBufferCallbackFunction_t pxSendCompletedCallback,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes, size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer, BaseType_t xIsMessageBuffer,
uint8_t * const pucStreamBufferStorageArea, uint8_t * const pucStreamBufferStorageArea,
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION; StaticStreamBuffer_t * const pxStaticStreamBuffer,
StreamBufferCallbackFunction_t pxSendCompletedCallback,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
#if( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer,
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
#endif #endif
/* *INDENT-OFF* */
#if defined( __cplusplus ) #if defined( __cplusplus )
} }
#endif #endif
/* *INDENT-ON* */
#endif /* !defined( STREAM_BUFFER_H ) */ #endif /* !defined( STREAM_BUFFER_H ) */
File diff suppressed because it is too large Load Diff
+274 -180
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
@@ -30,41 +31,43 @@
#define TIMERS_H #define TIMERS_H
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
#error "include FreeRTOS.h must appear in source files before include timers.h" #error "include FreeRTOS.h must appear in source files before include timers.h"
#endif #endif
/*lint -save -e537 This headers are only multiply included if the application code /*lint -save -e537 This headers are only multiply included if the application code
happens to also be including task.h. */ * happens to also be including task.h. */
#include "task.h" #include "task.h"
/*lint -restore */ /*lint -restore */
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* MACROS AND DEFINITIONS * MACROS AND DEFINITIONS
*----------------------------------------------------------*/ *----------------------------------------------------------*/
/* IDs for commands that can be sent/received on the timer queue. These are to /* IDs for commands that can be sent/received on the timer queue. These are to
be used solely through the macros that make up the public software timer API, * be used solely through the macros that make up the public software timer API,
as defined below. The commands that are sent from interrupts must use the * as defined below. The commands that are sent from interrupts must use the
highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task * highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
or interrupt version of the queue send function should be used. */ * or interrupt version of the queue send function should be used. */
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) #define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )
#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) #define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )
#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) #define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )
#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) #define tmrCOMMAND_START ( ( BaseType_t ) 1 )
#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) #define tmrCOMMAND_RESET ( ( BaseType_t ) 2 )
#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) #define tmrCOMMAND_STOP ( ( BaseType_t ) 3 )
#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) #define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 )
#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) #define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 )
#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) #define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 )
#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) #define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 )
#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) #define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 )
#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) #define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 )
#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) #define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 )
/** /**
@@ -79,20 +82,21 @@ typedef struct tmrTimerControl * TimerHandle_t;
/* /*
* Defines the prototype to which timer callback functions must conform. * Defines the prototype to which timer callback functions must conform.
*/ */
typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer );
/* /*
* Defines the prototype to which functions used with the * Defines the prototype to which functions used with the
* xTimerPendFunctionCallFromISR() function must conform. * xTimerPendFunctionCallFromISR() function must conform.
*/ */
typedef void (*PendedFunction_t)( void *, uint32_t ); typedef void (* PendedFunction_t)( void *,
uint32_t );
/** /**
* TimerHandle_t xTimerCreate( const char * const pcTimerName, * TimerHandle_t xTimerCreate( const char * const pcTimerName,
* TickType_t xTimerPeriodInTicks, * TickType_t xTimerPeriodInTicks,
* UBaseType_t uxAutoReload, * BaseType_t xAutoReload,
* void * pvTimerID, * void * pvTimerID,
* TimerCallbackFunction_t pxCallbackFunction ); * TimerCallbackFunction_t pxCallbackFunction );
* *
* Creates a new software timer instance, and returns a handle by which the * Creates a new software timer instance, and returns a handle by which the
* created software timer can be referenced. * created software timer can be referenced.
@@ -101,7 +105,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* of memory, in which the timer data structure is stored. If a software timer * of memory, in which the timer data structure is stored. If a software timer
* is created using xTimerCreate() then the required memory is automatically * is created using xTimerCreate() then the required memory is automatically
* dynamically allocated inside the xTimerCreate() function. (see * dynamically allocated inside the xTimerCreate() function. (see
* http://www.freertos.org/a00111.html). If a software timer is created using * https://www.FreeRTOS.org/a00111.html). If a software timer is created using
* xTimerCreateStatic() then the application writer must provide the memory that * xTimerCreateStatic() then the application writer must provide the memory that
* will get used by the software timer. xTimerCreateStatic() therefore allows a * will get used by the software timer. xTimerCreateStatic() therefore allows a
* software timer to be created without using any dynamic memory allocation. * software timer to be created without using any dynamic memory allocation.
@@ -123,9 +127,9 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or
* equal to 1000. Time timer period must be greater than 0. * equal to 1000. Time timer period must be greater than 0.
* *
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will
* expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.
* If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and * If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and
* enter the dormant state after it expires. * enter the dormant state after it expires.
* *
* @param pvTimerID An identifier that is assigned to the timer being created. * @param pvTimerID An identifier that is assigned to the timer being created.
@@ -135,7 +139,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* *
* @param pxCallbackFunction The function to call when the timer expires. * @param pxCallbackFunction The function to call when the timer expires.
* Callback functions must have the prototype defined by TimerCallbackFunction_t, * Callback functions must have the prototype defined by TimerCallbackFunction_t,
* which is "void vCallbackFunction( TimerHandle_t xTimer );". * which is "void vCallbackFunction( TimerHandle_t xTimer );".
* *
* @return If the timer is successfully created then a handle to the newly * @return If the timer is successfully created then a handle to the newly
* created timer is returned. If the timer cannot be created because there is * created timer is returned. If the timer cannot be created because there is
@@ -161,8 +165,8 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* int32_t lArrayIndex; * int32_t lArrayIndex;
* const int32_t xMaxExpiryCountBeforeStopping = 10; * const int32_t xMaxExpiryCountBeforeStopping = 10;
* *
* // Optionally do something if the pxTimer parameter is NULL. * // Optionally do something if the pxTimer parameter is NULL.
* configASSERT( pxTimer ); * configASSERT( pxTimer );
* *
* // Which timer expired? * // Which timer expired?
* lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer );
@@ -188,11 +192,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* // the scheduler starts. * // the scheduler starts.
* for( x = 0; x < NUM_TIMERS; x++ ) * for( x = 0; x < NUM_TIMERS; x++ )
* { * {
* xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.
* ( 100 * x ), // The timer period in ticks. * ( 100 * ( x + 1 ) ), // The timer period in ticks.
* pdTRUE, // The timers will auto-reload themselves when they expire. * pdTRUE, // The timers will auto-reload themselves when they expire.
* ( void * ) x, // Assign each timer a unique id equal to its array index. * ( void * ) x, // Assign each timer a unique id equal to its array index.
* vTimerCallback // Each timer calls the same callback when it expires. * vTimerCallback // Each timer calls the same callback when it expires.
* ); * );
* *
* if( xTimers[ x ] == NULL ) * if( xTimers[ x ] == NULL )
@@ -224,21 +228,21 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* } * }
* @endverbatim * @endverbatim
*/ */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const BaseType_t xAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
#endif #endif
/** /**
* TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
* TickType_t xTimerPeriodInTicks, * TickType_t xTimerPeriodInTicks,
* UBaseType_t uxAutoReload, * BaseType_t xAutoReload,
* void * pvTimerID, * void * pvTimerID,
* TimerCallbackFunction_t pxCallbackFunction, * TimerCallbackFunction_t pxCallbackFunction,
* StaticTimer_t *pxTimerBuffer ); * StaticTimer_t *pxTimerBuffer );
* *
* Creates a new software timer instance, and returns a handle by which the * Creates a new software timer instance, and returns a handle by which the
* created software timer can be referenced. * created software timer can be referenced.
@@ -247,7 +251,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* of memory, in which the timer data structure is stored. If a software timer * of memory, in which the timer data structure is stored. If a software timer
* is created using xTimerCreate() then the required memory is automatically * is created using xTimerCreate() then the required memory is automatically
* dynamically allocated inside the xTimerCreate() function. (see * dynamically allocated inside the xTimerCreate() function. (see
* http://www.freertos.org/a00111.html). If a software timer is created using * https://www.FreeRTOS.org/a00111.html). If a software timer is created using
* xTimerCreateStatic() then the application writer must provide the memory that * xTimerCreateStatic() then the application writer must provide the memory that
* will get used by the software timer. xTimerCreateStatic() therefore allows a * will get used by the software timer. xTimerCreateStatic() therefore allows a
* software timer to be created without using any dynamic memory allocation. * software timer to be created without using any dynamic memory allocation.
@@ -269,9 +273,9 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or
* equal to 1000. The timer period must be greater than 0. * equal to 1000. The timer period must be greater than 0.
* *
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will
* expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.
* If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and * If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and
* enter the dormant state after it expires. * enter the dormant state after it expires.
* *
* @param pvTimerID An identifier that is assigned to the timer being created. * @param pvTimerID An identifier that is assigned to the timer being created.
@@ -354,13 +358,13 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* } * }
* @endverbatim * @endverbatim
*/ */
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const BaseType_t xAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION;
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
/** /**
@@ -383,7 +387,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* *
* See the xTimerCreate() API function example usage scenario. * See the xTimerCreate() API function example usage scenario.
*/ */
void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; void * pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/** /**
* void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
@@ -404,7 +408,8 @@ void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* *
* See the xTimerCreate() API function example usage scenario. * See the xTimerCreate() API function example usage scenario.
*/ */
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION; void vTimerSetTimerID( TimerHandle_t xTimer,
void * pvNewID ) PRIVILEGED_FUNCTION;
/** /**
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
@@ -501,7 +506,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* See the xTimerCreate() API function example usage scenario. * See the xTimerCreate() API function example usage scenario.
* *
*/ */
#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) #define xTimerStart( xTimer, xTicksToWait ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
/** /**
* BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
@@ -543,12 +549,13 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* See the xTimerCreate() API function example usage scenario. * See the xTimerCreate() API function example usage scenario.
* *
*/ */
#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) #define xTimerStop( xTimer, xTicksToWait ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
/** /**
* BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
* TickType_t xNewPeriod, * TickType_t xNewPeriod,
* TickType_t xTicksToWait ); * TickType_t xTicksToWait );
* *
* Timer functionality is provided by a timer service/daemon task. Many of the * Timer functionality is provided by a timer service/daemon task. Many of the
* public FreeRTOS timer API functions send commands to the timer service task * public FreeRTOS timer API functions send commands to the timer service task
@@ -623,7 +630,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* } * }
* @endverbatim * @endverbatim
*/ */
#define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) )
/** /**
* BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );
@@ -661,7 +669,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* *
* See the xTimerChangePeriod() API function example usage scenario. * See the xTimerChangePeriod() API function example usage scenario.
*/ */
#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) #define xTimerDelete( xTimer, xTicksToWait ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )
/** /**
* BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
@@ -785,11 +794,12 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* } * }
* @endverbatim * @endverbatim
*/ */
#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) #define xTimerReset( xTimer, xTicksToWait ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
/** /**
* BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,
* BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
* *
* A version of xTimerStart() that can be called from an interrupt service * A version of xTimerStart() that can be called from an interrupt service
* routine. * routine.
@@ -871,11 +881,12 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* } * }
* @endverbatim * @endverbatim
*/ */
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) #define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
/** /**
* BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,
* BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
* *
* A version of xTimerStop() that can be called from an interrupt service * A version of xTimerStop() that can be called from an interrupt service
* routine. * routine.
@@ -934,12 +945,13 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* } * }
* @endverbatim * @endverbatim
*/ */
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) #define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )
/** /**
* BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,
* TickType_t xNewPeriod, * TickType_t xNewPeriod,
* BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
* *
* A version of xTimerChangePeriod() that can be called from an interrupt * A version of xTimerChangePeriod() that can be called from an interrupt
* service routine. * service routine.
@@ -1007,11 +1019,12 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* } * }
* @endverbatim * @endverbatim
*/ */
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) #define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
/** /**
* BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
* BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
* *
* A version of xTimerReset() that can be called from an interrupt service * A version of xTimerReset() that can be called from an interrupt service
* routine. * routine.
@@ -1093,7 +1106,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* } * }
* @endverbatim * @endverbatim
*/ */
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) #define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) \
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
/** /**
@@ -1146,79 +1160,85 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* Example usage: * Example usage:
* @verbatim * @verbatim
* *
* // The callback function that will execute in the context of the daemon task. * // The callback function that will execute in the context of the daemon task.
* // Note callback functions must all use this same prototype. * // Note callback functions must all use this same prototype.
* void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 )
* { * {
* BaseType_t xInterfaceToService; * BaseType_t xInterfaceToService;
* *
* // The interface that requires servicing is passed in the second * // The interface that requires servicing is passed in the second
* // parameter. The first parameter is not used in this case. * // parameter. The first parameter is not used in this case.
* xInterfaceToService = ( BaseType_t ) ulParameter2; * xInterfaceToService = ( BaseType_t ) ulParameter2;
* *
* // ...Perform the processing here... * // ...Perform the processing here...
* } * }
* *
* // An ISR that receives data packets from multiple interfaces * // An ISR that receives data packets from multiple interfaces
* void vAnISR( void ) * void vAnISR( void )
* { * {
* BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken;
* *
* // Query the hardware to determine which interface needs processing. * // Query the hardware to determine which interface needs processing.
* xInterfaceToService = prvCheckInterfaces(); * xInterfaceToService = prvCheckInterfaces();
* *
* // The actual processing is to be deferred to a task. Request the * // The actual processing is to be deferred to a task. Request the
* // vProcessInterface() callback function is executed, passing in the * // vProcessInterface() callback function is executed, passing in the
* // number of the interface that needs processing. The interface to * // number of the interface that needs processing. The interface to
* // service is passed in the second parameter. The first parameter is * // service is passed in the second parameter. The first parameter is
* // not used in this case. * // not used in this case.
* xHigherPriorityTaskWoken = pdFALSE; * xHigherPriorityTaskWoken = pdFALSE;
* xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken );
* *
* // If xHigherPriorityTaskWoken is now set to pdTRUE then a context * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
* // switch should be requested. The macro used is port specific and will * // switch should be requested. The macro used is port specific and will
* // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
* // the documentation page for the port being used. * // the documentation page for the port being used.
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
* *
* } * }
* @endverbatim * @endverbatim
*/ */
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/** /**
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
* void *pvParameter1, * void *pvParameter1,
* uint32_t ulParameter2, * uint32_t ulParameter2,
* TickType_t xTicksToWait ); * TickType_t xTicksToWait );
* *
* *
* Used to defer the execution of a function to the RTOS daemon task (the timer * Used to defer the execution of a function to the RTOS daemon task (the timer
* service task, hence this function is implemented in timers.c and is prefixed * service task, hence this function is implemented in timers.c and is prefixed
* with 'Timer'). * with 'Timer').
* *
* @param xFunctionToPend The function to execute from the timer service/ * @param xFunctionToPend The function to execute from the timer service/
* daemon task. The function must conform to the PendedFunction_t * daemon task. The function must conform to the PendedFunction_t
* prototype. * prototype.
* *
* @param pvParameter1 The value of the callback function's first parameter. * @param pvParameter1 The value of the callback function's first parameter.
* The parameter has a void * type to allow it to be used to pass any type. * The parameter has a void * type to allow it to be used to pass any type.
* For example, unsigned longs can be cast to a void *, or the void * can be * For example, unsigned longs can be cast to a void *, or the void * can be
* used to point to a structure. * used to point to a structure.
* *
* @param ulParameter2 The value of the callback function's second parameter. * @param ulParameter2 The value of the callback function's second parameter.
* *
* @param xTicksToWait Calling this function will result in a message being * @param xTicksToWait Calling this function will result in a message being
* sent to the timer daemon task on a queue. xTicksToWait is the amount of * sent to the timer daemon task on a queue. xTicksToWait is the amount of
* time the calling task should remain in the Blocked state (so not using any * time the calling task should remain in the Blocked state (so not using any
* processing time) for space to become available on the timer queue if the * processing time) for space to become available on the timer queue if the
* queue is found to be full. * queue is found to be full.
* *
* @return pdPASS is returned if the message was successfully sent to the * @return pdPASS is returned if the message was successfully sent to the
* timer daemon task, otherwise pdFALSE is returned. * timer daemon task, otherwise pdFALSE is returned.
* *
*/ */
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* const char * const pcTimerGetName( TimerHandle_t xTimer ); * const char * const pcTimerGetName( TimerHandle_t xTimer );
@@ -1232,7 +1252,7 @@ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvPar
const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
/** /**
* void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ); * void vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t xAutoReload );
* *
* Updates a timer to be either an auto-reload timer, in which case the timer * Updates a timer to be either an auto-reload timer, in which case the timer
* automatically resets itself each time it expires, or a one-shot timer, in * automatically resets itself each time it expires, or a one-shot timer, in
@@ -1240,26 +1260,41 @@ const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint
* *
* @param xTimer The handle of the timer being updated. * @param xTimer The handle of the timer being updated.
* *
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will
* expire repeatedly with a frequency set by the timer's period (see the * expire repeatedly with a frequency set by the timer's period (see the
* xTimerPeriodInTicks parameter of the xTimerCreate() API function). If * xTimerPeriodInTicks parameter of the xTimerCreate() API function). If
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and * xAutoReload is set to pdFALSE then the timer will be a one-shot timer and
* enter the dormant state after it expires. * enter the dormant state after it expires.
*/ */
void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; void vTimerSetReloadMode( TimerHandle_t xTimer,
const BaseType_t xAutoReload ) PRIVILEGED_FUNCTION;
/** /**
* UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ); * BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer );
* *
* Queries a timer to determine if it is an auto-reload timer, in which case the timer * Queries a timer to determine if it is an auto-reload timer, in which case the timer
* automatically resets itself each time it expires, or a one-shot timer, in * automatically resets itself each time it expires, or a one-shot timer, in
* which case the timer will only expire once unless it is manually restarted. * which case the timer will only expire once unless it is manually restarted.
* *
* @param xTimer The handle of the timer being queried. * @param xTimer The handle of the timer being queried.
* *
* @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise * @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise
* pdFALSE is returned. * pdFALSE is returned.
*/ */
BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/**
* UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer );
*
* Queries a timer to determine if it is an auto-reload timer, in which case the timer
* automatically resets itself each time it expires, or a one-shot timer, in
* which case the timer will only expire once unless it is manually restarted.
*
* @param xTimer The handle of the timer being queried.
*
* @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise
* pdFALSE is returned.
*/
UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/** /**
@@ -1274,36 +1309,95 @@ UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/** /**
* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); * TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );
* *
* Returns the time in ticks at which the timer will expire. If this is less * Returns the time in ticks at which the timer will expire. If this is less
* than the current tick count then the expiry time has overflowed from the * than the current tick count then the expiry time has overflowed from the
* current time. * current time.
* *
* @param xTimer The handle of the timer being queried. * @param xTimer The handle of the timer being queried.
* *
* @return If the timer is running then the time in ticks at which the timer * @return If the timer is running then the time in ticks at which the timer
* will next expire is returned. If the timer is not running then the return * will next expire is returned. If the timer is not running then the return
* value is undefined. * value is undefined.
*/ */
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/**
* BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
* StaticTimer_t ** ppxTimerBuffer );
*
* Retrieve pointer to a statically created timer's data structure
* buffer. This is the same buffer that is supplied at the time of
* creation.
*
* @param xTimer The timer for which to retrieve the buffer.
*
* @param ppxTaskBuffer Used to return a pointer to the timers's data
* structure buffer.
*
* @return pdTRUE if the buffer was retrieved, pdFALSE otherwise.
*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION;
#endif /* configSUPPORT_STATIC_ALLOCATION */
/* /*
* Functions beyond this part are not part of the public API and are intended * Functions beyond this part are not part of the public API and are intended
* for use by the kernel only. * for use by the kernel only.
*/ */
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; BaseType_t xTimerGenericCommand( TimerHandle_t xTimer,
const BaseType_t xCommandID,
const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
#if( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION; void vTimerSetTimerNumber( TimerHandle_t xTimer,
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
#endif #endif
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
/**
* task.h
* @code{c}
* void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
* @endcode
*
* This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Timer Task TCB. This function is required when
* configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION
*
* @param ppxTimerTaskTCBBuffer A handle to a statically allocated TCB buffer
* @param ppxTimerTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task
* @param pulTimerTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer
*/
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize );
#endif
#if ( configUSE_DAEMON_TASK_STARTUP_HOOK != 0 )
/**
* timers.h
* @code{c}
* void vApplicationDaemonTaskStartupHook( void );
* @endcode
*
* This hook function is called form the timer task once when the task starts running.
*/
void vApplicationDaemonTaskStartupHook( void );
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */
#endif /* TIMERS_H */ #endif /* TIMERS_H */
+152 -124
View File
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,180 +21,206 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#include <stdlib.h> #include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
* all the API functions to use the MPU wrappers. That should only be done when
* task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "list.h" #include "list.h"
/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified
* because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be
* defined for the header files above, but not in this file, in order to
* generate the correct privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* PUBLIC LIST API documented in list.h * PUBLIC LIST API documented in list.h
*----------------------------------------------------------*/ *----------------------------------------------------------*/
void vListInitialise( List_t * const pxList ) void vListInitialise( List_t * const pxList )
{ {
/* The list structure contains a list item which is used to mark the /* The list structure contains a list item which is used to mark the
end of the list. To initialise the list the list end is inserted * end of the list. To initialise the list the list end is inserted
as the only list entry. */ * as the only list entry. */
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
/* The list end value is the highest possible value in the list to listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
ensure it remains at the end of the list. */
pxList->xListEnd.xItemValue = portMAX_DELAY;
/* The list end next and previous pointers point to itself so we know /* The list end value is the highest possible value in the list to
when the list is empty. */ * ensure it remains at the end of the list. */
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->xListEnd.xItemValue = portMAX_DELAY;
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
pxList->uxNumberOfItems = ( UBaseType_t ) 0U; /* The list end next and previous pointers point to itself so we know
* when the list is empty. */
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
/* Write known values into the list if /* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ #if ( configUSE_MINI_LIST_ITEM == 0 )
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); {
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); pxList->xListEnd.pvOwner = NULL;
pxList->xListEnd.pxContainer = NULL;
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
}
#endif
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
/* Write known values into the list if
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInitialiseItem( ListItem_t * const pxItem ) void vListInitialiseItem( ListItem_t * const pxItem )
{ {
/* Make sure the list item is not recorded as being on a list. */ /* Make sure the list item is not recorded as being on a list. */
pxItem->pxContainer = NULL; pxItem->pxContainer = NULL;
/* Write known values into the list item if /* Write known values into the list item if
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem )
{ {
ListItem_t * const pxIndex = pxList->pxIndex; ListItem_t * const pxIndex = pxList->pxIndex;
/* Only effective when configASSERT() is also defined, these tests may catch /* Only effective when configASSERT() is also defined, these tests may catch
the list data structures being overwritten in memory. They will not catch * the list data structures being overwritten in memory. They will not catch
data errors caused by incorrect configuration or use of FreeRTOS. */ * data errors caused by incorrect configuration or use of FreeRTOS. */
listTEST_LIST_INTEGRITY( pxList ); listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
/* Insert a new list item into pxList, but rather than sort the list, /* Insert a new list item into pxList, but rather than sort the list,
makes the new list item the last item to be removed by a call to * makes the new list item the last item to be removed by a call to
listGET_OWNER_OF_NEXT_ENTRY(). */ * listGET_OWNER_OF_NEXT_ENTRY(). */
pxNewListItem->pxNext = pxIndex; pxNewListItem->pxNext = pxIndex;
pxNewListItem->pxPrevious = pxIndex->pxPrevious; pxNewListItem->pxPrevious = pxIndex->pxPrevious;
/* Only used during decision coverage testing. */ /* Only used during decision coverage testing. */
mtCOVERAGE_TEST_DELAY(); mtCOVERAGE_TEST_DELAY();
pxIndex->pxPrevious->pxNext = pxNewListItem; pxIndex->pxPrevious->pxNext = pxNewListItem;
pxIndex->pxPrevious = pxNewListItem; pxIndex->pxPrevious = pxNewListItem;
/* Remember which list the item is in. */ /* Remember which list the item is in. */
pxNewListItem->pxContainer = pxList; pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++; ( pxList->uxNumberOfItems )++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) void vListInsert( List_t * const pxList,
ListItem_t * const pxNewListItem )
{ {
ListItem_t *pxIterator; ListItem_t * pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
/* Only effective when configASSERT() is also defined, these tests may catch /* Only effective when configASSERT() is also defined, these tests may catch
the list data structures being overwritten in memory. They will not catch * the list data structures being overwritten in memory. They will not catch
data errors caused by incorrect configuration or use of FreeRTOS. */ * data errors caused by incorrect configuration or use of FreeRTOS. */
listTEST_LIST_INTEGRITY( pxList ); listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
/* Insert the new list item into the list, sorted in xItemValue order. /* Insert the new list item into the list, sorted in xItemValue order.
*
* If the list already contains a list item with the same item value then the
* new list item should be placed after it. This ensures that TCBs which are
* stored in ready lists (all of which have the same xItemValue value) get a
* share of the CPU. However, if the xItemValue is the same as the back marker
* the iteration loop below will not end. Therefore the value is checked
* first, and the algorithm slightly modified if necessary. */
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
/* *** NOTE ***********************************************************
* If you find your application is crashing here then likely causes are
* listed below. In addition see https://www.FreeRTOS.org/FAQHelp.html for
* more tips, and ensure configASSERT() is defined!
* https://www.FreeRTOS.org/a00110.html#configASSERT
*
* 1) Stack overflow -
* see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html
* 2) Incorrect interrupt priority assignment, especially on Cortex-M
* parts where numerically high priority values denote low actual
* interrupt priorities, which can seem counter intuitive. See
* https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition
* of configMAX_SYSCALL_INTERRUPT_PRIORITY on
* https://www.FreeRTOS.org/a00110.html
* 3) Calling an API function from within a critical section or when
* the scheduler is suspended, or calling an API function that does
* not end in "FromISR" from an interrupt.
* 4) Using a queue or semaphore before it has been initialised or
* before the scheduler has been started (are interrupts firing
* before vTaskStartScheduler() has been called?).
* 5) If the FreeRTOS port supports interrupt nesting then ensure that
* the priority of the tick interrupt is at or below
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
**********************************************************************/
If the list already contains a list item with the same item value then the for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
new list item should be placed after it. This ensures that TCBs which are {
stored in ready lists (all of which have the same xItemValue value) get a /* There is nothing to do here, just iterating to the wanted
share of the CPU. However, if the xItemValue is the same as the back marker * insertion position. */
the iteration loop below will not end. Therefore the value is checked }
first, and the algorithm slightly modified if necessary. */ }
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
/* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are
listed below. In addition see https://www.freertos.org/FAQHelp.html for
more tips, and ensure configASSERT() is defined!
https://www.freertos.org/a00110.html#configASSERT
1) Stack overflow - pxNewListItem->pxNext = pxIterator->pxNext;
see https://www.freertos.org/Stacks-and-stack-overflow-checking.html pxNewListItem->pxNext->pxPrevious = pxNewListItem;
2) Incorrect interrupt priority assignment, especially on Cortex-M pxNewListItem->pxPrevious = pxIterator;
parts where numerically high priority values denote low actual pxIterator->pxNext = pxNewListItem;
interrupt priorities, which can seem counter intuitive. See
https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
https://www.freertos.org/a00110.html
3) Calling an API function from within a critical section or when
the scheduler is suspended, or calling an API function that does
not end in "FromISR" from an interrupt.
4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?).
**********************************************************************/
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ /* Remember which list the item is in. This allows fast removal of the
{ * item later. */
/* There is nothing to do here, just iterating to the wanted pxNewListItem->pxContainer = pxList;
insertion position. */
}
}
pxNewListItem->pxNext = pxIterator->pxNext; ( pxList->uxNumberOfItems )++;
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the
item later. */
pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{ {
/* The list item knows which list it is in. Obtain the list from the list /* The list item knows which list it is in. Obtain the list from the list
item. */ * item. */
List_t * const pxList = pxItemToRemove->pxContainer; List_t * const pxList = pxItemToRemove->pxContainer;
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
/* Only used during decision coverage testing. */ /* Only used during decision coverage testing. */
mtCOVERAGE_TEST_DELAY(); mtCOVERAGE_TEST_DELAY();
/* Make sure the index is left pointing to a valid item. */ /* Make sure the index is left pointing to a valid item. */
if( pxList->pxIndex == pxItemToRemove ) if( pxList->pxIndex == pxItemToRemove )
{ {
pxList->pxIndex = pxItemToRemove->pxPrevious; pxList->pxIndex = pxItemToRemove->pxPrevious;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
pxItemToRemove->pxContainer = NULL; pxItemToRemove->pxContainer = NULL;
( pxList->uxNumberOfItems )--; ( pxList->uxNumberOfItems )--;
return pxList->uxNumberOfItems; return pxList->uxNumberOfItems;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,19 +21,20 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Port specific definitions. * Port specific definitions.
@@ -44,200 +47,208 @@ extern "C" {
*/ */
/* Type definitions. */ /* Type definitions. */
#define portCHAR char #define portCHAR char
#define portFLOAT float #define portFLOAT float
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE uint32_t #define portSTACK_TYPE uint32_t
#define portBASE_TYPE long #define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t; typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
#if( configUSE_16_BIT_TICKS == 1 ) #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t; typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff #define portMAX_DELAY ( TickType_t ) 0xffff
#else #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
typedef uint64_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffULL
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Architecture specifics. */ /* Architecture specifics. */
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8 #define portBYTE_ALIGNMENT 8
#define portDONT_DISCARD __attribute__( ( used ) )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Scheduler utilities. */ /* Scheduler utilities. */
#define portYIELD() \ #define portYIELD() \
{ \ { \
/* Set a PendSV to request a context switch. */ \ /* Set a PendSV to request a context switch. */ \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ * within the specified behaviour for the architecture. */ \
__asm volatile( "dsb" ::: "memory" ); \ __asm volatile ( "dsb" ::: "memory" ); \
__asm volatile( "isb" ); \ __asm volatile ( "isb" ); \
} }
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */
extern void vPortEnterCritical( void ); extern void vPortEnterCritical( void );
extern void vPortExitCritical( void ); extern void vPortExitCritical( void );
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are /* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files * not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */ * (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Tickless idle/low power functionality. */ /* Tickless idle/low power functionality. */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Architecture specific optimisations. */ /* Architecture specific optimisations. */
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#endif #endif
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Generic helper function. */ /* Generic helper function. */
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
{ {
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn;
}
/* Check the configuration. */ return ucReturn;
#if( configMAX_PRIORITIES > 32 ) }
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
#endif
/* Store/clear the ready priorities in a bit map. */ /* Check the configuration. */
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) #if ( configMAX_PRIORITIES > 32 )
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
#endif
/*-----------------------------------------------------------*/ /* Store/clear the ready priorities in a bit map. */
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef configASSERT #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
void vPortValidateInterruptPriority( void );
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
#endif
/*-----------------------------------------------------------*/
#ifdef configASSERT
void vPortValidateInterruptPriority( void );
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
#endif
/* portNOP() is not required by this port. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()
#define portINLINE __inline #define portINLINE __inline
#ifndef portFORCE_INLINE #ifndef portFORCE_INLINE
#define portFORCE_INLINE inline __attribute__(( always_inline)) #define portFORCE_INLINE inline __attribute__( ( always_inline ) )
#endif #endif
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
{ {
uint32_t ulCurrentInterrupt; uint32_t ulCurrentInterrupt;
BaseType_t xReturn; BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
if( ulCurrentInterrupt == 0 ) if( ulCurrentInterrupt == 0 )
{ {
xReturn = pdFALSE; xReturn = pdFALSE;
} }
else else
{ {
xReturn = pdTRUE; xReturn = pdTRUE;
} }
return xReturn; return xReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
portFORCE_INLINE static void vPortRaiseBASEPRI( void ) portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{ {
uint32_t ulNewBASEPRI; uint32_t ulNewBASEPRI;
__asm volatile __asm volatile
( (
" mov %0, %1 \n" \ " mov %0, %1 \n"\
" msr basepri, %0 \n" \ " msr basepri, %0 \n"\
" isb \n" \ " isb \n"\
" dsb \n" \ " dsb \n"\
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
{ {
uint32_t ulOriginalBASEPRI, ulNewBASEPRI; uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
__asm volatile __asm volatile
( (
" mrs %0, basepri \n" \ " mrs %0, basepri \n"\
" mov %1, %2 \n" \ " mov %1, %2 \n"\
" msr basepri, %1 \n" \ " msr basepri, %1 \n"\
" isb \n" \ " isb \n"\
" dsb \n" \ " dsb \n"\
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
warnings. */ * warnings. */
return ulOriginalBASEPRI; return ulOriginalBASEPRI;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
{ {
__asm volatile __asm volatile
( (
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory" " msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */
@@ -1,146 +0,0 @@
/*
* FreeRTOS Kernel V10.3.1
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
* The simplest possible implementation of pvPortMalloc(). Note that this
* implementation does NOT allow allocated memory to be freed again.
*
* See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the
* memory management pages of http://www.FreeRTOS.org for more information.
*/
#include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h"
#include "task.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
/* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS
heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */
/* Index into the ucHeap array. */
static size_t xNextFreeByte = ( size_t ) 0;
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn = NULL;
static uint8_t *pucAlignedHeap = NULL;
/* Ensure that blocks are always aligned to the required number of bytes. */
#if( portBYTE_ALIGNMENT != 1 )
{
if( xWantedSize & portBYTE_ALIGNMENT_MASK )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
}
#endif
vTaskSuspendAll();
{
if( pucAlignedHeap == NULL )
{
/* Ensure the heap starts on a correctly aligned boundary. */
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
}
/* Check there is enough room left for the allocation. */
if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
{
/* Return the next free byte then increment the index past this
block. */
pvReturn = pucAlignedHeap + xNextFreeByte;
xNextFreeByte += xWantedSize;
}
traceMALLOC( pvReturn, xWantedSize );
}
( void ) xTaskResumeAll();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif
return pvReturn;
}
/*-----------------------------------------------------------*/
void vPortFree( void *pv )
{
/* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and
heap_4.c for alternative implementations, and the memory management pages of
http://www.FreeRTOS.org for more information. */
( void ) pv;
/* Force an assert as it is invalid to call this function. */
configASSERT( pv == NULL );
}
/*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void )
{
/* Only required when static memory is not cleared. */
xNextFreeByte = ( size_t ) 0;
}
/*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void )
{
return ( configADJUSTED_HEAP_SIZE - xNextFreeByte );
}
@@ -1,272 +0,0 @@
/*
* FreeRTOS Kernel V10.3.1
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
* A sample implementation of pvPortMalloc() and vPortFree() that permits
* allocated blocks to be freed, but does not combine adjacent free blocks
* into a single larger block (and so will fragment memory). See heap_4.c for
* an equivalent that does combine adjacent blocks into single larger blocks.
*
* See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the
* memory management pages of http://www.FreeRTOS.org for more information.
*/
#include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h"
#include "task.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
/*
* Initialises the heap structures before their first use.
*/
static void prvHeapInit( void );
/* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS
heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */
/* Define the linked list structure. This is used to link free blocks in order
of their size. */
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} BlockLink_t;
static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
/* Create a couple of list links to mark the start and end of the list. */
static BlockLink_t xStart, xEnd;
/* Keeps track of the number of free bytes remaining, but says nothing about
fragmentation. */
static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE;
/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
/*
* Insert a block into the list of free blocks - which is ordered by size of
* the block. Small blocks at the start of the list and large blocks at the end
* of the list.
*/
#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \
{ \
BlockLink_t *pxIterator; \
size_t xBlockSize; \
\
xBlockSize = pxBlockToInsert->xBlockSize; \
\
/* Iterate through the list until a block is found that has a larger size */ \
/* than the block we are inserting. */ \
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \
{ \
/* There is nothing to do here - just iterate to the correct position. */ \
} \
\
/* Update the list to include the block being inserted in the correct */ \
/* position. */ \
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \
pxIterator->pxNextFreeBlock = pxBlockToInsert; \
}
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
{
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
static BaseType_t xHeapHasBeenInitialised = pdFALSE;
void *pvReturn = NULL;
vTaskSuspendAll();
{
/* If this is the first call to malloc then the heap will require
initialisation to setup the list of free blocks. */
if( xHeapHasBeenInitialised == pdFALSE )
{
prvHeapInit();
xHeapHasBeenInitialised = pdTRUE;
}
/* The wanted size is increased so it can contain a BlockLink_t
structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize += heapSTRUCT_SIZE;
/* Ensure that blocks are always aligned to the required number of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
}
if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) )
{
/* Blocks are stored in byte order - traverse the list from the start
(smallest) block until one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
/* If we found the end marker then a block of adequate size was not found. */
if( pxBlock != &xEnd )
{
/* Return the memory space - jumping over the BlockLink_t structure
at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
/* This block is being returned for use so must be taken out of the
list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
{
/* This block is to be split into two. Create a new block
following the number of bytes requested. The void cast is
used to prevent byte alignment warnings from the compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
/* Calculate the sizes of two blocks split from the single
block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
}
xFreeBytesRemaining -= pxBlock->xBlockSize;
}
}
traceMALLOC( pvReturn, xWantedSize );
}
( void ) xTaskResumeAll();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif
return pvReturn;
}
/*-----------------------------------------------------------*/
void vPortFree( void *pv )
{
uint8_t *puc = ( uint8_t * ) pv;
BlockLink_t *pxLink;
if( pv != NULL )
{
/* The memory being freed will have an BlockLink_t structure immediately
before it. */
puc -= heapSTRUCT_SIZE;
/* This unexpected casting is to keep some compilers from issuing
byte alignment warnings. */
pxLink = ( void * ) puc;
vTaskSuspendAll();
{
/* Add this block to the list of free blocks. */
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize );
}
( void ) xTaskResumeAll();
}
}
/*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void )
{
return xFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void )
{
/* This just exists to keep the linker quiet. */
}
/*-----------------------------------------------------------*/
static void prvHeapInit( void )
{
BlockLink_t *pxFirstFreeBlock;
uint8_t *pucAlignedHeap;
/* Ensure the heap starts on a correctly aligned boundary. */
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
/* xStart is used to hold a pointer to the first item in the list of free
blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
/* xEnd is used to mark the end of the list of free blocks. */
xEnd.xBlockSize = configADJUSTED_HEAP_SIZE;
xEnd.pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the
entire heap space. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE;
pxFirstFreeBlock->pxNextFreeBlock = &xEnd;
}
/*-----------------------------------------------------------*/
@@ -1,97 +0,0 @@
/*
* FreeRTOS Kernel V10.3.1
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
* Implementation of pvPortMalloc() and vPortFree() that relies on the
* compilers own malloc() and free() implementations.
*
* This file can only be used if the linker is configured to to generate
* a heap memory area.
*
* See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the
* memory management pages of http://www.FreeRTOS.org for more information.
*/
#include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h"
#include "task.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn;
vTaskSuspendAll();
{
pvReturn = malloc( xWantedSize );
traceMALLOC( pvReturn, xWantedSize );
}
( void ) xTaskResumeAll();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif
return pvReturn;
}
/*-----------------------------------------------------------*/
void vPortFree( void *pv )
{
if( pv )
{
vTaskSuspendAll();
{
free( pv );
traceFREE( pv, 0 );
}
( void ) xTaskResumeAll();
}
}
@@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel V10.3.1 * FreeRTOS Kernel V10.6.2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@@ -19,10 +21,9 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* http://www.FreeRTOS.org * https://www.FreeRTOS.org
* http://aws.amazon.com/freertos * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces!
*/ */
/* /*
@@ -31,13 +32,14 @@
* limits memory fragmentation. * limits memory fragmentation.
* *
* See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the
* memory management pages of http://www.FreeRTOS.org for more information. * memory management pages of https://www.FreeRTOS.org for more information.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when * all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */ * task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h" #include "FreeRTOS.h"
@@ -45,31 +47,57 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
#ifndef configHEAP_CLEAR_MEMORY_ON_FREE
#define configHEAP_CLEAR_MEMORY_ON_FREE 0
#endif #endif
/* Block sizes must not get too small. */ /* Block sizes must not get too small. */
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
/* Assumes 8bit bytes! */ /* Assumes 8bit bytes! */
#define heapBITS_PER_BYTE ( ( size_t ) 8 ) #define heapBITS_PER_BYTE ( ( size_t ) 8 )
/* Max value that fits in a size_t type. */
#define heapSIZE_MAX ( ~( ( size_t ) 0 ) )
/* Check if multiplying a and b will result in overflow. */
#define heapMULTIPLY_WILL_OVERFLOW( a, b ) ( ( ( a ) > 0 ) && ( ( b ) > ( heapSIZE_MAX / ( a ) ) ) )
/* Check if adding a and b will result in overflow. */
#define heapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( heapSIZE_MAX - ( b ) ) )
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
* the allocation status of a block. When MSB of the xBlockSize member of
* an BlockLink_t structure is set then the block belongs to the application.
* When the bit is free the block is still part of the free heap space. */
#define heapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ) )
#define heapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) == 0 )
#define heapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) != 0 )
#define heapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= heapBLOCK_ALLOCATED_BITMASK )
#define heapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~heapBLOCK_ALLOCATED_BITMASK )
/*-----------------------------------------------------------*/
/* Allocate the memory for the heap. */ /* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) #if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS
heap - probably so it can be placed in a special segment or address. */ /* The application writer has already defined the array used for the RTOS
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; * heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else #else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */ #endif /* configAPPLICATION_ALLOCATED_HEAP */
/* Define the linked list structure. This is used to link free blocks in order /* Define the linked list structure. This is used to link free blocks in order
of their memory address. */ * of their memory address. */
typedef struct A_BLOCK_LINK typedef struct A_BLOCK_LINK
{ {
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */ size_t xBlockSize; /**< The size of the free block. */
} BlockLink_t; } BlockLink_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -80,413 +108,448 @@ typedef struct A_BLOCK_LINK
* the block in front it and/or the block behind it if the memory blocks are * the block in front it and/or the block behind it if the memory blocks are
* adjacent to each other. * adjacent to each other.
*/ */
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) PRIVILEGED_FUNCTION;
/* /*
* Called automatically to setup the required heap structures the first time * Called automatically to setup the required heap structures the first time
* pvPortMalloc() is called. * pvPortMalloc() is called.
*/ */
static void prvHeapInit( void ); static void prvHeapInit( void ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The size of the structure placed at the beginning of each allocated memory /* The size of the structure placed at the beginning of each allocated memory
block must by correctly byte aligned. */ * block must by correctly byte aligned. */
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
/* Create a couple of list links to mark the start and end of the list. */ /* Create a couple of list links to mark the start and end of the list. */
static BlockLink_t xStart, *pxEnd = NULL; PRIVILEGED_DATA static BlockLink_t xStart;
PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL;
/* Keeps track of the number of calls to allocate and free memory as well as the /* Keeps track of the number of calls to allocate and free memory as well as the
number of free bytes remaining, but says nothing about fragmentation. */ * number of free bytes remaining, but says nothing about fragmentation. */
static size_t xFreeBytesRemaining = 0U; PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U;
static size_t xMinimumEverFreeBytesRemaining = 0U; PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U;
static size_t xNumberOfSuccessfulAllocations = 0; PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0;
static size_t xNumberOfSuccessfulFrees = 0; PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0;
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
member of an BlockLink_t structure is set then the block belongs to the
application. When the bit is free the block is still part of the free heap
space. */
static size_t xBlockAllocatedBit = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize ) void * pvPortMalloc( size_t xWantedSize )
{ {
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; BlockLink_t * pxBlock;
void *pvReturn = NULL; BlockLink_t * pxPreviousBlock;
BlockLink_t * pxNewBlockLink;
void * pvReturn = NULL;
size_t xAdditionalRequiredSize;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
/* If this is the first call to malloc then the heap will require /* If this is the first call to malloc then the heap will require
initialisation to setup the list of free blocks. */ * initialisation to setup the list of free blocks. */
if( pxEnd == NULL ) if( pxEnd == NULL )
{ {
prvHeapInit(); prvHeapInit();
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
/* Check the requested block size is not so large that the top bit is if( xWantedSize > 0 )
set. The top bit of the block size member of the BlockLink_t structure {
is used to determine who owns the block - the application or the /* The wanted size must be increased so it can contain a BlockLink_t
kernel, so it must be free. */ * structure in addition to the requested amount of bytes. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
{ {
/* The wanted size is increased so it can contain a BlockLink_t xWantedSize += xHeapStructSize;
structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number /* Ensure that blocks are always aligned to the required number
of bytes. */ * of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{ {
/* Byte alignment required. */ /* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
{ {
/* Traverse the list from the start (lowest address) block until xWantedSize += xAdditionalRequiredSize;
one of adequate size is found. */ }
pxPreviousBlock = &xStart; else
pxBlock = xStart.pxNextFreeBlock; {
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) xWantedSize = 0;
{ }
pxPreviousBlock = pxBlock; }
pxBlock = pxBlock->pxNextFreeBlock; else
} {
mtCOVERAGE_TEST_MARKER();
}
}
else
{
xWantedSize = 0;
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* If the end marker was reached then a block of adequate size /* Check the block size we are trying to allocate is not so large that the
was not found. */ * top bit is set. The top bit of the block size member of the BlockLink_t
if( pxBlock != pxEnd ) * structure is used to determine who owns the block - the application or
{ * the kernel, so it must be free. */
/* Return the memory space pointed to - jumping over the if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
BlockLink_t structure at its start. */ {
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{
/* Traverse the list from the start (lowest address) block until
* one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
/* This block is being returned for use so must be taken out while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
of the list of free blocks. */ {
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
/* If the block is larger than required it can be split into /* If the end marker was reached then a block of adequate size
two. */ * was not found. */
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) if( pxBlock != pxEnd )
{ {
/* This block is to be split into two. Create a new /* Return the memory space pointed to - jumping over the
block following the number of bytes requested. The void * BlockLink_t structure at its start. */
cast is used to prevent byte alignment warnings from the pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
/* Calculate the sizes of two blocks split from the /* This block is being returned for use so must be taken out
single block. */ * of the list of free blocks. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */ /* If the block is larger than required it can be split into
prvInsertBlockIntoFreeList( pxNewBlockLink ); * two. */
} if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
else {
{ /* This block is to be split into two. Create a new
mtCOVERAGE_TEST_MARKER(); * block following the number of bytes requested. The void
} * cast is used to prevent byte alignment warnings from the
* compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
xFreeBytesRemaining -= pxBlock->xBlockSize; /* Calculate the sizes of two blocks split from the
* single block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) /* Insert the new block into the list of free blocks. */
{ prvInsertBlockIntoFreeList( pxNewBlockLink );
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; }
} else
else {
{ mtCOVERAGE_TEST_MARKER();
mtCOVERAGE_TEST_MARKER(); }
}
/* The block is being returned - it is allocated and owned xFreeBytesRemaining -= pxBlock->xBlockSize;
by the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL;
xNumberOfSuccessfulAllocations++;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
traceMALLOC( pvReturn, xWantedSize ); if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
} {
( void ) xTaskResumeAll(); xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
#if( configUSE_MALLOC_FAILED_HOOK == 1 ) /* The block is being returned - it is allocated and owned
{ * by the application and has no "next" block. */
if( pvReturn == NULL ) heapALLOCATE_BLOCK( pxBlock );
{ pxBlock->pxNextFreeBlock = NULL;
extern void vApplicationMallocFailedHook( void ); xNumberOfSuccessfulAllocations++;
vApplicationMallocFailedHook(); }
} else
else {
{ mtCOVERAGE_TEST_MARKER();
mtCOVERAGE_TEST_MARKER(); }
} }
} else
#endif {
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); traceMALLOC( pvReturn, xWantedSize );
return pvReturn; }
( void ) xTaskResumeAll();
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
vApplicationMallocFailedHook();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */
configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortFree( void *pv ) void vPortFree( void * pv )
{ {
uint8_t *puc = ( uint8_t * ) pv; uint8_t * puc = ( uint8_t * ) pv;
BlockLink_t *pxLink; BlockLink_t * pxLink;
if( pv != NULL ) if( pv != NULL )
{ {
/* The memory being freed will have an BlockLink_t structure immediately /* The memory being freed will have an BlockLink_t structure immediately
before it. */ * before it. */
puc -= xHeapStructSize; puc -= xHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */ /* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc; pxLink = ( void * ) puc;
/* Check the block is actually allocated. */ configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); configASSERT( pxLink->pxNextFreeBlock == NULL );
configASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
{ {
if( pxLink->pxNextFreeBlock == NULL ) if( pxLink->pxNextFreeBlock == NULL )
{ {
/* The block is being returned to the heap - it is no longer /* The block is being returned to the heap - it is no longer
allocated. */ * allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit; heapFREE_BLOCK( pxLink );
#if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 )
{
( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize );
}
#endif
vTaskSuspendAll(); vTaskSuspendAll();
{ {
/* Add this block to the list of free blocks. */ /* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize; xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize ); traceFREE( pv, pxLink->xBlockSize );
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
xNumberOfSuccessfulFrees++; xNumberOfSuccessfulFrees++;
} }
( void ) xTaskResumeAll(); ( void ) xTaskResumeAll();
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void ) size_t xPortGetFreeHeapSize( void )
{ {
return xFreeBytesRemaining; return xFreeBytesRemaining;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
size_t xPortGetMinimumEverFreeHeapSize( void ) size_t xPortGetMinimumEverFreeHeapSize( void )
{ {
return xMinimumEverFreeBytesRemaining; return xMinimumEverFreeBytesRemaining;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void ) void vPortInitialiseBlocks( void )
{ {
/* This just exists to keep the linker quiet. */ /* This just exists to keep the linker quiet. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvHeapInit( void ) void * pvPortCalloc( size_t xNum,
size_t xSize )
{ {
BlockLink_t *pxFirstFreeBlock; void * pv = NULL;
uint8_t *pucAlignedHeap;
size_t uxAddress;
size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
/* Ensure the heap starts on a correctly aligned boundary. */ if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 )
uxAddress = ( size_t ) ucHeap; {
pv = pvPortMalloc( xNum * xSize );
if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) if( pv != NULL )
{ {
uxAddress += ( portBYTE_ALIGNMENT - 1 ); ( void ) memset( pv, 0, xNum * xSize );
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); }
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; }
}
pucAlignedHeap = ( uint8_t * ) uxAddress; return pv;
/* xStart is used to hold a pointer to the first item in the list of free
blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
/* pxEnd is used to mark the end of the list of free blocks and is inserted
at the end of the heap space. */
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
uxAddress -= xHeapStructSize;
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
pxEnd = ( void * ) uxAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the
entire heap space, minus the space taken by pxEnd. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
/* Only one block exists - and it covers the entire usable heap space. */
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */
{ {
BlockLink_t *pxIterator; BlockLink_t * pxFirstFreeBlock;
uint8_t *puc; uint8_t * pucAlignedHeap;
portPOINTER_SIZE_TYPE uxAddress;
size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
/* Iterate through the list until a block is found that has a higher address /* Ensure the heap starts on a correctly aligned boundary. */
than the block being inserted. */ uxAddress = ( portPOINTER_SIZE_TYPE ) ucHeap;
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{
/* Nothing to do here, just iterate to the right position. */
}
/* Do the block being inserted, and the block it is being inserted after if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
make a contiguous block of memory? */ {
puc = ( uint8_t * ) pxIterator; uxAddress += ( portBYTE_ALIGNMENT - 1 );
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK );
{ xTotalHeapSize -= ( size_t ) ( uxAddress - ( portPOINTER_SIZE_TYPE ) ucHeap );
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; }
pxBlockToInsert = pxIterator;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* Do the block being inserted, and the block it is being inserted before pucAlignedHeap = ( uint8_t * ) uxAddress;
make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{
if( pxIterator->pxNextFreeBlock != pxEnd )
{
/* Form one big block from the two blocks. */
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxEnd;
}
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
}
/* If the block being inserted plugged a gab, so was merged with the block /* xStart is used to hold a pointer to the first item in the list of free
before and the block after, then it's pxNextFreeBlock pointer will have * blocks. The void cast is used to prevent compiler warnings. */
already been set, and should not be set here as that would make it point xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
to itself. */ xStart.xBlockSize = ( size_t ) 0;
if( pxIterator != pxBlockToInsert )
{ /* pxEnd is used to mark the end of the list of free blocks and is inserted
pxIterator->pxNextFreeBlock = pxBlockToInsert; * at the end of the heap space. */
} uxAddress = ( portPOINTER_SIZE_TYPE ) ( pucAlignedHeap + xTotalHeapSize );
else uxAddress -= xHeapStructSize;
{ uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK );
mtCOVERAGE_TEST_MARKER(); pxEnd = ( BlockLink_t * ) uxAddress;
} pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the
* entire heap space, minus the space taken by pxEnd. */
pxFirstFreeBlock = ( BlockLink_t * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = ( size_t ) ( uxAddress - ( portPOINTER_SIZE_TYPE ) pxFirstFreeBlock );
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
/* Only one block exists - and it covers the entire usable heap space. */
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortGetHeapStats( HeapStats_t *pxHeapStats ) static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVILEGED_FUNCTION */
{ {
BlockLink_t *pxBlock; BlockLink_t * pxIterator;
size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */ uint8_t * puc;
vTaskSuspendAll(); /* Iterate through the list until a block is found that has a higher address
{ * than the block being inserted. */
pxBlock = xStart.pxNextFreeBlock; for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{
/* Nothing to do here, just iterate to the right position. */
}
/* pxBlock will be NULL if the heap has not been initialised. The heap /* Do the block being inserted, and the block it is being inserted after
is initialised automatically when the first allocation is made. */ * make a contiguous block of memory? */
if( pxBlock != NULL ) puc = ( uint8_t * ) pxIterator;
{
do
{
/* Increment the number of blocks and record the largest block seen
so far. */
xBlocks++;
if( pxBlock->xBlockSize > xMaxSize ) if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{ {
xMaxSize = pxBlock->xBlockSize; pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
} pxBlockToInsert = pxIterator;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
if( pxBlock->xBlockSize < xMinSize ) /* Do the block being inserted, and the block it is being inserted before
{ * make a contiguous block of memory? */
xMinSize = pxBlock->xBlockSize; puc = ( uint8_t * ) pxBlockToInsert;
}
/* Move to the next block in the chain until the last block is if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
reached. */ {
pxBlock = pxBlock->pxNextFreeBlock; if( pxIterator->pxNextFreeBlock != pxEnd )
} while( pxBlock != pxEnd ); {
} /* Form one big block from the two blocks. */
} pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
xTaskResumeAll(); pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxEnd;
}
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
}
pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize; /* If the block being inserted plugged a gab, so was merged with the block
pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize; * before and the block after, then it's pxNextFreeBlock pointer will have
pxHeapStats->xNumberOfFreeBlocks = xBlocks; * already been set, and should not be set here as that would make it point
* to itself. */
taskENTER_CRITICAL(); if( pxIterator != pxBlockToInsert )
{ {
pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining; pxIterator->pxNextFreeBlock = pxBlockToInsert;
pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations; }
pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees; else
pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining; {
} mtCOVERAGE_TEST_MARKER();
taskEXIT_CRITICAL(); }
} }
/*-----------------------------------------------------------*/
void vPortGetHeapStats( HeapStats_t * pxHeapStats )
{
BlockLink_t * pxBlock;
size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */
vTaskSuspendAll();
{
pxBlock = xStart.pxNextFreeBlock;
/* pxBlock will be NULL if the heap has not been initialised. The heap
* is initialised automatically when the first allocation is made. */
if( pxBlock != NULL )
{
while( pxBlock != pxEnd )
{
/* Increment the number of blocks and record the largest block seen
* so far. */
xBlocks++;
if( pxBlock->xBlockSize > xMaxSize )
{
xMaxSize = pxBlock->xBlockSize;
}
if( pxBlock->xBlockSize < xMinSize )
{
xMinSize = pxBlock->xBlockSize;
}
/* Move to the next block in the chain until the last block is
* reached. */
pxBlock = pxBlock->pxNextFreeBlock;
}
}
}
( void ) xTaskResumeAll();
pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;
pxHeapStats->xNumberOfFreeBlocks = xBlocks;
taskENTER_CRITICAL();
{
pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining;
pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations;
pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees;
pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining;
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
@@ -1,547 +0,0 @@
/*
* FreeRTOS Kernel V10.3.1
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
* A sample implementation of pvPortMalloc() that allows the heap to be defined
* across multiple non-contigous blocks and combines (coalescences) adjacent
* memory blocks as they are freed.
*
* See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative
* implementations, and the memory management pages of http://www.FreeRTOS.org
* for more information.
*
* Usage notes:
*
* vPortDefineHeapRegions() ***must*** be called before pvPortMalloc().
* pvPortMalloc() will be called if any task objects (tasks, queues, event
* groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be
* called before any other objects are defined.
*
* vPortDefineHeapRegions() takes a single parameter. The parameter is an array
* of HeapRegion_t structures. HeapRegion_t is defined in portable.h as
*
* typedef struct HeapRegion
* {
* uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap.
* size_t xSizeInBytes; << Size of the block of memory.
* } HeapRegion_t;
*
* The array is terminated using a NULL zero sized region definition, and the
* memory regions defined in the array ***must*** appear in address order from
* low address to high address. So the following is a valid example of how
* to use the function.
*
* HeapRegion_t xHeapRegions[] =
* {
* { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000
* { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000
* { NULL, 0 } << Terminates the array.
* };
*
* vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions().
*
* Note 0x80000000 is the lower address so appears in the array first.
*
*/
#include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h"
#include "task.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/* Block sizes must not get too small. */
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
/* Assumes 8bit bytes! */
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
/* Define the linked list structure. This is used to link free blocks in order
of their memory address. */
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} BlockLink_t;
/*-----------------------------------------------------------*/
/*
* Inserts a block of memory that is being freed into the correct position in
* the list of free memory blocks. The block being freed will be merged with
* the block in front it and/or the block behind it if the memory blocks are
* adjacent to each other.
*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
/*-----------------------------------------------------------*/
/* The size of the structure placed at the beginning of each allocated memory
block must by correctly byte aligned. */
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
/* Create a couple of list links to mark the start and end of the list. */
static BlockLink_t xStart, *pxEnd = NULL;
/* Keeps track of the number of calls to allocate and free memory as well as the
number of free bytes remaining, but says nothing about fragmentation. */
static size_t xFreeBytesRemaining = 0U;
static size_t xMinimumEverFreeBytesRemaining = 0U;
static size_t xNumberOfSuccessfulAllocations = 0;
static size_t xNumberOfSuccessfulFrees = 0;
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
member of an BlockLink_t structure is set then the block belongs to the
application. When the bit is free the block is still part of the free heap
space. */
static size_t xBlockAllocatedBit = 0;
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
{
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
void *pvReturn = NULL;
/* The heap must be initialised before the first call to
prvPortMalloc(). */
configASSERT( pxEnd );
vTaskSuspendAll();
{
/* Check the requested block size is not so large that the top bit is
set. The top bit of the block size member of the BlockLink_t structure
is used to determine who owns the block - the application or the
kernel, so it must be free. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{
/* The wanted size is increased so it can contain a BlockLink_t
structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number
of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{
/* Traverse the list from the start (lowest address) block until
one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
/* If the end marker was reached then a block of adequate size
was not found. */
if( pxBlock != pxEnd )
{
/* Return the memory space pointed to - jumping over the
BlockLink_t structure at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
/* This block is being returned for use so must be taken out
of the list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into
two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
{
/* This block is to be split into two. Create a new
block following the number of bytes requested. The void
cast is used to prevent byte alignment warnings from the
compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
/* Calculate the sizes of two blocks split from the
single block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
xFreeBytesRemaining -= pxBlock->xBlockSize;
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
{
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* The block is being returned - it is allocated and owned
by the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL;
xNumberOfSuccessfulAllocations++;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
traceMALLOC( pvReturn, xWantedSize );
}
( void ) xTaskResumeAll();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif
return pvReturn;
}
/*-----------------------------------------------------------*/
void vPortFree( void *pv )
{
uint8_t *puc = ( uint8_t * ) pv;
BlockLink_t *pxLink;
if( pv != NULL )
{
/* The memory being freed will have an BlockLink_t structure immediately
before it. */
puc -= xHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc;
/* Check the block is actually allocated. */
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
configASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
{
if( pxLink->pxNextFreeBlock == NULL )
{
/* The block is being returned to the heap - it is no longer
allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;
vTaskSuspendAll();
{
/* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize );
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
xNumberOfSuccessfulFrees++;
}
( void ) xTaskResumeAll();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
/*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void )
{
return xFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
size_t xPortGetMinimumEverFreeHeapSize( void )
{
return xMinimumEverFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
{
BlockLink_t *pxIterator;
uint8_t *puc;
/* Iterate through the list until a block is found that has a higher address
than the block being inserted. */
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{
/* Nothing to do here, just iterate to the right position. */
}
/* Do the block being inserted, and the block it is being inserted after
make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
pxBlockToInsert = pxIterator;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* Do the block being inserted, and the block it is being inserted before
make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{
if( pxIterator->pxNextFreeBlock != pxEnd )
{
/* Form one big block from the two blocks. */
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxEnd;
}
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
}
/* If the block being inserted plugged a gab, so was merged with the block
before and the block after, then it's pxNextFreeBlock pointer will have
already been set, and should not be set here as that would make it point
to itself. */
if( pxIterator != pxBlockToInsert )
{
pxIterator->pxNextFreeBlock = pxBlockToInsert;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/*-----------------------------------------------------------*/
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions )
{
BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;
size_t xAlignedHeap;
size_t xTotalRegionSize, xTotalHeapSize = 0;
BaseType_t xDefinedRegions = 0;
size_t xAddress;
const HeapRegion_t *pxHeapRegion;
/* Can only call once! */
configASSERT( pxEnd == NULL );
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
while( pxHeapRegion->xSizeInBytes > 0 )
{
xTotalRegionSize = pxHeapRegion->xSizeInBytes;
/* Ensure the heap region starts on a correctly aligned boundary. */
xAddress = ( size_t ) pxHeapRegion->pucStartAddress;
if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
{
xAddress += ( portBYTE_ALIGNMENT - 1 );
xAddress &= ~portBYTE_ALIGNMENT_MASK;
/* Adjust the size for the bytes lost to alignment. */
xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress;
}
xAlignedHeap = xAddress;
/* Set xStart if it has not already been set. */
if( xDefinedRegions == 0 )
{
/* xStart is used to hold a pointer to the first item in the list of
free blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
}
else
{
/* Should only get here if one region has already been added to the
heap. */
configASSERT( pxEnd != NULL );
/* Check blocks are passed in with increasing start addresses. */
configASSERT( xAddress > ( size_t ) pxEnd );
}
/* Remember the location of the end marker in the previous region, if
any. */
pxPreviousFreeBlock = pxEnd;
/* pxEnd is used to mark the end of the list of free blocks and is
inserted at the end of the region space. */
xAddress = xAlignedHeap + xTotalRegionSize;
xAddress -= xHeapStructSize;
xAddress &= ~portBYTE_ALIGNMENT_MASK;
pxEnd = ( BlockLink_t * ) xAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block in this region that is
sized to take up the entire heap region minus the space taken by the
free block structure. */
pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap;
pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion;
pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd;
/* If this is not the first region that makes up the entire heap space
then link the previous region to this region. */
if( pxPreviousFreeBlock != NULL )
{
pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion;
}
xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize;
/* Move onto the next HeapRegion_t structure. */
xDefinedRegions++;
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
}
xMinimumEverFreeBytesRemaining = xTotalHeapSize;
xFreeBytesRemaining = xTotalHeapSize;
/* Check something was actually defined before it is accessed. */
configASSERT( xTotalHeapSize );
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
}
/*-----------------------------------------------------------*/
void vPortGetHeapStats( HeapStats_t *pxHeapStats )
{
BlockLink_t *pxBlock;
size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */
vTaskSuspendAll();
{
pxBlock = xStart.pxNextFreeBlock;
/* pxBlock will be NULL if the heap has not been initialised. The heap
is initialised automatically when the first allocation is made. */
if( pxBlock != NULL )
{
do
{
/* Increment the number of blocks and record the largest block seen
so far. */
xBlocks++;
if( pxBlock->xBlockSize > xMaxSize )
{
xMaxSize = pxBlock->xBlockSize;
}
/* Heap five will have a zero sized block at the end of each
each region - the block is only used to link to the next
heap region so it not a real block. */
if( pxBlock->xBlockSize != 0 )
{
if( pxBlock->xBlockSize < xMinSize )
{
xMinSize = pxBlock->xBlockSize;
}
}
/* Move to the next block in the chain until the last block is
reached. */
pxBlock = pxBlock->pxNextFreeBlock;
} while( pxBlock != pxEnd );
}
}
xTaskResumeAll();
pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;
pxHeapStats->xNumberOfFreeBlocks = xBlocks;
taskENTER_CRITICAL();
{
pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining;
pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations;
pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees;
pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining;
}
taskEXIT_CRITICAL();
}
File diff suppressed because it is too large Load Diff
-17
View File
@@ -1,17 +0,0 @@
Each real time kernel port consists of three files that contain the core kernel
components and are common to every port, and one or more files that are
specific to a particular microcontroller and or compiler.
+ The FreeRTOS/Source directory contains the three files that are common to
every port - list.c, queue.c and tasks.c. The kernel is contained within these
three files. croutine.c implements the optional co-routine functionality - which
is normally only used on very memory limited systems.
+ The FreeRTOS/Source/Portable directory contains the files that are specific to
a particular microcontroller and or compiler.
+ The FreeRTOS/Source/include directory contains the real time kernel header
files.
See the readme file in the FreeRTOS/Source/Portable directory for more
information.
-422
View File
@@ -1,422 +0,0 @@
@verbatim
******************************************************************************
*
* Portions Copyright © 2019 STMicroelectronics International N.V. All rights reserved.
* Portions Copyright (C) 2016 Real Time Engineers Ltd, All rights reserved
*
* @file st_readme.txt
* @author MCD Application Team
* @brief This file lists the main modification done by STMicroelectronics on
* FreeRTOS for integration with STM32Cube solution.
* For more details on FreeRTOS implementation on STM32Cube, please refer
* to UM1722 "Developing Applications on STM32Cube with FreeRTOS"
******************************************************************************
*
* Copyright (c) 2019 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
@endverbatim
=======
### 31-August-2020 ###
=========================
+ Bug fix for G0 compilation error due to IRQn_Type mismatch between G0 and other families
- Source/CMSIS_RTOS_V2/cmsis_os2.c
+ Bug fix when using systick as timebasse for HAL
- Source/CMSIS_RTOS_V2/cmsis_os2.c
### 20-July-2020 ###
=========================
+ FreeRTOS: Update to FreeRTOS v10.3.1
+ CMSIS_RTOS_V2: update against the latest CMSIS-FreeRTOS v10.3.0 release
- CMSIS_RTOS_V2/cmsis_os2.c
- CMSIS_RTOS_V2/freertos_mpool.h
- CMSIS_RTOS_V2/freertos_os2.h
- CMSIS_RTOS_V2/os_systick.c
+ Add Tickless Idle support for CM23/CM33
- GCC/ARM_CM23/non_secure/port.c
- GCC/ARM_CM23/non_secure/portmacro.h
- GCC/ARM_CM23_NTZ/non_secure/port.c
- GCC/ARM_CM23_NTZ/non_secure/portmacro.h
- GCC/ARM_CM33/non_secure/port.c
- GCC/ARM_CM33/non_secure/portmacro.h
- GCC/ARM_CM33_NTZ/non_secure/port.c
- GCC/ARM_CM33_NTZ/non_secure/portmacro.h
- IAR/ARM_CM23/non_secure/port.c
- IAR/ARM_CM23/non_secure/portmacro.h
- IAR/ARM_CM23_NTZ/non_secure/port.c
- IAR/ARM_CM23_NTZ/non_secure/portmacro.h
- IAR/ARM_CM33/non_secure/port.c
- IAR/ARM_CM33/non_secure/portmacro.h
- IAR/ARM_CM33_NTZ/non_secure/port.c
- IAR/ARM_CM33_NTZ/non_secure/portmacro.h
+ Fix MPU hardfault bug for Cortex-M4 MPU
- GCC\ARM_CM4_MPU\port.c
- IAR\ARM_CM4_MPU\port.c
- RVDS\ARM_CM4_MPU\port.c
+ Add support for 16 MPU regions to Cortex-M4 MPU ports
- GCC/ARM_CM4_MPU/portmacro.h
- IAR/ARM_CM4_MPU/portmacro.h
- RVDS/ARM_CM4_MPU/portmacro.h
+ Update ARM_CM7_MPU source files for all compilers
- GCC/ARM_CM7_MPU/r0p1/port.c
- GCC/ARM_CM7_MPU/r0p1/portmacro.h
- IAR/ARM_CM7_MPU/r0p1/port.c
- IAR/ARM_CM7_MPU/r0p1/portasm.s
- IAR/ARM_CM7_MPU/r0p1/portmacro.h
- RVDS/ARM_CM7_MPU/r0p1/port.c
- RVDS/ARM_CM7_MPU/r0p1/portmacro.h
### 17-January-2020 ###
=========================
+ Fix compile error in the GCC CM7_MPU port caused by a duplicated variable declaration
- Source/portable/GCC/ARM_CM7_MPU/r0p1/port.c
### 13-December-2019 ###
=========================
+ Remove warnings thrown by EWARM for CM33/CM23 ports
- IAR/ARM_CM23/non_secure/portmacro.h
- IAR/ARM_CM23_NTZ/non_secure/portmacro.h
- IAR/ARM_CM33/non_secure/portmacro.h
- IAR/ARM_CM33_NTZ/non_secure/portmacro.h
### 19-July-2019 ###
=========================
+ Fix runtime error in the IAR/CM4_MPU port
- IAR/ARM_CM4_MPU/port.c
### 12-July-2019 ###
=========================
+ FreeRTOS: Update against the FreeRTOS v10.2.1 release
- support for the CM33 and CM23 cores
+ CMSIS_RTOS_V2: update against the latest CMSIS-FreeRTOS v10.2.0 release
+ Add MPU support for the CM7/r0p1:
- GCC/ARM_CM7_MPU/r0p1/port.c
- GCC/ARM_CM7_MPU/r0p1/portmacro.h
- IAR/ARM_CM7_MPU/r0p1/port.c
- IAR/ARM_CM7_MPU/r0p1/portasm.s
- IAR/ARM_CM7_MPU/r0p1/portmacro.h
- RVDS/ARM_CM7_MPU/r0p1/port.c
- RVDS/ARM_CM7_MPU/r0p1/portmacro.h
+ cmsis_os.c: Fix compile errors by using the correct TimerCallbackFunction_t type for timer creation
### 29-Mars-2019 ###
=========================
+ cmsis_os.c : Fix bug in osPoolAlloc(): memory blocks can't be reused after being free'd
+ Source/CMSIS_RTOS_V2/cmsis_os, Source/CMSIS_RTOS_V2/cmsis_os1.c, Source/CMSIS_RTOS_V2/cmsis_os2.c, Source/CMSIS_RTOS_V2/cmsis_os2.h: restore original Apache license terms
+ st_readme.txt: update license terms to BSD-3-Clause
### 13-August-2018 ###
=========================
+ Add empty implementation for the missing function osThreadGetStackSize()
to avoid link errors when using CMSIS-RTOS V2.
+ Update the FreeRTOSConfig_template.h with specific defines for the
CMSIS-RTOS V2.
+ Rename the "RTE_RTOS_FreeRTOS_XXXX" macros to "USE_FreeRTOS_XXXX" in
cmsis_os2.c.
### 30-July-2018 ###
=========================
+ Update License.txt file to MIT license instead of GPLv2
### 23-July-2018 ###
=========================
+ Fix compiler warnings thrown by IAR compiler 8.20
+ Add MPU support for the CM7/r0p1:
- GCC/ARM_CM7_MPU/r0p1/port.c
- GCC/ARM_CM7_MPU/r0p1/portmacro.h
- IAR/ARM_CM7_MPU/r0p1/port.c
- IAR/ARM_CM7_MPU/r0p1/portasm.s
- IAR/ARM_CM7_MPU/r0p1/portmacro.h
- RVDS/ARM_CM7_MPU/r0p1/port.c
- RVDS/ARM_CM7_MPU/r0p1/portmacro.h
### 09-April-2018 ###
=========================
Update the FreeRTOS against the latest release 10.0.1
more details are available in: https://www.freertos.org/History.txt
+ Integrate support for tickless mode for ARM_CM0 core:
- GCC/ARM_CM0/port.c
- GCC/ARM_CM0/portmacro.h
- IAR/ARM_CM0/port.c
- IAR/ARM_CM0/portmacro.h
- RVDS/ARM_CM0/port.c
Integrate CMSIS-RTOSv2 wrapper based on: https://github.com/ARM-software/CMSIS-FreeRTOS/releases/tag/10.0.1
+ Add new files:
- CMSIS_RTOS_V2/cmsis_os.h
- CMSIS_RTOS_V2/cmsis_os1.c
- CMSIS_RTOS_V2/cmsis_os2.c
- CMSIS_RTOS_V2/cmsis_os2.h
"cmsis_os1.c" and "cmsis_os1.h" contains the reference implementation of
CMSIS-RTOSv1,i.e as released by ARM, using the CMSIS-RTOSV2 API.
+ The ST customized CMSIS-RTOSv1 is maintained under:
- CMSIS_RTOS/cmsis_os.c
- CMSIS_RTOS/cmsis_os.h
+ When using CMSIS-RTOSv2 APIs, the following FreeRTOS defines are required:
- #define configMAX_PRIORITIES 56
- #define configSUPPORT_STATIC_ALLOCATION 0
- #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
### 10-August-2017 ###
=========================
Update FreeRTOS to support MPU feature with IAR compiler.
+ Add the following ports:
- IAR/ARM_CM4_MPU
- IAR/ARM_CM7_MPU
- RVDS/ARM_CM7_MPU
### 03-March-2017 ###
=========================
Update CMSIS-RTOS drivers to support both CMSIS Core V4.x and V5.x
Bug fixes:
+ CMSIS-RTOS: Wrong return value for osSignalWait()
+ CMSIS-RTOS: Not all queue size is 0 initialized with osMailCAlloc()
Limitation:
+ CMSIS-RTOS: osSignalWAit() function is not fully compliant with the specification
### 30-September-2016 ###
=========================
The purpose of this release is to Upgrade to use FreeRTOS V9.0.0, this version
is a drop-in compatible replacement for FreeRTOS V8.2.3.
For more details please refer to http://www.freertos.org/History.txt
+ Add support to tickless mode for MPU ports:
- GCC/ARM_CM3_MPU/port.c
- GCC/ARM_CM4_MPU/port.c
- RVDS/ARM_CM4_MPU/port.c
+ Update CM0 ports, add possibility to use a timebase different than Systick:
- IAR/ARM_CM0/port.c
- RVDS/ARM_CM0/port.c
- GCC/ARM_CM0/port.c
+ Fix compilation error in CM3_MPU and CM4_MPU ports:
- GCC/ARM_CM3_MPU/portmacro.h
- GCC/ARM_CM4_MPU/portmacro.h
- RVDS/ARM_CM4_MPU/portmacro.h
- Add "Source\portable\Common\" directory
+ cmsis_os.c
- Add support of Statically Allocated Systems introduced with FreeRTOS V9.0.0
- Add new wrappers CMSIS-RTOS APIs
FreeRTOS APIs | CMSIS-RTOS APIs | Description
==================================================================================================================
uxQueueMessagesWaiting() | osMessageWaiting() | Return the number of messages stored in a queue
------------------------------------------------------------------------------------------------------------------
xTaskAbortDelay() | osAbortDelay() | Force a thread to get out the blocked state immediately
------------------------------------------------------------------------------------------------------------------
uxSemaphoreGetCount() | osSemaphoreGetCount() | Return the current count of a semaphore
------------------------------------------------------------------------------------------------------------------
uxQueueSpacesAvailable() | osMessageAvailableSpace() | Return the available space in a message queue
------------------------------------------------------------------------------------------------------------------
vQueueDelete() | osMessageDelete() | Delete a message Queue
------------------------------------------------------------------------------------------------------------------
### 22-January-2016 ###
=======================
The purpose of this release is to Upgrade to use FreeRTOS V8.2.3.
It also provides fixes for minor issues.
+ cmsis_os.c
- Implementation of functions "osSignalSet" and "osSignalWait" are now delimited by
#define configUSE_TASK_NOTIFICATIONS.
- Function "osTimerStart" : fix for an assert issue when called from an ISR.
- Function "osMailCreate" : internal variables initialization.
- Function "osSignalWait" : signals value is now compared versus integer zero for error checking.
+ freeRTOS sources
- FreeRTOS.h file : Add configuration sanity check in case of configUSE_RECURSIVE_MUTEXES set
and configUSE_MUTEXES not set.
+ STMicroelectronics license simplifications, see license disclaimer within this file's header
### 27-March-2015 ###
=====================
The purpose of this release is to Upgrade to use FreeRTOS V8.2.1.
+ Major change of the version 8.2.1 is the support of CM7 core.
For STM32F746xx/STM32F756xx devices, need to use port files under Source/Portable/XXX/ARM_CM7/r0p1,
where XXX refers to the compiler used.
+ It also provides implementation of osSignal management APIs, osSignalSet() and osSignalWait(),
fixes osMassage queue size, osMailQDef macro and osDelayUntil parameters.
+ In this release an alignment has been done in ARM_CM4 and ARM_CM3 port.c versus ARM_CM0 port.c
regarding the use of macros configPRE_SLEEP_PROCESSING and configPOST_SLEEP_PROCESSING, these tow macros
are now taking as parameter as pointer to TickType_t.
+ cmsis_os.c
- Add implementation of osSignalSet() and osSignalWait() APIs
- Fix massage queue size in osMessageCreate API
- osDelayUntil: parameter PreviousWakeTime is now passed as a pointer.
- Enabling Mail queue management APIs (temporary removed in previous version).
- Function "osThreadGetPriority" uses now uxTaskPriorityGetFromISR if called from an interrupt handler, if not use uxTaskPriorityGet.
+ cmsis_os.h
- osFeature_Wait is defined to 0 to indicate that osWait function is not available (as specified by cmsis_os template by ARM)
- Fix compilation issue with osMailQDef macro.
- Enabling Mail queue management APIs (temporary removed in previous version)
+ freeRTOS sources
- ARM_CM3 port.c and ARM_CM4 port.c:
function vPortSuppressTicksAndSleep : configPRE_SLEEP_PROCESSING and configPOST_SLEEP_PROCESSING are now taking
as parameter as pointer to TickType_t.
The purpose of this change is to align the CM3 and CM4 implementation with CM0 one.
+ Note
- osSignalSet returns an int32_t value which is a a status (osOK or osError)
instead of the previous signal value as specified in cmsis_os template by ARM.
This is mainly due to freeRTOS implementation, the return value will be aligned (with the cmsis os template by ARM) as soon as the freeRTOS next version will allow it.
- osThreadDef() macro is defined in the freeRTOS cmsis_os.h wrapper as follow :
osThreadDef(name, thread, priority, instances, stacksz)
the macro osThreadDef() as defined in ARM cmsis_os.h is defined with 4 parameters :
name : name of the thread function.
priority : initial priority of the thread function.
instances : number of possible thread instances.
stacksz : stack size (in bytes) requirements for the thread function.
- osThreadDef as defined in the ARM template file cmsis_os.h assumes that the thread name is the same as the thread function name.
where the freeRTOS implementation gives separate parameters for the thread name and the thread function name.
care must be taken when porting an application from/to another OS to/from freeRTOS cmsis_os regarding this macro.
the macro osThreadDef() as defined in ARM cmsis_os.h template is defined with 4 parameters :
name : name of the thread function.
priority : initial priority of the thread function.
instances : number of possible thread instances.
stacksz : stack size (in bytes) requirements for the thread function.
the macro osThreadDef() as defined in freeRTOS cmsis_os.h is defined with 5 parameters :
name : name of the thread (used for debugging and trace).
thread : name of the thread function
priority : initial priority of the thread function.
instances : number of possible thread instances.
stacksz : stack size (in bytes) requirements for the thread function.
### 25-December-2014 ###
========================
The purpose of this release is to remove compilation errors and warning. It also reintroduces
the function osThreadIsSuspended() which has been removed in the version V1.2.0.
+ cmsis_os.c
- osThreadGetPriority() and makeCmsisPriority(): replace INCLUDE_vTaskPriorityGet by the correct
freeRTOS constant uxTaskPriorityGet.
The version 1.2.2 is using a wrong constant INCLUDE_vTaskPriorityGet, while the correct freeRTOS
constant is uxTaskPriorityGet.
This fix ensure a safe use of osThreadGetPriority() function.
- osThreadIsSuspended(): this function has been removed in version V1.2.0, it is now available gain.
User can either use this function to check if a Thread is suspended either use function osThreadGetState,
which is more generic, to check the exact state of a thread.
- osThreadList(): this function is now taking as argument a pointer to uint8_t instead of a pointer to int8_t.
The change is made to remove a compilation warning.
- osRecursiveMutexCreate(): the prototype has been changed to osMutexId osRecursiveMutexCreate (const osMutexDef_t *mutex_def)
This change is made to make osRecursiveMutexCreate() compatible with function MutexCreate().
It also allow the better use of the function in conjunction with the macro osMutex, note that osMutex return a
"const osMutexDef_t *mutex_def".
example : osMutex1Id = osRecursiveMutexCreate (osMutex(Mutex1));
- Fix implementation of functions osSemaphoreWait(), osMutexRelease() and osMutexWait() by using the appropriate
freeRTOS “FromISR” APIs when called from an interrupt.
- Fix compilation warning when the constant INCLUDE_eTaskGetState is not defined
+ cmsis_os.h
- osThreadIsSuspended(): add function prototype.
- osThreadList(): function prototype modified as described in cmsis_os.c section.
- osRecursiveMutexCreate(): function modified as described in cmsis_os.c section.
+ Important note:
Mail Queue Management Functions are not supported in this cmsis_os version, will be added in the next release.
### 04-December-2014 ###
========================
+ cmsis_os.c, osSemaphoreCreate(): use vSemaphoreCreateBinary() instead of xSemaphoreCreateBinary(),
to keep compatibility with application code developed on FreeRTOS V7.6.0.
### 07-November-2014 ###
========================
+ cmsis_os.h: modify the osThreadState enum to fix warning generated by ARMCC compiler
+ task.c: add preprocessor compilation condition for prvTaskIsTaskSuspended() function
(it's build only when INCLUDE_vTaskSuspend option is enabled in FreeRTOSConfig.h file)
### 04-November-2014 ###
========================
+ Upgrade to use FreeRTOS V8.1.2 and CMSIS-RTOS V1.02.
+ cmsis_os.c
- Almost of CMSIS-RTOS APIs are implemented for FreeRTOS
- Additional wrapper APIs created for FreeRTOS
+ Important note:
When upgrading existing application code to use this last version, the following
update should be considered:
- osThreadIsSuspended() is no longer public API in FreeRTOS and it should
be replaced by the wrapping of eTaskGetState()
- osKernelStart() API changed, must be updated
- update FreeRTOSConfig.h file, taking FreeRTOSConfig_template.h file as reference
### 13-June-2014 ###
====================
+ FreeRTOSConfig_template.h: add this definition #define INCLUDE_xTaskGetSchedulerState 1
to enable the use of xTaskGetSchedulerState() API in the
application code.
### 30-April-2014 ###
=====================
+ cmsis_os.c: add preprocessor compilation condition when calling some FreeRTOS APIs, to avoid link
errors with MDK-ARM when some FreeRTOS features are not enabled in FreeRTOSConfig.h
### 22-April-2014 ###
=====================
+ Add Tickles mode for CM0 port (IAR, GCC, RVDS).
### 18-February-2014 ###
========================
+ FreeRTOS V7.6.0 customized version for STM32Cube solution.
* <h3><center>&copy; COPYRIGHT STMicroelectronics</center></h3>
*/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+24 -1
View File
@@ -16,6 +16,10 @@ set(MX_Include_Dirs
${CMAKE_CURRENT_SOURCE_DIR}/../../USB_DEVICE/Target ${CMAKE_CURRENT_SOURCE_DIR}/../../USB_DEVICE/Target
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Inc ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Inc
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/include
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/CMSIS/RTOS2/Include
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Core/Inc ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Core/Inc
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/CMSIS/Device/ST/STM32H7xx/Include ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/CMSIS/Device/ST/STM32H7xx/Include
@@ -31,6 +35,7 @@ set(MX_Application_Src
${CMAKE_CURRENT_SOURCE_DIR}/../../USB_DEVICE/App/usbd_cdc_if.c ${CMAKE_CURRENT_SOURCE_DIR}/../../USB_DEVICE/App/usbd_cdc_if.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/gpio.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/gpio.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/freertos.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/adc.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/adc.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/dma.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/dma.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/fdcan.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/fdcan.c
@@ -90,6 +95,19 @@ set(USB_Device_Library_Src
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
) )
set(FreeRTOS_Src
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers_v2.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/croutine.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/list.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/queue.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/tasks.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/timers.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
)
# Link directories setup # Link directories setup
set(MX_LINK_DIRS set(MX_LINK_DIRS
@@ -99,7 +117,7 @@ set(MX_LINK_DIRS
set(MX_LINK_LIBS set(MX_LINK_LIBS
STM32_Drivers STM32_Drivers
${TOOLCHAIN_LINK_LIBRARIES} ${TOOLCHAIN_LINK_LIBRARIES}
USB_Device_Library USB_Device_Library FreeRTOS
) )
# Interface library for includes and symbols # Interface library for includes and symbols
add_library(stm32cubemx INTERFACE) add_library(stm32cubemx INTERFACE)
@@ -117,6 +135,11 @@ add_library(USB_Device_Library OBJECT)
target_sources(USB_Device_Library PRIVATE ${USB_Device_Library_Src}) target_sources(USB_Device_Library PRIVATE ${USB_Device_Library_Src})
target_link_libraries(USB_Device_Library PUBLIC stm32cubemx) target_link_libraries(USB_Device_Library PUBLIC stm32cubemx)
# Create FreeRTOS static library
add_library(FreeRTOS OBJECT)
target_sources(FreeRTOS PRIVATE ${FreeRTOS_Src})
target_link_libraries(FreeRTOS PUBLIC stm32cubemx)
# Add STM32CubeMX generated application sources to the project # Add STM32CubeMX generated application sources to the project
target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${MX_Application_Src}) target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${MX_Application_Src})
+3 -3
View File
@@ -3,7 +3,7 @@
VisionData_t vision_data; VisionData_t vision_data;
static USARTInstance *cv_usart_instance; static USARTInstance *cv_usart_instance;
static DaemonInstance *vision_daemon_instance; //static DaemonInstance *vision_daemon_instance;
static uint8_t calc_checksum(uint8_t *buf, uint8_t len) static uint8_t calc_checksum(uint8_t *buf, uint8_t len)
{ {
@@ -15,7 +15,7 @@ static uint8_t calc_checksum(uint8_t *buf, uint8_t len)
static void DecodeVision() static void DecodeVision()
{ {
DaemonReload(vision_daemon_instance); //DaemonReload(vision_daemon_instance);
static uint32_t counter; static uint32_t counter;
float dt = DWT_GetDeltaT(&counter); float dt = DWT_GetDeltaT(&counter);
@@ -71,5 +71,5 @@ void Vision_Uart_Init(UART_HandleTypeDef *_handle)
.owner_id = NULL, .owner_id = NULL,
.reload_count = 10, .reload_count = 10,
}; };
vision_daemon_instance = DaemonRegister(&daemon_conf); //vision_daemon_instance = DaemonRegister(&daemon_conf);
} }
+2 -2
View File
@@ -111,7 +111,7 @@ static void DMMotorDecode(CANInstance *motor_can)
DM_Motor_Measure_s *measure = &motor->measure; DM_Motor_Measure_s *measure = &motor->measure;
uint16_t tmp; uint16_t tmp;
DaemonReload(motor->motor_daemon); //DaemonReload(motor->motor_daemon);
measure->id = rxbuff[0] & 0x0F; measure->id = rxbuff[0] & 0x0F;
measure->state = (rxbuff[0] >> 4) & 0x0F; measure->state = (rxbuff[0] >> 4) & 0x0F;
@@ -175,7 +175,7 @@ DMMotorInstance *DMMotorInit(DM_Motor_Init_Config_s *config)
.owner_id = motor, .owner_id = motor,
.reload_count = 10, .reload_count = 10,
}; };
motor->motor_daemon = DaemonRegister(&conf); //motor->motor_daemon = DaemonRegister(&conf);
/* enable motor */ /* enable motor */
DMMotorSetMode(DM_CMD_MOTOR_MODE, motor); DMMotorSetMode(DM_CMD_MOTOR_MODE, motor);