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",
+224 -243
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
+32 -20
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
@@ -51,11 +50,11 @@
#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.
+48 -38
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"
@@ -45,8 +46,8 @@
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. --------------------------------*/
@@ -65,13 +66,13 @@ static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
* 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
@@ -99,17 +100,20 @@ 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,
UBaseType_t uxIndex )
{ {
BaseType_t xReturn; BaseType_t xReturn;
CRCB_t * pxCoRoutine; 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( pxCoRoutine )
{ {
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to /* If pxCurrentCoRoutine is NULL then this is the first co-routine to
be created and the co-routine data structures need initialising. */ * be created and the co-routine data structures need initialising. */
if( pxCurrentCoRoutine == NULL ) if( pxCurrentCoRoutine == NULL )
{ {
pxCurrentCoRoutine = pxCoRoutine; pxCurrentCoRoutine = pxCoRoutine;
@@ -133,8 +137,8 @@ CRCB_t *pxCoRoutine;
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
/* Set the co-routine control block as a link back from the ListItem_t. /* Set the co-routine control block as a link back from the ListItem_t.
This is so we can get back to the containing CRCB from a generic item * This is so we can get back to the containing CRCB from a generic item
in a list. */ * in a list. */
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
@@ -142,7 +146,7 @@ CRCB_t *pxCoRoutine;
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
/* Now the co-routine has been initialised it can be added to the ready /* Now the co-routine has been initialised it can be added to the ready
list at the correct priority. */ * list at the correct priority. */
prvAddCoRoutineToReadyQueue( pxCoRoutine ); prvAddCoRoutineToReadyQueue( pxCoRoutine );
xReturn = pdPASS; xReturn = pdPASS;
@@ -156,17 +160,18 @@ CRCB_t *pxCoRoutine;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
@@ -175,20 +180,20 @@ TickType_t 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 ) );
} }
} }
@@ -197,8 +202,8 @@ TickType_t xTimeToWake;
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;
@@ -222,6 +227,7 @@ static void prvCheckDelayedList( void )
CRCB_t * pxCRCB; CRCB_t * pxCRCB;
xPassedTicks = xTaskGetTickCount() - xLastTickCount; xPassedTicks = xTaskGetTickCount() - xLastTickCount;
while( xPassedTicks ) while( xPassedTicks )
{ {
xCoRoutineTickCount++; xCoRoutineTickCount++;
@@ -233,7 +239,7 @@ CRCB_t *pxCRCB;
List_t * pxTemp; List_t * pxTemp;
/* Tick count has overflowed so we need to swap the delay lists. If there are /* Tick count has overflowed so we need to swap the delay lists. If there are
any items in pxDelayedCoRoutineList here then there is an error! */ * any items in pxDelayedCoRoutineList here then there is an error! */
pxTemp = pxDelayedCoRoutineList; pxTemp = pxDelayedCoRoutineList;
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
pxOverflowDelayedCoRoutineList = pxTemp; pxOverflowDelayedCoRoutineList = pxTemp;
@@ -253,10 +259,10 @@ CRCB_t *pxCRCB;
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
{ {
/* The event could have occurred just before this critical /* The event could have occurred just before this critical
section. If this is the case then the generic list item will * section. If this is the case then the generic list item will
have been moved to the pending ready list and the following * have been moved to the pending ready list and the following
line is still valid. Also the pvContainer parameter will have * line is still valid. Also the pvContainer parameter will have
been set to NULL so the following lines are also valid. */ * been set to NULL so the following lines are also valid. */
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
/* Is the co-routine waiting on an event also? */ /* Is the co-routine waiting on an event also? */
@@ -276,6 +282,11 @@ CRCB_t *pxCRCB;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vCoRoutineSchedule( void ) void vCoRoutineSchedule( void )
{
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been
* 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. */ /* See if any co-routines readied by events need moving to the ready lists. */
prvCheckPendingReadyList(); prvCheckPendingReadyList();
@@ -291,17 +302,17 @@ void vCoRoutineSchedule( void )
/* No more co-routines to check. */ /* No more co-routines to check. */
return; return;
} }
--uxTopCoRoutineReadyPriority; --uxTopCoRoutineReadyPriority;
} }
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
of the same priority get an equal share of the processor time. */ * of the same priority get an equal share of the processor time. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
/* Call the co-routine. */ /* Call the co-routine. */
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
}
return;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -319,7 +330,7 @@ UBaseType_t uxPriority;
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;
} }
@@ -331,8 +342,8 @@ 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 ) );
@@ -350,4 +361,3 @@ BaseType_t xReturn;
} }
#endif /* configUSE_CO_ROUTINES == 0 */ #endif /* configUSE_CO_ROUTINES == 0 */
+156 -110
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,18 +21,17 @@
* 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!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdlib.h> #include <stdlib.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
/* FreeRTOS includes. */ /* FreeRTOS includes. */
@@ -40,37 +41,22 @@ task.h is included from an application file. */
#include "event_groups.h" #include "event_groups.h"
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified /* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * 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 * for the header files above, but not in this file, in order to generate the
correct privileged Vs unprivileged linkage and placement. */ * correct privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */
/* The following bit fields convey control information in a task's event list
item value. It is important they don't clash with the
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
#if configUSE_16_BIT_TICKS == 1
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
#define eventWAIT_FOR_ALL_BITS 0x0400U
#define eventEVENT_BITS_CONTROL_BYTES 0xff00U
#else
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
#define eventWAIT_FOR_ALL_BITS 0x04000000UL
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
#endif
typedef struct EventGroupDef_t typedef struct EventGroupDef_t
{ {
EventBits_t uxEventBits; EventBits_t uxEventBits;
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ List_t xTasksWaitingForBits; /**< List of tasks waiting for a bit to be set. */
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxEventGroupNumber; UBaseType_t uxEventGroupNumber;
#endif #endif
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
#endif #endif
} EventGroup_t; } EventGroup_t;
@@ -84,7 +70,9 @@ typedef struct EventGroupDef_t
* wait condition is met if any of the bits set in uxBitsToWait for are also set * wait condition is met if any of the bits set in uxBitsToWait for are also set
* in uxCurrentEventBits. * in uxCurrentEventBits.
*/ */
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -100,8 +88,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
#if ( configASSERT_DEFINED == 1 ) #if ( configASSERT_DEFINED == 1 )
{ {
/* Sanity check that the size of the structure used to declare a /* Sanity check that the size of the structure used to declare a
variable of type StaticEventGroup_t equals the size of the real * variable of type StaticEventGroup_t equals the size of the real
event group structure. */ * event group structure. */
volatile size_t xSize = sizeof( StaticEventGroup_t ); volatile size_t xSize = sizeof( StaticEventGroup_t );
configASSERT( xSize == sizeof( EventGroup_t ) ); configASSERT( xSize == sizeof( EventGroup_t ) );
} /*lint !e529 xSize is referenced if configASSERT() is defined. */ } /*lint !e529 xSize is referenced if configASSERT() is defined. */
@@ -118,8 +106,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{ {
/* Both static and dynamic allocation can be used, so note that /* Both static and dynamic allocation can be used, so note that
this event group was created statically in case the event group * this event group was created statically in case the event group
is later deleted. */ * is later deleted. */
pxEventBits->ucStaticallyAllocated = pdTRUE; pxEventBits->ucStaticallyAllocated = pdTRUE;
} }
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
@@ -129,8 +117,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
else else
{ {
/* xEventGroupCreateStatic should only ever be called with /* xEventGroupCreateStatic should only ever be called with
pxEventGroupBuffer pointing to a pre-allocated (compile time * pxEventGroupBuffer pointing to a pre-allocated (compile time
allocated) StaticEventGroup_t variable. */ * allocated) StaticEventGroup_t variable. */
traceEVENT_GROUP_CREATE_FAILED(); traceEVENT_GROUP_CREATE_FAILED();
} }
@@ -147,18 +135,18 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
EventGroup_t * pxEventBits; EventGroup_t * pxEventBits;
/* Allocate the event group. Justification for MISRA deviation as /* Allocate the event group. Justification for MISRA deviation as
follows: pvPortMalloc() always ensures returned memory blocks are * follows: pvPortMalloc() always ensures returned memory blocks are
aligned per the requirements of the MCU stack. In this case * aligned per the requirements of the MCU stack. In this case
pvPortMalloc() must return a pointer that is guaranteed to meet the * pvPortMalloc() must return a pointer that is guaranteed to meet the
alignment requirements of the EventGroup_t structure - which (if you * alignment requirements of the EventGroup_t structure - which (if you
follow it through) is the alignment requirements of the TickType_t type * follow it through) is the alignment requirements of the TickType_t type
(EventBits_t being of TickType_t itself). Therefore, whenever the * (EventBits_t being of TickType_t itself). Therefore, whenever the
stack alignment requirements are greater than or equal to the * stack alignment requirements are greater than or equal to the
TickType_t alignment requirements the cast is safe. In other cases, * TickType_t alignment requirements the cast is safe. In other cases,
where the natural word size of the architecture is less than * where the natural word size of the architecture is less than
sizeof( TickType_t ), the TickType_t variables will be accessed in two * sizeof( TickType_t ), the TickType_t variables will be accessed in two
or more reads operations, and the alignment requirements is only that * or more reads operations, and the alignment requirements is only that
of each individual read. */ * of each individual read. */
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
if( pxEventBits != NULL ) if( pxEventBits != NULL )
@@ -169,8 +157,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
{ {
/* Both static and dynamic allocation can be used, so note this /* Both static and dynamic allocation can be used, so note this
event group was allocated statically in case the event group is * event group was allocated statically in case the event group is
later deleted. */ * later deleted. */
pxEventBits->ucStaticallyAllocated = pdFALSE; pxEventBits->ucStaticallyAllocated = pdFALSE;
} }
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
@@ -188,7 +176,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait )
{ {
EventBits_t uxOriginalBitValue, uxReturn; EventBits_t uxOriginalBitValue, uxReturn;
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
@@ -215,7 +206,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
uxReturn = ( uxOriginalBitValue | uxBitsToSet ); uxReturn = ( uxOriginalBitValue | uxBitsToSet );
/* Rendezvous always clear the bits. They will have been cleared /* Rendezvous always clear the bits. They will have been cleared
already unless this is the only task in the rendezvous. */ * already unless this is the only task in the rendezvous. */
pxEventBits->uxEventBits &= ~uxBitsToWaitFor; pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
xTicksToWait = 0; xTicksToWait = 0;
@@ -227,20 +218,20 @@ BaseType_t xTimeoutOccurred = pdFALSE;
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
/* Store the bits that the calling task is waiting for in the /* Store the bits that the calling task is waiting for in the
task's event list item so the kernel knows when a match is * task's event list item so the kernel knows when a match is
found. Then enter the blocked state. */ * found. Then enter the blocked state. */
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
/* This assignment is obsolete as uxReturn will get set after /* This assignment is obsolete as uxReturn will get set after
the task unblocks, but some compilers mistakenly generate a * the task unblocks, but some compilers mistakenly generate a
warning about uxReturn being returned without being set if the * warning about uxReturn being returned without being set if the
assignment is omitted. */ * assignment is omitted. */
uxReturn = 0; uxReturn = 0;
} }
else else
{ {
/* The rendezvous bits were not set, but no block time was /* The rendezvous bits were not set, but no block time was
specified - just return the current event bit value. */ * specified - just return the current event bit value. */
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
xTimeoutOccurred = pdTRUE; xTimeoutOccurred = pdTRUE;
} }
@@ -260,9 +251,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/* The task blocked to wait for its required bits to be set - at this /* The task blocked to wait for its required bits to be set - at this
point either the required bits were set or the block time expired. If * point either the required bits were set or the block time expired. If
the required bits were set they will have been stored in the task's * the required bits were set they will have been stored in the task's
event list item, and they should now be retrieved then cleared. */ * event list item, and they should now be retrieved then cleared. */
uxReturn = uxTaskResetEventItemValue(); uxReturn = uxTaskResetEventItemValue();
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
@@ -273,9 +264,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
/* Although the task got here because it timed out before the /* Although the task got here because it timed out before the
bits it was waiting for were set, it is possible that since it * bits it was waiting for were set, it is possible that since it
unblocked another task has set the bits. If this is the case * unblocked another task has set the bits. If this is the case
then it needs to clear the bits before exiting. */ * then it needs to clear the bits before exiting. */
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
{ {
pxEventBits->uxEventBits &= ~uxBitsToWaitFor; pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
@@ -295,7 +286,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/* Control bits might be set as the task had blocked should not be /* Control bits might be set as the task had blocked should not be
returned. */ * returned. */
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
} }
@@ -308,7 +299,11 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait )
{ {
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
EventBits_t uxReturn, uxControlBits = 0; EventBits_t uxReturn, uxControlBits = 0;
@@ -316,7 +311,7 @@ BaseType_t xWaitConditionMet, xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE; BaseType_t xTimeoutOccurred = pdFALSE;
/* Check the user is not attempting to wait on the bits used by the kernel /* Check the user is not attempting to wait on the bits used by the kernel
itself, and that at least one bit is being requested. */ * itself, and that at least one bit is being requested. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
configASSERT( uxBitsToWaitFor != 0 ); configASSERT( uxBitsToWaitFor != 0 );
@@ -336,7 +331,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
if( xWaitConditionMet != pdFALSE ) if( xWaitConditionMet != pdFALSE )
{ {
/* The wait condition has already been met so there is no need to /* The wait condition has already been met so there is no need to
block. */ * block. */
uxReturn = uxCurrentEventBits; uxReturn = uxCurrentEventBits;
xTicksToWait = ( TickType_t ) 0; xTicksToWait = ( TickType_t ) 0;
@@ -353,16 +348,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
else if( xTicksToWait == ( TickType_t ) 0 ) else if( xTicksToWait == ( TickType_t ) 0 )
{ {
/* The wait condition has not been met, but no block time was /* The wait condition has not been met, but no block time was
specified, so just return the current value. */ * specified, so just return the current value. */
uxReturn = uxCurrentEventBits; uxReturn = uxCurrentEventBits;
xTimeoutOccurred = pdTRUE; xTimeoutOccurred = pdTRUE;
} }
else else
{ {
/* The task is going to block to wait for its required bits to be /* The task is going to block to wait for its required bits to be
set. uxControlBits are used to remember the specified behaviour of * set. uxControlBits are used to remember the specified behaviour of
this call to xEventGroupWaitBits() - for use when the event bits * this call to xEventGroupWaitBits() - for use when the event bits
unblock the task. */ * unblock the task. */
if( xClearOnExit != pdFALSE ) if( xClearOnExit != pdFALSE )
{ {
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
@@ -382,13 +377,13 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/* Store the bits that the calling task is waiting for in the /* Store the bits that the calling task is waiting for in the
task's event list item so the kernel knows when a match is * task's event list item so the kernel knows when a match is
found. Then enter the blocked state. */ * found. Then enter the blocked state. */
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
/* This is obsolete as it will get set after the task unblocks, but /* This is obsolete as it will get set after the task unblocks, but
some compilers mistakenly generate a warning about the variable * some compilers mistakenly generate a warning about the variable
being returned without being set if it is not done. */ * being returned without being set if it is not done. */
uxReturn = 0; uxReturn = 0;
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
@@ -408,9 +403,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/* The task blocked to wait for its required bits to be set - at this /* The task blocked to wait for its required bits to be set - at this
point either the required bits were set or the block time expired. If * point either the required bits were set or the block time expired. If
the required bits were set they will have been stored in the task's * the required bits were set they will have been stored in the task's
event list item, and they should now be retrieved then cleared. */ * event list item, and they should now be retrieved then cleared. */
uxReturn = uxTaskResetEventItemValue(); uxReturn = uxTaskResetEventItemValue();
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
@@ -421,7 +416,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
/* It is possible that the event bits were updated between this /* It is possible that the event bits were updated between this
task leaving the Blocked state and running again. */ * task leaving the Blocked state and running again. */
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
{ {
if( xClearOnExit != pdFALSE ) if( xClearOnExit != pdFALSE )
@@ -437,6 +432,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
xTimeoutOccurred = pdTRUE; xTimeoutOccurred = pdTRUE;
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
@@ -449,6 +445,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
/* The task blocked so control bits may have been set. */ /* The task blocked so control bits may have been set. */
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
} }
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
/* Prevent compiler warnings when trace macros are not used. */ /* Prevent compiler warnings when trace macros are not used. */
@@ -458,13 +455,14 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear )
{ {
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
EventBits_t uxReturn; EventBits_t uxReturn;
/* Check the user is not attempting to clear the bits used by the kernel /* Check the user is not attempting to clear the bits used by the kernel
itself. */ * itself. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
@@ -473,7 +471,7 @@ EventBits_t uxReturn;
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
/* The value returned is the event group value prior to the bits being /* The value returned is the event group value prior to the bits being
cleared. */ * cleared. */
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
/* Clear the bits. */ /* Clear the bits. */
@@ -487,7 +485,8 @@ EventBits_t uxReturn;
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear )
{ {
BaseType_t xReturn; BaseType_t xReturn;
@@ -497,7 +496,7 @@ EventBits_t uxReturn;
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
@@ -516,9 +515,11 @@ EventBits_t uxReturn;
} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ } /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet )
{ {
ListItem_t *pxListItem, *pxNext; ListItem_t * pxListItem;
ListItem_t * pxNext;
ListItem_t const * pxListEnd; ListItem_t const * pxListEnd;
List_t const * pxList; List_t const * pxList;
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
@@ -526,7 +527,7 @@ EventGroup_t *pxEventBits = xEventGroup;
BaseType_t xMatchFound = pdFALSE; BaseType_t xMatchFound = pdFALSE;
/* Check the user is not attempting to set the bits used by the kernel /* Check the user is not attempting to set the bits used by the kernel
itself. */ * itself. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
@@ -587,21 +588,21 @@ BaseType_t xMatchFound = pdFALSE;
} }
/* Store the actual event flag value in the task's event list /* Store the actual event flag value in the task's event list
item before removing the task from the event list. The * item before removing the task from the event list. The
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows * eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
that is was unblocked due to its required bits matching, rather * that is was unblocked due to its required bits matching, rather
than because it timed out. */ * than because it timed out. */
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
} }
/* Move onto the next list item. Note pxListItem->pxNext is not /* Move onto the next list item. Note pxListItem->pxNext is not
used here as the list item may have been removed from the event list * used here as the list item may have been removed from the event list
and inserted into the ready/pending reading list. */ * and inserted into the ready/pending reading list. */
pxListItem = pxNext; pxListItem = pxNext;
} }
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
bit was set in the control word. */ * bit was set in the control word. */
pxEventBits->uxEventBits &= ~uxBitsToClear; pxEventBits->uxEventBits &= ~uxBitsToClear;
} }
( void ) xTaskResumeAll(); ( void ) xTaskResumeAll();
@@ -613,7 +614,11 @@ BaseType_t xMatchFound = pdFALSE;
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) void vEventGroupDelete( EventGroupHandle_t xEventGroup )
{ {
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); const List_t * pxTasksWaitingForBits;
configASSERT( pxEventBits );
pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
vTaskSuspendAll(); vTaskSuspendAll();
{ {
@@ -622,21 +627,23 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
{ {
/* Unblock the task, returning 0 as the event list is being deleted /* Unblock the task, returning 0 as the event list is being deleted
and cannot therefore have any bits set. */ * and cannot therefore have any bits set. */
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
} }
}
( void ) xTaskResumeAll();
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
{ {
/* The event group can only have been allocated dynamically - free /* The event group can only have been allocated dynamically - free
it again. */ * it again. */
vPortFree( pxEventBits ); vPortFree( pxEventBits );
} }
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
{ {
/* The event group could have been allocated statically or /* The event group could have been allocated statically or
dynamically, so check before attempting to free the memory. */ * dynamically, so check before attempting to free the memory. */
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
{ {
vPortFree( pxEventBits ); vPortFree( pxEventBits );
@@ -648,34 +655,72 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
} }
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
} }
( void ) xTaskResumeAll(); /*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
StaticEventGroup_t ** ppxEventGroupBuffer )
{
BaseType_t xReturn;
EventGroup_t * pxEventBits = xEventGroup;
configASSERT( pxEventBits );
configASSERT( ppxEventGroupBuffer );
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
/* Check if the event group was statically allocated. */
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE )
{
*ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits;
xReturn = pdTRUE;
} }
else
{
xReturn = pdFALSE;
}
}
#else /* configSUPPORT_DYNAMIC_ALLOCATION */
{
/* Event group must have been statically allocated. */
*ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits;
xReturn = pdTRUE;
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
return xReturn;
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* For internal use only - execute a 'set bits' command that was pended from /* For internal use only - execute a 'set bits' command that was pended from
an interrupt. */ * an interrupt. */
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) void vEventGroupSetBitsCallback( void * pvEventGroup,
const uint32_t ulBitsToSet )
{ {
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* For internal use only - execute a 'clear bits' command that was pended from /* For internal use only - execute a 'clear bits' command that was pended from
an interrupt. */ * an interrupt. */
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) void vEventGroupClearBitsCallback( void * pvEventGroup,
const uint32_t ulBitsToClear )
{ {
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xWaitForAllBits )
{ {
BaseType_t xWaitConditionMet = pdFALSE; BaseType_t xWaitConditionMet = pdFALSE;
if( xWaitForAllBits == pdFALSE ) if( xWaitForAllBits == pdFALSE )
{ {
/* Task only has to wait for one bit within uxBitsToWaitFor to be /* Task only has to wait for one bit within uxBitsToWaitFor to be
set. Is one already set? */ * set. Is one already set? */
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
{ {
xWaitConditionMet = pdTRUE; xWaitConditionMet = pdTRUE;
@@ -688,7 +733,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
else else
{ {
/* Task has to wait for all the bits in uxBitsToWaitFor to be set. /* Task has to wait for all the bits in uxBitsToWaitFor to be set.
Are they set already? */ * Are they set already? */
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
{ {
xWaitConditionMet = pdTRUE; xWaitConditionMet = pdTRUE;
@@ -705,7 +750,9 @@ BaseType_t xWaitConditionMet = pdFALSE;
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t * pxHigherPriorityTaskWoken )
{ {
BaseType_t xReturn; BaseType_t xReturn;
@@ -715,7 +762,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
@@ -742,12 +789,11 @@ BaseType_t xWaitConditionMet = pdFALSE;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) void vEventGroupSetNumber( void * xEventGroup,
UBaseType_t uxEventGroupNumber )
{ {
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
} }
#endif /* configUSE_TRACE_FACILITY */ #endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
+268 -103
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 INC_FREERTOS_H #ifndef INC_FREERTOS_H
@@ -48,13 +49,48 @@
*/ */
#include <stdint.h> /* READ COMMENT ABOVE. */ #include <stdint.h> /* READ COMMENT ABOVE. */
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/* Acceptable values for configTICK_TYPE_WIDTH_IN_BITS. */
#define TICK_TYPE_WIDTH_16_BITS 0
#define TICK_TYPE_WIDTH_32_BITS 1
#define TICK_TYPE_WIDTH_64_BITS 2
/* Application specific configuration options. */ /* Application specific configuration options. */
#include "FreeRTOSConfig.h" #include "FreeRTOSConfig.h"
#if !defined( configUSE_16_BIT_TICKS ) && !defined( configTICK_TYPE_WIDTH_IN_BITS )
#error Missing definition: One of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#if defined( configUSE_16_BIT_TICKS ) && defined( configTICK_TYPE_WIDTH_IN_BITS )
#error Only one of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details.
#endif
/* Define configTICK_TYPE_WIDTH_IN_BITS according to the
* value of configUSE_16_BIT_TICKS for backward compatibility. */
#ifndef configTICK_TYPE_WIDTH_IN_BITS
#if ( configUSE_16_BIT_TICKS == 1 )
#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_16_BITS
#else
#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS
#endif
#endif
/* Set configUSE_MPU_WRAPPERS_V1 to 1 to use MPU wrappers v1. */
#ifndef configUSE_MPU_WRAPPERS_V1
#define configUSE_MPU_WRAPPERS_V1 0
#endif
/* Set configENABLE_ACCESS_CONTROL_LIST to 1 to enable access control list support. */
#ifndef configENABLE_ACCESS_CONTROL_LIST
#define configENABLE_ACCESS_CONTROL_LIST 0
#endif
/* Basic FreeRTOS definitions. */ /* Basic FreeRTOS definitions. */
#include "projdefs.h" #include "projdefs.h"
@@ -68,8 +104,45 @@ extern "C" {
/* Required if struct _reent is used. */ /* Required if struct _reent is used. */
#if ( configUSE_NEWLIB_REENTRANT == 1 ) #if ( configUSE_NEWLIB_REENTRANT == 1 )
#include <reent.h>
#include "newlib-freertos.h"
#endif /* if ( configUSE_NEWLIB_REENTRANT == 1 ) */
/* Must be defaulted before configUSE_PICOLIBC_TLS is used below. */
#ifndef configUSE_PICOLIBC_TLS
#define configUSE_PICOLIBC_TLS 0
#endif #endif
#if ( configUSE_PICOLIBC_TLS == 1 )
#include "picolibc-freertos.h"
#endif /* if ( configUSE_PICOLIBC_TLS == 1 ) */
#ifndef configUSE_C_RUNTIME_TLS_SUPPORT
#define configUSE_C_RUNTIME_TLS_SUPPORT 0
#endif
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
#ifndef configTLS_BLOCK_TYPE
#error Missing definition: configTLS_BLOCK_TYPE must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
#endif
#ifndef configINIT_TLS_BLOCK
#error Missing definition: configINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
#endif
#ifndef configSET_TLS_BLOCK
#error Missing definition: configSET_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
#endif
#ifndef configDEINIT_TLS_BLOCK
#error Missing definition: configDEINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
#endif
#endif /* if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) */
/* /*
* Check all the required application specific macros have been defined. * Check all the required application specific macros have been defined.
* These macros are application specific and (as downloaded) are defined * These macros are application specific and (as downloaded) are defined
@@ -100,8 +173,10 @@ extern "C" {
#error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif #endif
#ifndef configUSE_16_BIT_TICKS #if ( ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_16_BITS ) && \
#error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_32_BITS ) && \
( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_64_BITS ) )
#error Macro configTICK_TYPE_WIDTH_IN_BITS is defined to incorrect value. See the Configuration section of the FreeRTOS API documentation for details.
#endif #endif
#ifndef configUSE_CO_ROUTINES #ifndef configUSE_CO_ROUTINES
@@ -124,8 +199,30 @@ extern "C" {
#define INCLUDE_vTaskSuspend 0 #define INCLUDE_vTaskSuspend 0
#endif #endif
#ifndef INCLUDE_vTaskDelayUntil #ifdef INCLUDE_xTaskDelayUntil
#define INCLUDE_vTaskDelayUntil 0 #ifdef INCLUDE_vTaskDelayUntil
/* INCLUDE_vTaskDelayUntil was replaced by INCLUDE_xTaskDelayUntil. Backward
* compatibility is maintained if only one or the other is defined, but
* there is a conflict if both are defined. */
#error INCLUDE_vTaskDelayUntil and INCLUDE_xTaskDelayUntil are both defined. INCLUDE_vTaskDelayUntil is no longer required and should be removed
#endif
#endif
#ifndef INCLUDE_xTaskDelayUntil
#ifdef INCLUDE_vTaskDelayUntil
/* If INCLUDE_vTaskDelayUntil is set but INCLUDE_xTaskDelayUntil is not then
* the project's FreeRTOSConfig.h probably pre-dates the introduction of
* xTaskDelayUntil and setting INCLUDE_xTaskDelayUntil to whatever
* INCLUDE_vTaskDelayUntil is set to will ensure backward compatibility.
*/
#define INCLUDE_xTaskDelayUntil INCLUDE_vTaskDelayUntil
#endif
#endif
#ifndef INCLUDE_xTaskDelayUntil
#define INCLUDE_xTaskDelayUntil 0
#endif #endif
#ifndef INCLUDE_vTaskDelay #ifndef INCLUDE_vTaskDelay
@@ -177,7 +274,7 @@ extern "C" {
#endif #endif
#ifndef INCLUDE_xTaskGetCurrentTaskHandle #ifndef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1
#endif #endif
#if configUSE_CO_ROUTINES != 0 #if configUSE_CO_ROUTINES != 0
@@ -242,10 +339,10 @@ extern "C" {
#endif #endif
/* configPRECONDITION should be defined as configASSERT. /* configPRECONDITION should be defined as configASSERT.
The CBMC proofs need a way to track assumptions and assertions. * The CBMC proofs need a way to track assumptions and assertions.
A configPRECONDITION statement should express an implicit invariant or * A configPRECONDITION statement should express an implicit invariant or
assumption made. A configASSERT statement should express an invariant that must * assumption made. A configASSERT statement should express an invariant that must
hold explicit before calling the code. */ * hold explicit before calling the code. */
#ifndef configPRECONDITION #ifndef configPRECONDITION
#define configPRECONDITION( X ) configASSERT( X ) #define configPRECONDITION( X ) configASSERT( X )
#define configPRECONDITION_DEFINED 0 #define configPRECONDITION_DEFINED 0
@@ -283,11 +380,11 @@ hold explicit before calling the code. */
#endif #endif
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR #ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue )
#endif #endif
#ifndef portCLEAN_UP_TCB #ifndef portCLEAN_UP_TCB
#define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB #define portCLEAN_UP_TCB( pxTCB ) ( void ) ( pxTCB )
#endif #endif
#ifndef portPRE_TASK_DELETE_HOOK #ifndef portPRE_TASK_DELETE_HOOK
@@ -295,7 +392,7 @@ hold explicit before calling the code. */
#endif #endif
#ifndef portSETUP_TCB #ifndef portSETUP_TCB
#define portSETUP_TCB( pxTCB ) ( void ) pxTCB #define portSETUP_TCB( pxTCB ) ( void ) ( pxTCB )
#endif #endif
#ifndef configQUEUE_REGISTRY_SIZE #ifndef configQUEUE_REGISTRY_SIZE
@@ -308,32 +405,40 @@ hold explicit before calling the code. */
#define pcQueueGetName( xQueue ) #define pcQueueGetName( xQueue )
#endif #endif
#ifndef configUSE_MINI_LIST_ITEM
#define configUSE_MINI_LIST_ITEM 1
#endif
#ifndef portPOINTER_SIZE_TYPE #ifndef portPOINTER_SIZE_TYPE
#define portPOINTER_SIZE_TYPE uint32_t #define portPOINTER_SIZE_TYPE uint32_t
#endif #endif
/* Remove any unused trace macros. */ /* Remove any unused trace macros. */
#ifndef traceSTART #ifndef traceSTART
/* Used to perform any necessary initialisation - for example, open a file /* Used to perform any necessary initialisation - for example, open a file
into which trace is to be written. */ * into which trace is to be written. */
#define traceSTART() #define traceSTART()
#endif #endif
#ifndef traceEND #ifndef traceEND
/* Use to close a trace, for example close a file into which trace has been /* Use to close a trace, for example close a file into which trace has been
written. */ * written. */
#define traceEND() #define traceEND()
#endif #endif
#ifndef traceTASK_SWITCHED_IN #ifndef traceTASK_SWITCHED_IN
/* Called after a task has been selected to run. pxCurrentTCB holds a pointer /* Called after a task has been selected to run. pxCurrentTCB holds a pointer
to the task control block of the selected task. */ * to the task control block of the selected task. */
#define traceTASK_SWITCHED_IN() #define traceTASK_SWITCHED_IN()
#endif #endif
#ifndef traceINCREASE_TICK_COUNT #ifndef traceINCREASE_TICK_COUNT
/* Called before stepping the tick count after waking from tickless idle /* Called before stepping the tick count after waking from tickless idle
sleep. */ * sleep. */
#define traceINCREASE_TICK_COUNT( x ) #define traceINCREASE_TICK_COUNT( x )
#endif #endif
@@ -348,49 +453,55 @@ hold explicit before calling the code. */
#endif #endif
#ifndef traceTASK_SWITCHED_OUT #ifndef traceTASK_SWITCHED_OUT
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer /* Called before a task has been selected to run. pxCurrentTCB holds a pointer
to the task control block of the task being switched out. */ * to the task control block of the task being switched out. */
#define traceTASK_SWITCHED_OUT() #define traceTASK_SWITCHED_OUT()
#endif #endif
#ifndef traceTASK_PRIORITY_INHERIT #ifndef traceTASK_PRIORITY_INHERIT
/* Called when a task attempts to take a mutex that is already held by a /* Called when a task attempts to take a mutex that is already held by a
lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task * lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task
that holds the mutex. uxInheritedPriority is the priority the mutex holder * that holds the mutex. uxInheritedPriority is the priority the mutex holder
will inherit (the priority of the task that is attempting to obtain the * will inherit (the priority of the task that is attempting to obtain the
muted. */ * muted. */
#define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )
#endif #endif
#ifndef traceTASK_PRIORITY_DISINHERIT #ifndef traceTASK_PRIORITY_DISINHERIT
/* Called when a task releases a mutex, the holding of which had resulted in /* Called when a task releases a mutex, the holding of which had resulted in
the task inheriting the priority of a higher priority task. * the task inheriting the priority of a higher priority task.
pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the * pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the
mutex. uxOriginalPriority is the task's configured (base) priority. */ * mutex. uxOriginalPriority is the task's configured (base) priority. */
#define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )
#endif #endif
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE #ifndef traceBLOCKING_ON_QUEUE_RECEIVE
/* Task is about to block because it cannot read from a /* Task is about to block because it cannot read from a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the read was attempted. pxCurrentTCB points to the TCB of the * upon which the read was attempted. pxCurrentTCB points to the TCB of the
task that attempted the read. */ * task that attempted the read. */
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
#endif #endif
#ifndef traceBLOCKING_ON_QUEUE_PEEK #ifndef traceBLOCKING_ON_QUEUE_PEEK
/* Task is about to block because it cannot read from a /* Task is about to block because it cannot read from a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the read was attempted. pxCurrentTCB points to the TCB of the * upon which the read was attempted. pxCurrentTCB points to the TCB of the
task that attempted the read. */ * task that attempted the read. */
#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue )
#endif #endif
#ifndef traceBLOCKING_ON_QUEUE_SEND #ifndef traceBLOCKING_ON_QUEUE_SEND
/* Task is about to block because it cannot write to a /* Task is about to block because it cannot write to a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the write was attempted. pxCurrentTCB points to the TCB of the * upon which the write was attempted. pxCurrentTCB points to the TCB of the
task that attempted the write. */ * task that attempted the write. */
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) #define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
#endif #endif
@@ -456,6 +567,10 @@ hold explicit before calling the code. */
#define traceCREATE_COUNTING_SEMAPHORE_FAILED() #define traceCREATE_COUNTING_SEMAPHORE_FAILED()
#endif #endif
#ifndef traceQUEUE_SET_SEND
#define traceQUEUE_SET_SEND traceQUEUE_SEND
#endif
#ifndef traceQUEUE_SEND #ifndef traceQUEUE_SEND
#define traceQUEUE_SEND( pxQueue ) #define traceQUEUE_SEND( pxQueue )
#endif #endif
@@ -589,7 +704,7 @@ hold explicit before calling the code. */
#endif #endif
#ifndef traceEVENT_GROUP_SYNC_END #ifndef traceEVENT_GROUP_SYNC_END
#define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) ( xTimeoutOccurred )
#endif #endif
#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK #ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK
@@ -597,7 +712,7 @@ hold explicit before calling the code. */
#endif #endif
#ifndef traceEVENT_GROUP_WAIT_BITS_END #ifndef traceEVENT_GROUP_WAIT_BITS_END
#define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) ( xTimeoutOccurred )
#endif #endif
#ifndef traceEVENT_GROUP_CLEAR_BITS #ifndef traceEVENT_GROUP_CLEAR_BITS
@@ -633,31 +748,31 @@ hold explicit before calling the code. */
#endif #endif
#ifndef traceTASK_NOTIFY_TAKE_BLOCK #ifndef traceTASK_NOTIFY_TAKE_BLOCK
#define traceTASK_NOTIFY_TAKE_BLOCK() #define traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWait )
#endif #endif
#ifndef traceTASK_NOTIFY_TAKE #ifndef traceTASK_NOTIFY_TAKE
#define traceTASK_NOTIFY_TAKE() #define traceTASK_NOTIFY_TAKE( uxIndexToWait )
#endif #endif
#ifndef traceTASK_NOTIFY_WAIT_BLOCK #ifndef traceTASK_NOTIFY_WAIT_BLOCK
#define traceTASK_NOTIFY_WAIT_BLOCK() #define traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWait )
#endif #endif
#ifndef traceTASK_NOTIFY_WAIT #ifndef traceTASK_NOTIFY_WAIT
#define traceTASK_NOTIFY_WAIT() #define traceTASK_NOTIFY_WAIT( uxIndexToWait )
#endif #endif
#ifndef traceTASK_NOTIFY #ifndef traceTASK_NOTIFY
#define traceTASK_NOTIFY() #define traceTASK_NOTIFY( uxIndexToNotify )
#endif #endif
#ifndef traceTASK_NOTIFY_FROM_ISR #ifndef traceTASK_NOTIFY_FROM_ISR
#define traceTASK_NOTIFY_FROM_ISR() #define traceTASK_NOTIFY_FROM_ISR( uxIndexToNotify )
#endif #endif
#ifndef traceTASK_NOTIFY_GIVE_FROM_ISR #ifndef traceTASK_NOTIFY_GIVE_FROM_ISR
#define traceTASK_NOTIFY_GIVE_FROM_ISR() #define traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify )
#endif #endif
#ifndef traceSTREAM_BUFFER_CREATE_FAILED #ifndef traceSTREAM_BUFFER_CREATE_FAILED
@@ -834,10 +949,24 @@ hold explicit before calling the code. */
#define configUSE_TASK_NOTIFICATIONS 1 #define configUSE_TASK_NOTIFICATIONS 1
#endif #endif
#ifndef configTASK_NOTIFICATION_ARRAY_ENTRIES
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1
#endif
#if configTASK_NOTIFICATION_ARRAY_ENTRIES < 1
#error configTASK_NOTIFICATION_ARRAY_ENTRIES must be at least 1
#endif
#ifndef configUSE_POSIX_ERRNO #ifndef configUSE_POSIX_ERRNO
#define configUSE_POSIX_ERRNO 0 #define configUSE_POSIX_ERRNO 0
#endif #endif
#ifndef configUSE_SB_COMPLETED_CALLBACK
/* By default per-instance callbacks are not enabled for stream buffer or message buffer. */
#define configUSE_SB_COMPLETED_CALLBACK 0
#endif
#ifndef portTICK_TYPE_IS_ATOMIC #ifndef portTICK_TYPE_IS_ATOMIC
#define portTICK_TYPE_IS_ATOMIC 0 #define portTICK_TYPE_IS_ATOMIC 0
#endif #endif
@@ -852,26 +981,40 @@ hold explicit before calling the code. */
#define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1
#endif #endif
#if ( ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION != 1 ) )
#error configUSE_STATS_FORMATTING_FUNCTIONS cannot be used without dynamic allocation, but configSUPPORT_DYNAMIC_ALLOCATION is not set to 1.
#endif
#if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 )
#if ( ( configUSE_TRACE_FACILITY != 1 ) && ( configGENERATE_RUN_TIME_STATS != 1 ) )
#error configUSE_STATS_FORMATTING_FUNCTIONS is 1 but the functions it enables are not used because neither configUSE_TRACE_FACILITY or configGENERATE_RUN_TIME_STATS are 1. Set configUSE_STATS_FORMATTING_FUNCTIONS to 0 in FreeRTOSConfig.h.
#endif
#endif
#ifndef configSTACK_DEPTH_TYPE #ifndef configSTACK_DEPTH_TYPE
/* Defaults to uint16_t for backward compatibility, but can be overridden /* Defaults to uint16_t for backward compatibility, but can be overridden
in FreeRTOSConfig.h if uint16_t is too restrictive. */ * in FreeRTOSConfig.h if uint16_t is too restrictive. */
#define configSTACK_DEPTH_TYPE uint16_t #define configSTACK_DEPTH_TYPE uint16_t
#endif #endif
#ifndef configRUN_TIME_COUNTER_TYPE
/* Defaults to uint32_t for backward compatibility, but can be overridden in
* FreeRTOSConfig.h if uint32_t is too restrictive. */
#define configRUN_TIME_COUNTER_TYPE uint32_t
#endif
#ifndef configMESSAGE_BUFFER_LENGTH_TYPE #ifndef configMESSAGE_BUFFER_LENGTH_TYPE
/* Defaults to size_t for backward compatibility, but can be overridden /* Defaults to size_t for backward compatibility, but can be overridden
in FreeRTOSConfig.h if lengths will always be less than the number of bytes * in FreeRTOSConfig.h if lengths will always be less than the number of bytes
in a size_t. */ * in a size_t. */
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t #define configMESSAGE_BUFFER_LENGTH_TYPE size_t
#endif #endif
/* Sanity check the configuration. */ /* Sanity check the configuration. */
#if( configUSE_TICKLESS_IDLE != 0 )
#if( INCLUDE_vTaskSuspend != 1 )
#error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0
#endif /* INCLUDE_vTaskSuspend */
#endif /* configUSE_TICKLESS_IDLE */
#if ( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) #if ( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) )
#error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1.
#endif #endif
@@ -885,51 +1028,56 @@ hold explicit before calling the code. */
#endif #endif
#if ( portTICK_TYPE_IS_ATOMIC == 0 ) #if ( portTICK_TYPE_IS_ATOMIC == 0 )
/* Either variables of tick type cannot be read atomically, or /* Either variables of tick type cannot be read atomically, or
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when * portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
the tick count is returned to the standard critical section macros. */ * the tick count is returned to the standard critical section macros. */
#define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL()
#define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL()
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) )
#else #else
/* The tick type can be read atomically, so critical sections used when the /* The tick type can be read atomically, so critical sections used when the
tick count is returned can be defined away. */ * tick count is returned can be defined away. */
#define portTICK_TYPE_ENTER_CRITICAL() #define portTICK_TYPE_ENTER_CRITICAL()
#define portTICK_TYPE_EXIT_CRITICAL() #define portTICK_TYPE_EXIT_CRITICAL()
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0
#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) ( x )
#endif #endif /* if ( portTICK_TYPE_IS_ATOMIC == 0 ) */
/* Definitions to allow backward compatibility with FreeRTOS versions prior to /* Definitions to allow backward compatibility with FreeRTOS versions prior to
V8 if desired. */ * V8 if desired. */
#ifndef configENABLE_BACKWARD_COMPATIBILITY #ifndef configENABLE_BACKWARD_COMPATIBILITY
#define configENABLE_BACKWARD_COMPATIBILITY 1 #define configENABLE_BACKWARD_COMPATIBILITY 1
#endif #endif
#ifndef configPRINTF #ifndef configPRINTF
/* configPRINTF() was not defined, so define it away to nothing. To use /* configPRINTF() was not defined, so define it away to nothing. To use
configPRINTF() then define it as follows (where MyPrintFunction() is * configPRINTF() then define it as follows (where MyPrintFunction() is
provided by the application writer): * provided by the application writer):
*
void MyPrintFunction(const char *pcFormat, ... ); * void MyPrintFunction(const char *pcFormat, ... );
#define configPRINTF( X ) MyPrintFunction X #define configPRINTF( X ) MyPrintFunction X
*
Then call like a standard printf() function, but placing brackets around * Then call like a standard printf() function, but placing brackets around
all parameters so they are passed as a single parameter. For example: * all parameters so they are passed as a single parameter. For example:
configPRINTF( ("Value = %d", MyVariable) ); */ * configPRINTF( ("Value = %d", MyVariable) ); */
#define configPRINTF( X ) #define configPRINTF( X )
#endif #endif
#ifndef configMAX #ifndef configMAX
/* The application writer has not provided their own MAX macro, so define /* The application writer has not provided their own MAX macro, so define
the following generic implementation. */ * the following generic implementation. */
#define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
#endif #endif
#ifndef configMIN #ifndef configMIN
/* The application writer has not provided their own MAX macro, so define
the following generic implementation. */ /* The application writer has not provided their own MIN macro, so define
* the following generic implementation. */
#define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#endif #endif
@@ -956,14 +1104,14 @@ V8 if desired. */
#define xTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter #define xTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter
/* Backward compatibility within the scheduler code only - these definitions /* Backward compatibility within the scheduler code only - these definitions
are not really required but are included for completeness. */ * are not really required but are included for completeness. */
#define tmrTIMER_CALLBACK TimerCallbackFunction_t #define tmrTIMER_CALLBACK TimerCallbackFunction_t
#define pdTASK_CODE TaskFunction_t #define pdTASK_CODE TaskFunction_t
#define xListItem ListItem_t #define xListItem ListItem_t
#define xList List_t #define xList List_t
/* For libraries that break the list data hiding, and access list structure /* For libraries that break the list data hiding, and access list structure
members directly (which is not supposed to be done). */ * members directly (which is not supposed to be done). */
#define pxContainer pvContainer #define pxContainer pvContainer
#endif /* configENABLE_BACKWARD_COMPATIBILITY */ #endif /* configENABLE_BACKWARD_COMPATIBILITY */
@@ -972,37 +1120,48 @@ V8 if desired. */
#endif #endif
/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even /* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even
if floating point hardware is otherwise supported by the FreeRTOS port in use. * if floating point hardware is otherwise supported by the FreeRTOS port in use.
This constant is not supported by all FreeRTOS ports that include floating * This constant is not supported by all FreeRTOS ports that include floating
point support. */ * point support. */
#ifndef configUSE_TASK_FPU_SUPPORT #ifndef configUSE_TASK_FPU_SUPPORT
#define configUSE_TASK_FPU_SUPPORT 1 #define configUSE_TASK_FPU_SUPPORT 1
#endif #endif
/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is /* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is
currently used in ARMv8M ports. */ * currently used in ARMv8M ports. */
#ifndef configENABLE_MPU #ifndef configENABLE_MPU
#define configENABLE_MPU 0 #define configENABLE_MPU 0
#endif #endif
/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is /* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is
currently used in ARMv8M ports. */ * currently used in ARMv8M ports. */
#ifndef configENABLE_FPU #ifndef configENABLE_FPU
#define configENABLE_FPU 1 #define configENABLE_FPU 1
#endif #endif
/* Set configENABLE_MVE to 1 to enable MVE support and 0 to disable it. This is
* currently used in ARMv8M ports. */
#ifndef configENABLE_MVE
#define configENABLE_MVE 0
#endif
/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it. /* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it.
This is currently used in ARMv8M ports. */ * This is currently used in ARMv8M ports. */
#ifndef configENABLE_TRUSTZONE #ifndef configENABLE_TRUSTZONE
#define configENABLE_TRUSTZONE 1 #define configENABLE_TRUSTZONE 1
#endif #endif
/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on /* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on
the Secure Side only. */ * the Secure Side only. */
#ifndef configRUN_FREERTOS_SECURE_ONLY #ifndef configRUN_FREERTOS_SECURE_ONLY
#define configRUN_FREERTOS_SECURE_ONLY 0 #define configRUN_FREERTOS_SECURE_ONLY 0
#endif #endif
#ifndef configRUN_ADDITIONAL_TESTS
#define configRUN_ADDITIONAL_TESTS 0
#endif
/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using /* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
* dynamically allocated RAM, in which case when any task is deleted it is known * dynamically allocated RAM, in which case when any task is deleted it is known
* that both the task's stack and TCB need to be freed. Sometimes the * that both the task's stack and TCB need to be freed. Sometimes the
@@ -1045,7 +1204,8 @@ the Secure Side only. */
* | | | | xTaskCreateRestrictedStatic | | | | * | | | | xTaskCreateRestrictedStatic | | | |
* +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+
*/ */
#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \ #define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE \
( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \
( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) ) ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) )
/* /*
@@ -1053,7 +1213,7 @@ the Secure Side only. */
* data hiding policy, so the real structures used by FreeRTOS to maintain the * data hiding policy, so the real structures used by FreeRTOS to maintain the
* state of tasks, queues, semaphores, etc. are not accessible to the application * state of tasks, queues, semaphores, etc. are not accessible to the application
* code. However, if the application writer wants to statically allocate such * code. However, if the application writer wants to statically allocate such
* an object then the size of the object needs to be know. Dummy structures * an object then the size of the object needs to be known. Dummy structures
* that are guaranteed to have the same size and alignment requirements of the * that are guaranteed to have the same size and alignment requirements of the
* real objects are used for this purpose. The dummy list and list item * real objects are used for this purpose. The dummy list and list item
* structures below are used for inclusion in such a dummy structure. * structures below are used for inclusion in such a dummy structure.
@@ -1071,6 +1231,7 @@ struct xSTATIC_LIST_ITEM
}; };
typedef struct xSTATIC_LIST_ITEM StaticListItem_t; typedef struct xSTATIC_LIST_ITEM StaticListItem_t;
#if ( configUSE_MINI_LIST_ITEM == 1 )
/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ /* See the comments above the struct xSTATIC_LIST_ITEM definition. */
struct xSTATIC_MINI_LIST_ITEM struct xSTATIC_MINI_LIST_ITEM
{ {
@@ -1081,6 +1242,9 @@ struct xSTATIC_MINI_LIST_ITEM
void * pvDummy3[ 2 ]; void * pvDummy3[ 2 ];
}; };
typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t;
#else /* if ( configUSE_MINI_LIST_ITEM == 1 ) */
typedef struct xSTATIC_LIST_ITEM StaticMiniListItem_t;
#endif /* if ( configUSE_MINI_LIST_ITEM == 1 ) */
/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ /* See the comments above the struct xSTATIC_LIST_ITEM definition. */
typedef struct xSTATIC_LIST typedef struct xSTATIC_LIST
@@ -1102,7 +1266,7 @@ typedef struct xSTATIC_LIST
* strict data hiding policy. This means the Task structure used internally by * strict data hiding policy. This means the Task structure used internally by
* FreeRTOS is not accessible to application code. However, if the application * FreeRTOS is not accessible to application code. However, if the application
* writer wants to statically allocate the memory required to create a task then * writer wants to statically allocate the memory required to create a task then
* the size of the task object needs to be know. The StaticTask_t structure * the size of the task object needs to be known. The StaticTask_t structure
* below is provided for this purpose. Its sizes and alignment requirements are * below is provided for this purpose. Its sizes and alignment requirements are
* guaranteed to match those of the genuine structure, no matter which * guaranteed to match those of the genuine structure, no matter which
* architecture is being used, and no matter how the values in FreeRTOSConfig.h * architecture is being used, and no matter how the values in FreeRTOSConfig.h
@@ -1138,14 +1302,14 @@ typedef struct xSTATIC_TCB
void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif #endif
#if ( configGENERATE_RUN_TIME_STATS == 1 ) #if ( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulDummy16; configRUN_TIME_COUNTER_TYPE ulDummy16;
#endif #endif
#if ( configUSE_NEWLIB_REENTRANT == 1 ) #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
struct _reent xDummy17; configTLS_BLOCK_TYPE xDummy17;
#endif #endif
#if ( configUSE_TASK_NOTIFICATIONS == 1 ) #if ( configUSE_TASK_NOTIFICATIONS == 1 )
uint32_t ulDummy18; uint32_t ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
uint8_t ucDummy19; uint8_t ucDummy19[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
#endif #endif
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
uint8_t uxDummy20; uint8_t uxDummy20;
@@ -1165,7 +1329,7 @@ typedef struct xSTATIC_TCB
* strict data hiding policy. This means the Queue structure used internally by * strict data hiding policy. This means the Queue structure used internally by
* FreeRTOS is not accessible to application code. However, if the application * FreeRTOS is not accessible to application code. However, if the application
* writer wants to statically allocate the memory required to create a queue * writer wants to statically allocate the memory required to create a queue
* then the size of the queue object needs to be know. The StaticQueue_t * then the size of the queue object needs to be known. The StaticQueue_t
* structure below is provided for this purpose. Its sizes and alignment * structure below is provided for this purpose. Its sizes and alignment
* requirements are guaranteed to match those of the genuine structure, no * requirements are guaranteed to match those of the genuine structure, no
* matter which architecture is being used, and no matter how the values in * matter which architecture is being used, and no matter how the values in
@@ -1199,7 +1363,6 @@ typedef struct xSTATIC_QUEUE
UBaseType_t uxDummy8; UBaseType_t uxDummy8;
uint8_t ucDummy9; uint8_t ucDummy9;
#endif #endif
} StaticQueue_t; } StaticQueue_t;
typedef StaticQueue_t StaticSemaphore_t; typedef StaticQueue_t StaticSemaphore_t;
@@ -1229,7 +1392,6 @@ typedef struct xSTATIC_EVENT_GROUP
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
uint8_t ucDummy4; uint8_t ucDummy4;
#endif #endif
} StaticEventGroup_t; } StaticEventGroup_t;
/* /*
@@ -1238,7 +1400,7 @@ typedef struct xSTATIC_EVENT_GROUP
* strict data hiding policy. This means the software timer structure used * strict data hiding policy. This means the software timer structure used
* internally by FreeRTOS is not accessible to application code. However, if * internally by FreeRTOS is not accessible to application code. However, if
* the application writer wants to statically allocate the memory required to * the application writer wants to statically allocate the memory required to
* create a software timer then the size of the queue object needs to be know. * create a software timer then the size of the queue object needs to be known.
* The StaticTimer_t structure below is provided for this purpose. Its sizes * The StaticTimer_t structure below is provided for this purpose. Its sizes
* and alignment requirements are guaranteed to match those of the genuine * and alignment requirements are guaranteed to match those of the genuine
* structure, no matter which architecture is being used, and no matter how the * structure, no matter which architecture is being used, and no matter how the
@@ -1257,7 +1419,6 @@ typedef struct xSTATIC_TIMER
UBaseType_t uxDummy7; UBaseType_t uxDummy7;
#endif #endif
uint8_t ucDummy8; uint8_t ucDummy8;
} StaticTimer_t; } StaticTimer_t;
/* /*
@@ -1267,12 +1428,12 @@ typedef struct xSTATIC_TIMER
* internally by FreeRTOS is not accessible to application code. However, if * internally by FreeRTOS is not accessible to application code. However, if
* the application writer wants to statically allocate the memory required to * the application writer wants to statically allocate the memory required to
* create a stream buffer then the size of the stream buffer object needs to be * create a stream buffer then the size of the stream buffer object needs to be
* know. The StaticStreamBuffer_t structure below is provided for this purpose. * known. The StaticStreamBuffer_t structure below is provided for this
* Its size and alignment requirements are guaranteed to match those of the * purpose. Its size and alignment requirements are guaranteed to match those
* genuine structure, no matter which architecture is being used, and no matter * of the genuine structure, no matter which architecture is being used, and
* how the values in FreeRTOSConfig.h are set. Its contents are somewhat * no matter how the values in FreeRTOSConfig.h are set. Its contents are
* obfuscated in the hope users will recognise that it would be unwise to make * somewhat obfuscated in the hope users will recognise that it would be unwise
* direct use of the structure members. * to make direct use of the structure members.
*/ */
typedef struct xSTATIC_STREAM_BUFFER typedef struct xSTATIC_STREAM_BUFFER
{ {
@@ -1282,14 +1443,18 @@ typedef struct xSTATIC_STREAM_BUFFER
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxDummy4; UBaseType_t uxDummy4;
#endif #endif
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
void * pvDummy5[ 2 ];
#endif
} StaticStreamBuffer_t; } StaticStreamBuffer_t;
/* Message buffers are built on stream buffers. */ /* Message buffers are built on stream buffers. */
typedef StaticStreamBuffer_t StaticMessageBuffer_t; typedef StaticStreamBuffer_t StaticMessageBuffer_t;
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */
#endif /* INC_FREERTOS_H */ #endif /* INC_FREERTOS_H */
@@ -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 */
+10 -5
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!
*/ */
/** /**
@@ -44,9 +45,11 @@
/* 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.
@@ -407,8 +410,10 @@ uint32_t ulCurrent;
return ulCurrent; return ulCurrent;
} }
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */
#endif /* ATOMIC_H */ #endif /* ATOMIC_H */
+394 -359
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 CO_ROUTINE_H #ifndef CO_ROUTINE_H
@@ -34,36 +35,40 @@
#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,61 +182,67 @@ 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
*/ */
@@ -238,13 +252,18 @@ void vCoRoutineSchedule( void );
* 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 ) \
do { \
if( ( xTicksToDelay ) > 0 ) \ 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,43 +365,44 @@ 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 ) \
{ \ { \
@@ -390,18 +414,19 @@ void vCoRoutineSchedule( void );
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,37 +465,38 @@ 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 ) \
{ \ { \
@@ -482,16 +508,17 @@ void vCoRoutineSchedule( void );
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.
@@ -713,8 +746,10 @@ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
*/ */
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,13 +31,13 @@
/* 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"
@@ -209,16 +210,18 @@ projects should not use them. */
#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 /* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */ * FreeRTOSConfig.h when using the Borland compiler. */
#include "frconfig.h" #include "frconfig.h"
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h" #include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
typedef void ( __interrupt __far * pxISR )(); 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 /* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */ * FreeRTOSConfig.h when using the Borland compiler. */
#include "frconfig.h" #include "frconfig.h"
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
typedef void ( __interrupt __far * pxISR )(); typedef void ( __interrupt __far * pxISR )();
@@ -276,4 +279,3 @@ projects should not use them. */
#endif #endif
#endif /* DEPRECATED_DEFINITIONS_H */ #endif /* DEPRECATED_DEFINITIONS_H */
+421 -351
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 EVENT_GROUPS_H #ifndef EVENT_GROUPS_H
@@ -35,9 +36,31 @@
/* FreeRTOS includes. */ /* FreeRTOS includes. */
#include "timers.h" #include "timers.h"
/* The following bit fields convey control information in a task's event list
* item value. It is important they don't clash with the
* taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
#define eventWAIT_FOR_ALL_BITS 0x0400U
#define eventEVENT_BITS_CONTROL_BYTES 0xff00U
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
#define eventWAIT_FOR_ALL_BITS 0x04000000UL
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100000000000000ULL
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200000000000000ULL
#define eventWAIT_FOR_ALL_BITS 0x0400000000000000ULL
#define eventEVENT_BITS_CONTROL_BYTES 0xff00000000000000ULL
#endif /* if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) */
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
/** /**
* An event group is a collection of bits to which an application can assign a * An event group is a collection of bits to which an application can assign a
@@ -62,8 +85,6 @@ extern "C" {
* be set and then tested atomically - as is the case where event groups are * be set and then tested atomically - as is the case where event groups are
* used to create a synchronisation point between multiple tasks (a * used to create a synchronisation point between multiple tasks (a
* 'rendezvous'). * 'rendezvous').
*
* \defgroup EventGroup
*/ */
@@ -83,8 +104,8 @@ typedef struct EventGroupDef_t * EventGroupHandle_t;
/* /*
* The type that holds event bits always matches TickType_t - therefore the * The type that holds event bits always matches TickType_t - therefore the
* number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, * number of bits it holds is set by configTICK_TYPE_WIDTH_IN_BITS (16 bits if set to 0,
* 32 bits if set to 0. * 32 bits if set to 1, 64 bits if set to 2.
* *
* \defgroup EventBits_t EventBits_t * \defgroup EventBits_t EventBits_t
* \ingroup EventGroup * \ingroup EventGroup
@@ -93,53 +114,54 @@ typedef TickType_t EventBits_t;
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
EventGroupHandle_t xEventGroupCreate( void ); * EventGroupHandle_t xEventGroupCreate( void );
</pre> * @endcode
* *
* Create a new event group. * Create a new event group.
* *
* Internally, within the FreeRTOS implementation, event groups use a [small] * Internally, within the FreeRTOS implementation, event groups use a [small]
* block of memory, in which the event group's structure is stored. If an event * block of memory, in which the event group's structure is stored. If an event
* groups is created using xEventGropuCreate() then the required memory is * groups is created using xEventGroupCreate() then the required memory is
* automatically dynamically allocated inside the xEventGroupCreate() function. * automatically dynamically allocated inside the xEventGroupCreate() function.
* (see http://www.freertos.org/a00111.html). If an event group is created * (see https://www.FreeRTOS.org/a00111.html). If an event group is created
* using xEventGropuCreateStatic() then the application writer must instead * using xEventGroupCreateStatic() then the application writer must instead
* provide the memory that will get used by the event group. * provide the memory that will get used by the event group.
* xEventGroupCreateStatic() therefore allows an event group to be created * xEventGroupCreateStatic() therefore allows an event group to be created
* without using any dynamic memory allocation. * without using any dynamic memory allocation.
* *
* Although event groups are not related to ticks, for internal implementation * Although event groups are not related to ticks, for internal implementation
* reasons the number of bits available for use in an event group is dependent * reasons the number of bits available for use in an event group is dependent
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If * on the configTICK_TYPE_WIDTH_IN_BITS setting in FreeRTOSConfig.h. If
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit * configTICK_TYPE_WIDTH_IN_BITS is 0 then each event group contains 8 usable bits (bit
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has * 0 to bit 7). If configTICK_TYPE_WIDTH_IN_BITS is set to 1 then each event group has
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store * 24 usable bits (bit 0 to bit 23). If configTICK_TYPE_WIDTH_IN_BITS is set to 2 then
* event bits within an event group. * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type
* is used to store event bits within an event group.
* *
* @return If the event group was created then a handle to the event group is * @return If the event group was created then a handle to the event group is
* returned. If there was insufficient FreeRTOS heap available to create the * returned. If there was insufficient FreeRTOS heap available to create the
* event group then NULL is returned. See http://www.freertos.org/a00111.html * event group then NULL is returned. See https://www.FreeRTOS.org/a00111.html
* *
* Example usage: * Example usage:
<pre> * @code{c}
// Declare a variable to hold the created event group. * // Declare a variable to hold the created event group.
EventGroupHandle_t xCreatedEventGroup; * EventGroupHandle_t xCreatedEventGroup;
*
// Attempt to create the event group. * // Attempt to create the event group.
xCreatedEventGroup = xEventGroupCreate(); * xCreatedEventGroup = xEventGroupCreate();
*
// Was the event group created successfully? * // Was the event group created successfully?
if( xCreatedEventGroup == NULL ) * if( xCreatedEventGroup == NULL )
{ * {
// The event group was not created because there was insufficient * // The event group was not created because there was insufficient
// FreeRTOS heap available. * // FreeRTOS heap available.
} * }
else * else
{ * {
// The event group was created. * // The event group was created.
} * }
</pre> * @endcode
* \defgroup xEventGroupCreate xEventGroupCreate * \defgroup xEventGroupCreate xEventGroupCreate
* \ingroup EventGroup * \ingroup EventGroup
*/ */
@@ -149,29 +171,30 @@ typedef TickType_t EventBits_t;
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
</pre> * @endcode
* *
* Create a new event group. * Create a new event group.
* *
* Internally, within the FreeRTOS implementation, event groups use a [small] * Internally, within the FreeRTOS implementation, event groups use a [small]
* block of memory, in which the event group's structure is stored. If an event * block of memory, in which the event group's structure is stored. If an event
* groups is created using xEventGropuCreate() then the required memory is * groups is created using xEventGroupCreate() then the required memory is
* automatically dynamically allocated inside the xEventGroupCreate() function. * automatically dynamically allocated inside the xEventGroupCreate() function.
* (see http://www.freertos.org/a00111.html). If an event group is created * (see https://www.FreeRTOS.org/a00111.html). If an event group is created
* using xEventGropuCreateStatic() then the application writer must instead * using xEventGroupCreateStatic() then the application writer must instead
* provide the memory that will get used by the event group. * provide the memory that will get used by the event group.
* xEventGroupCreateStatic() therefore allows an event group to be created * xEventGroupCreateStatic() therefore allows an event group to be created
* without using any dynamic memory allocation. * without using any dynamic memory allocation.
* *
* Although event groups are not related to ticks, for internal implementation * Although event groups are not related to ticks, for internal implementation
* reasons the number of bits available for use in an event group is dependent * reasons the number of bits available for use in an event group is dependent
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If * on the configTICK_TYPE_WIDTH_IN_BITS setting in FreeRTOSConfig.h. If
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit * configTICK_TYPE_WIDTH_IN_BITS is 0 then each event group contains 8 usable bits (bit
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has * 0 to bit 7). If configTICK_TYPE_WIDTH_IN_BITS is set to 1 then each event group has
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store * 24 usable bits (bit 0 to bit 23). If configTICK_TYPE_WIDTH_IN_BITS is set to 2 then
* event bits within an event group. * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type
* is used to store event bits within an event group.
* *
* @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
* StaticEventGroup_t, which will be then be used to hold the event group's data * StaticEventGroup_t, which will be then be used to hold the event group's data
@@ -181,20 +204,20 @@ typedef TickType_t EventBits_t;
* returned. If pxEventGroupBuffer was NULL then NULL is returned. * returned. If pxEventGroupBuffer was NULL then NULL is returned.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// StaticEventGroup_t is a publicly accessible structure that has the same * // StaticEventGroup_t is a publicly accessible structure that has the same
// size and alignment requirements as the real event group structure. It is * // size and alignment requirements as the real event group structure. It is
// provided as a mechanism for applications to know the size of the event * // provided as a mechanism for applications to know the size of the event
// group (which is dependent on the architecture and configuration file * // group (which is dependent on the architecture and configuration file
// settings) without breaking the strict data hiding policy by exposing the * // settings) without breaking the strict data hiding policy by exposing the
// real event group internals. This StaticEventGroup_t variable is passed * // real event group internals. This StaticEventGroup_t variable is passed
// into the xSemaphoreCreateEventGroupStatic() function and is used to store * // into the xSemaphoreCreateEventGroupStatic() function and is used to store
// the event group's data structures * // the event group's data structures
StaticEventGroup_t xEventGroupBuffer; * StaticEventGroup_t xEventGroupBuffer;
*
// Create the event group without dynamically allocating any memory. * // Create the event group without dynamically allocating any memory.
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); * xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
</pre> * @endcode
*/ */
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION; EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
@@ -202,13 +225,13 @@ typedef TickType_t EventBits_t;
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, * EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor, * const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit, * const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits, * const BaseType_t xWaitForAllBits,
const TickType_t xTicksToWait ); * const TickType_t xTicksToWait );
</pre> * @endcode
* *
* [Potentially] block to wait for one or more bits to be set within a * [Potentially] block to wait for one or more bits to be set within a
* previously created event group. * previously created event group.
@@ -240,7 +263,8 @@ typedef TickType_t EventBits_t;
* *
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
* for one/all (depending on the xWaitForAllBits value) of the bits specified by * for one/all (depending on the xWaitForAllBits value) of the bits specified by
* uxBitsToWaitFor to become set. * uxBitsToWaitFor to become set. A value of portMAX_DELAY can be used to block
* indefinitely (provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
* *
* @return The value of the event group at the time either the bits being waited * @return The value of the event group at the time either the bits being waited
* for became set, or the block time expired. Test the return value to know * for became set, or the block time expired. Test the return value to know
@@ -252,53 +276,57 @@ typedef TickType_t EventBits_t;
* pdTRUE. * pdTRUE.
* *
* Example usage: * Example usage:
<pre> * @code{c}
#define BIT_0 ( 1 << 0 ) * #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) * #define BIT_4 ( 1 << 4 )
*
void aFunction( EventGroupHandle_t xEventGroup ) * void aFunction( EventGroupHandle_t xEventGroup )
{ * {
EventBits_t uxBits; * EventBits_t uxBits;
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; * const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
*
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within * // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
// the event group. Clear the bits before exiting. * // the event group. Clear the bits before exiting.
uxBits = xEventGroupWaitBits( * uxBits = xEventGroupWaitBits(
xEventGroup, // The event group being tested. * xEventGroup, // The event group being tested.
BIT_0 | BIT_4, // The bits within the event group to wait for. * BIT_0 | BIT_4, // The bits within the event group to wait for.
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning. * pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
pdFALSE, // Don't wait for both bits, either bit will do. * pdFALSE, // Don't wait for both bits, either bit will do.
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set. * xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
*
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{ * {
// xEventGroupWaitBits() returned because both bits were set. * // xEventGroupWaitBits() returned because both bits were set.
} * }
else if( ( uxBits & BIT_0 ) != 0 ) * else if( ( uxBits & BIT_0 ) != 0 )
{ * {
// xEventGroupWaitBits() returned because just BIT_0 was set. * // xEventGroupWaitBits() returned because just BIT_0 was set.
} * }
else if( ( uxBits & BIT_4 ) != 0 ) * else if( ( uxBits & BIT_4 ) != 0 )
{ * {
// xEventGroupWaitBits() returned because just BIT_4 was set. * // xEventGroupWaitBits() returned because just BIT_4 was set.
} * }
else * else
{ * {
// xEventGroupWaitBits() returned because xTicksToWait ticks passed * // xEventGroupWaitBits() returned because xTicksToWait ticks passed
// without either BIT_0 or BIT_4 becoming set. * // without either BIT_0 or BIT_4 becoming set.
} * }
} * }
</pre> * @endcode
* \defgroup xEventGroupWaitBits xEventGroupWaitBits * \defgroup xEventGroupWaitBits xEventGroupWaitBits
* \ingroup EventGroup * \ingroup EventGroup
*/ */
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); * EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
</pre> * @endcode
* *
* Clear bits within an event group. This function cannot be called from an * Clear bits within an event group. This function cannot be called from an
* interrupt. * interrupt.
@@ -312,50 +340,51 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits
* @return The value of the event group before the specified bits were cleared. * @return The value of the event group before the specified bits were cleared.
* *
* Example usage: * Example usage:
<pre> * @code{c}
#define BIT_0 ( 1 << 0 ) * #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) * #define BIT_4 ( 1 << 4 )
*
void aFunction( EventGroupHandle_t xEventGroup ) * void aFunction( EventGroupHandle_t xEventGroup )
{ * {
EventBits_t uxBits; * EventBits_t uxBits;
*
// Clear bit 0 and bit 4 in xEventGroup. * // Clear bit 0 and bit 4 in xEventGroup.
uxBits = xEventGroupClearBits( * uxBits = xEventGroupClearBits(
xEventGroup, // The event group being updated. * xEventGroup, // The event group being updated.
BIT_0 | BIT_4 );// The bits being cleared. * BIT_0 | BIT_4 );// The bits being cleared.
*
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{ * {
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was * // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
// called. Both will now be clear (not set). * // called. Both will now be clear (not set).
} * }
else if( ( uxBits & BIT_0 ) != 0 ) * else if( ( uxBits & BIT_0 ) != 0 )
{ * {
// Bit 0 was set before xEventGroupClearBits() was called. It will * // Bit 0 was set before xEventGroupClearBits() was called. It will
// now be clear. * // now be clear.
} * }
else if( ( uxBits & BIT_4 ) != 0 ) * else if( ( uxBits & BIT_4 ) != 0 )
{ * {
// Bit 4 was set before xEventGroupClearBits() was called. It will * // Bit 4 was set before xEventGroupClearBits() was called. It will
// now be clear. * // now be clear.
} * }
else * else
{ * {
// Neither bit 0 nor bit 4 were set in the first place. * // Neither bit 0 nor bit 4 were set in the first place.
} * }
} * }
</pre> * @endcode
* \defgroup xEventGroupClearBits xEventGroupClearBits * \defgroup xEventGroupClearBits xEventGroupClearBits
* \ingroup EventGroup * \ingroup EventGroup
*/ */
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); * BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
</pre> * @endcode
* *
* A version of xEventGroupClearBits() that can be called from an interrupt. * A version of xEventGroupClearBits() that can be called from an interrupt.
* *
@@ -369,6 +398,12 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
* timer task to have the clear operation performed in the context of the timer * timer task to have the clear operation performed in the context of the timer
* task. * task.
* *
* @note If this function returns pdPASS then the timer task is ready to run
* and a portYIELD_FROM_ISR(pdTRUE) should be executed to perform the needed
* clear on the event group. This behavior is different from
* xEventGroupSetBitsFromISR because the parameter xHigherPriorityTaskWoken is
* not present.
*
* @param xEventGroup The event group in which the bits are to be cleared. * @param xEventGroup The event group in which the bits are to be cleared.
* *
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
@@ -380,41 +415,44 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
* if the timer service queue was full. * if the timer service queue was full.
* *
* Example usage: * Example usage:
<pre> * @code{c}
#define BIT_0 ( 1 << 0 ) * #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) * #define BIT_4 ( 1 << 4 )
*
// An event group which it is assumed has already been created by a call to * // An event group which it is assumed has already been created by a call to
// xEventGroupCreate(). * // xEventGroupCreate().
EventGroupHandle_t xEventGroup; * EventGroupHandle_t xEventGroup;
*
void anInterruptHandler( void ) * void anInterruptHandler( void )
{ * {
// Clear bit 0 and bit 4 in xEventGroup. * // Clear bit 0 and bit 4 in xEventGroup.
xResult = xEventGroupClearBitsFromISR( * xResult = xEventGroupClearBitsFromISR(
xEventGroup, // The event group being updated. * xEventGroup, // The event group being updated.
BIT_0 | BIT_4 ); // The bits being set. * BIT_0 | BIT_4 ); // The bits being set.
*
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// The message was posted successfully. * // The message was posted successfully.
} * portYIELD_FROM_ISR(pdTRUE);
} * }
</pre> * }
* @endcode
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
* \ingroup EventGroup * \ingroup EventGroup
*/ */
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
#else #else
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) \
xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToClear ), NULL )
#endif #endif
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
</pre> * @endcode
* *
* Set bits within an event group. * Set bits within an event group.
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
@@ -440,55 +478,56 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
* event group value before the call to xEventGroupSetBits() returns. * event group value before the call to xEventGroupSetBits() returns.
* *
* Example usage: * Example usage:
<pre> * @code{c}
#define BIT_0 ( 1 << 0 ) * #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) * #define BIT_4 ( 1 << 4 )
*
void aFunction( EventGroupHandle_t xEventGroup ) * void aFunction( EventGroupHandle_t xEventGroup )
{ * {
EventBits_t uxBits; * EventBits_t uxBits;
*
// Set bit 0 and bit 4 in xEventGroup. * // Set bit 0 and bit 4 in xEventGroup.
uxBits = xEventGroupSetBits( * uxBits = xEventGroupSetBits(
xEventGroup, // The event group being updated. * xEventGroup, // The event group being updated.
BIT_0 | BIT_4 );// The bits being set. * BIT_0 | BIT_4 );// The bits being set.
*
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{ * {
// Both bit 0 and bit 4 remained set when the function returned. * // Both bit 0 and bit 4 remained set when the function returned.
} * }
else if( ( uxBits & BIT_0 ) != 0 ) * else if( ( uxBits & BIT_0 ) != 0 )
{ * {
// Bit 0 remained set when the function returned, but bit 4 was * // Bit 0 remained set when the function returned, but bit 4 was
// cleared. It might be that bit 4 was cleared automatically as a * // cleared. It might be that bit 4 was cleared automatically as a
// task that was waiting for bit 4 was removed from the Blocked * // task that was waiting for bit 4 was removed from the Blocked
// state. * // state.
} * }
else if( ( uxBits & BIT_4 ) != 0 ) * else if( ( uxBits & BIT_4 ) != 0 )
{ * {
// Bit 4 remained set when the function returned, but bit 0 was * // Bit 4 remained set when the function returned, but bit 0 was
// cleared. It might be that bit 0 was cleared automatically as a * // cleared. It might be that bit 0 was cleared automatically as a
// task that was waiting for bit 0 was removed from the Blocked * // task that was waiting for bit 0 was removed from the Blocked
// state. * // state.
} * }
else * else
{ * {
// Neither bit 0 nor bit 4 remained set. It might be that a task * // Neither bit 0 nor bit 4 remained set. It might be that a task
// was waiting for both of the bits to be set, and the bits were * // was waiting for both of the bits to be set, and the bits were
// cleared as the task left the Blocked state. * // cleared as the task left the Blocked state.
} * }
} * }
</pre> * @endcode
* \defgroup xEventGroupSetBits xEventGroupSetBits * \defgroup xEventGroupSetBits xEventGroupSetBits
* \ingroup EventGroup * \ingroup EventGroup
*/ */
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * @endcode
* *
* A version of xEventGroupSetBits() that can be called from an interrupt. * A version of xEventGroupSetBits() that can be called from an interrupt.
* *
@@ -521,55 +560,58 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
* if the timer service queue was full. * if the timer service queue was full.
* *
* Example usage: * Example usage:
<pre> * @code{c}
#define BIT_0 ( 1 << 0 ) * #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) * #define BIT_4 ( 1 << 4 )
*
// An event group which it is assumed has already been created by a call to * // An event group which it is assumed has already been created by a call to
// xEventGroupCreate(). * // xEventGroupCreate().
EventGroupHandle_t xEventGroup; * EventGroupHandle_t xEventGroup;
*
void anInterruptHandler( void ) * void anInterruptHandler( void )
{ * {
BaseType_t xHigherPriorityTaskWoken, xResult; * BaseType_t xHigherPriorityTaskWoken, xResult;
*
// xHigherPriorityTaskWoken must be initialised to pdFALSE. * // xHigherPriorityTaskWoken must be initialised to pdFALSE.
xHigherPriorityTaskWoken = pdFALSE; * xHigherPriorityTaskWoken = pdFALSE;
*
// Set bit 0 and bit 4 in xEventGroup. * // Set bit 0 and bit 4 in xEventGroup.
xResult = xEventGroupSetBitsFromISR( * xResult = xEventGroupSetBitsFromISR(
xEventGroup, // The event group being updated. * xEventGroup, // The event group being updated.
BIT_0 | BIT_4 // The bits being set. * BIT_0 | BIT_4 // The bits being set.
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
// Was the message posted successfully? * // Was the message posted successfully?
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// 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 * // switch should be requested. The macro used is port specific and
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - * // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
// refer to the documentation page for the port being used. * // refer to the documentation page for the port being used.
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
} * }
</pre> * @endcode
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
* \ingroup EventGroup * \ingroup EventGroup
*/ */
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
#else #else
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \
xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToSet ), ( pxHigherPriorityTaskWoken ) )
#endif #endif
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet, * const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor, * const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait ); * TickType_t xTicksToWait );
</pre> * @endcode
* *
* Atomically set bits within an event group, then wait for a combination of * Atomically set bits within an event group, then wait for a combination of
* bits to be set within the same event group. This functionality is typically * bits to be set within the same event group. This functionality is typically
@@ -608,92 +650,95 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
* automatically cleared. * automatically cleared.
* *
* Example usage: * Example usage:
<pre> * @code{c}
// Bits used by the three tasks. * // Bits used by the three tasks.
#define TASK_0_BIT ( 1 << 0 ) * #define TASK_0_BIT ( 1 << 0 )
#define TASK_1_BIT ( 1 << 1 ) * #define TASK_1_BIT ( 1 << 1 )
#define TASK_2_BIT ( 1 << 2 ) * #define TASK_2_BIT ( 1 << 2 )
*
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT ) * #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
*
// Use an event group to synchronise three tasks. It is assumed this event * // Use an event group to synchronise three tasks. It is assumed this event
// group has already been created elsewhere. * // group has already been created elsewhere.
EventGroupHandle_t xEventBits; * EventGroupHandle_t xEventBits;
*
void vTask0( void *pvParameters ) * void vTask0( void *pvParameters )
{ * {
EventBits_t uxReturn; * EventBits_t uxReturn;
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; * TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
*
for( ;; ) * for( ;; )
{ * {
// Perform task functionality here. * // Perform task functionality here.
*
// Set bit 0 in the event flag to note this task has reached the * // Set bit 0 in the event flag to note this task has reached the
// sync point. The other two tasks will set the other two bits defined * // sync point. The other two tasks will set the other two bits defined
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation * // by ALL_SYNC_BITS. All three tasks have reached the synchronisation
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms * // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
// for this to happen. * // for this to happen.
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait ); * uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
*
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS ) * if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
{ * {
// All three tasks reached the synchronisation point before the call * // All three tasks reached the synchronisation point before the call
// to xEventGroupSync() timed out. * // to xEventGroupSync() timed out.
} * }
} * }
} * }
*
void vTask1( void *pvParameters ) * void vTask1( void *pvParameters )
{ * {
for( ;; ) * for( ;; )
{ * {
// Perform task functionality here. * // Perform task functionality here.
*
// Set bit 1 in the event flag to note this task has reached the * // Set bit 1 in the event flag to note this task has reached the
// synchronisation point. The other two tasks will set the other two * // synchronisation point. The other two tasks will set the other two
// bits defined by ALL_SYNC_BITS. All three tasks have reached the * // bits defined by ALL_SYNC_BITS. All three tasks have reached the
// synchronisation point when all the ALL_SYNC_BITS are set. Wait * // synchronisation point when all the ALL_SYNC_BITS are set. Wait
// indefinitely for this to happen. * // indefinitely for this to happen.
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY ); * xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
*
// xEventGroupSync() was called with an indefinite block time, so * // xEventGroupSync() was called with an indefinite block time, so
// this task will only reach here if the syncrhonisation was made by all * // this task will only reach here if the synchronisation was made by all
// three tasks, so there is no need to test the return value. * // three tasks, so there is no need to test the return value.
} * }
} * }
*
void vTask2( void *pvParameters ) * void vTask2( void *pvParameters )
{ * {
for( ;; ) * for( ;; )
{ * {
// Perform task functionality here. * // Perform task functionality here.
*
// Set bit 2 in the event flag to note this task has reached the * // Set bit 2 in the event flag to note this task has reached the
// synchronisation point. The other two tasks will set the other two * // synchronisation point. The other two tasks will set the other two
// bits defined by ALL_SYNC_BITS. All three tasks have reached the * // bits defined by ALL_SYNC_BITS. All three tasks have reached the
// synchronisation point when all the ALL_SYNC_BITS are set. Wait * // synchronisation point when all the ALL_SYNC_BITS are set. Wait
// indefinitely for this to happen. * // indefinitely for this to happen.
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY ); * xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
*
// xEventGroupSync() was called with an indefinite block time, so * // xEventGroupSync() was called with an indefinite block time, so
// this task will only reach here if the syncrhonisation was made by all * // this task will only reach here if the synchronisation was made by all
// three tasks, so there is no need to test the return value. * // three tasks, so there is no need to test the return value.
} * }
} * }
*
</pre> * @endcode
* \defgroup xEventGroupSync xEventGroupSync * \defgroup xEventGroupSync xEventGroupSync
* \ingroup EventGroup * \ingroup EventGroup
*/ */
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); * EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
</pre> * @endcode
* *
* Returns the current value of the bits in an event group. This function * Returns the current value of the bits in an event group. This function
* cannot be used from an interrupt. * cannot be used from an interrupt.
@@ -705,13 +750,13 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
* \defgroup xEventGroupGetBits xEventGroupGetBits * \defgroup xEventGroupGetBits xEventGroupGetBits
* \ingroup EventGroup * \ingroup EventGroup
*/ */
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( ( xEventGroup ), 0 )
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); * EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
</pre> * @endcode
* *
* A version of xEventGroupGetBits() that can be called from an ISR. * A version of xEventGroupGetBits() that can be called from an ISR.
* *
@@ -726,9 +771,9 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG
/** /**
* event_groups.h * event_groups.h
*<pre> * @code{c}
void xEventGroupDelete( EventGroupHandle_t xEventGroup ); * void xEventGroupDelete( EventGroupHandle_t xEventGroup );
</pre> * @endcode
* *
* Delete an event group that was previously created by a call to * Delete an event group that was previously created by a call to
* xEventGroupCreate(). Tasks that are blocked on the event group will be * xEventGroupCreate(). Tasks that are blocked on the event group will be
@@ -738,20 +783,45 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG
*/ */
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
/**
* event_groups.h
* @code{c}
* BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
* StaticEventGroup_t ** ppxEventGroupBuffer );
* @endcode
*
* Retrieve a pointer to a statically created event groups's data structure
* buffer. It is the same buffer that is supplied at the time of creation.
*
* @param xEventGroup The event group for which to retrieve the buffer.
*
* @param ppxEventGroupBuffer Used to return a pointer to the event groups's
* data structure buffer.
*
* @return pdTRUE if the buffer was retrieved, pdFALSE otherwise.
*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION;
#endif /* configSUPPORT_STATIC_ALLOCATION */
/* For internal use only. */ /* For internal use only. */
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; void vEventGroupSetBitsCallback( void * pvEventGroup,
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
void vEventGroupClearBitsCallback( void * pvEventGroup,
const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION; UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION;
void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; void vEventGroupSetNumber( void * xEventGroup,
UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
#endif #endif
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */
#endif /* EVENT_GROUPS_H */ #endif /* EVENT_GROUPS_H */
+127 -36
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
@@ -92,15 +94,17 @@
#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
@@ -113,7 +117,7 @@ use of FreeRTOS.*/
#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;
@@ -127,7 +131,7 @@ use of FreeRTOS.*/
#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. */
#if ( configUSE_MINI_LIST_ITEM == 1 )
struct xMINI_LIST_ITEM 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. */ 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; configLIST_VOLATILE TickType_t xItemValue;
struct xLIST_ITEM * configLIST_VOLATILE pxNext; struct xLIST_ITEM * configLIST_VOLATILE pxNext;
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; 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;
/* /*
@@ -190,7 +198,7 @@ typedef struct xLIST
/* /*
* 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
@@ -275,18 +283,98 @@ typedef struct xLIST
* \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
@@ -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
/* *INDENT-ON* */
#endif #endif /* ifndef LIST_H */
+334 -250
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!
*/ */
@@ -69,26 +70,29 @@
/* 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;
/* 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_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. */
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;
EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
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_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
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;
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, 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;
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxEventGroupGetNumber( void* 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 */
+163 -55
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,22 +21,21 @@
* 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
/* /*
@@ -45,51 +46,76 @@ only for ports that are using the MPU. */
* 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 xTaskCreateStatic MPU_xTaskCreateStatic
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
#define vTaskDelete MPU_vTaskDelete
#define vTaskDelay MPU_vTaskDelay #define vTaskDelay MPU_vTaskDelay
#define vTaskDelayUntil MPU_vTaskDelayUntil #define xTaskDelayUntil MPU_xTaskDelayUntil
#define xTaskAbortDelay MPU_xTaskAbortDelay #define xTaskAbortDelay MPU_xTaskAbortDelay
#define uxTaskPriorityGet MPU_uxTaskPriorityGet #define uxTaskPriorityGet MPU_uxTaskPriorityGet
#define eTaskGetState MPU_eTaskGetState #define eTaskGetState MPU_eTaskGetState
#define vTaskGetInfo MPU_vTaskGetInfo #define vTaskGetInfo MPU_vTaskGetInfo
#define vTaskPrioritySet MPU_vTaskPrioritySet
#define vTaskSuspend MPU_vTaskSuspend #define vTaskSuspend MPU_vTaskSuspend
#define vTaskResume MPU_vTaskResume #define vTaskResume MPU_vTaskResume
#define vTaskSuspendAll MPU_vTaskSuspendAll
#define xTaskResumeAll MPU_xTaskResumeAll
#define xTaskGetTickCount MPU_xTaskGetTickCount #define xTaskGetTickCount MPU_xTaskGetTickCount
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
#define pcTaskGetName MPU_pcTaskGetName #define pcTaskGetName MPU_pcTaskGetName
#define xTaskGetHandle MPU_xTaskGetHandle
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
#define uxTaskGetSystemState MPU_uxTaskGetSystemState #define uxTaskGetSystemState MPU_uxTaskGetSystemState
#define vTaskList MPU_vTaskList
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
#define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter #define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter
#define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent
#define xTaskGenericNotify MPU_xTaskGenericNotify #define xTaskGenericNotify MPU_xTaskGenericNotify
#define xTaskNotifyWait MPU_xTaskNotifyWait #define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait
#define ulTaskNotifyTake MPU_ulTaskNotifyTake #define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake
#define xTaskNotifyStateClear MPU_xTaskNotifyStateClear #define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear
#define ulTaskNotifyValueClear MPU_ulTaskNotifyValueClear #define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear
#define xTaskCatchUpTicks MPU_xTaskCatchUpTicks
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define ulTaskGetRunTimeCounter MPU_ulTaskGetRunTimeCounter
#define ulTaskGetRunTimePercent MPU_ulTaskGetRunTimePercent
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/* 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 )
/* These are not needed in v2 because they do not take a task
* handle and therefore, no lookup is needed. Needed in v1 because
* these are available as system calls in v1. */
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
#define vTaskList MPU_vTaskList
#define vTaskSuspendAll MPU_vTaskSuspendAll
#define xTaskCatchUpTicks MPU_xTaskCatchUpTicks
#define xTaskResumeAll MPU_xTaskResumeAll
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
#define xTaskCreate MPU_xTaskCreate
#define xTaskCreateStatic MPU_xTaskCreateStatic
#define vTaskDelete MPU_vTaskDelete
#define vTaskPrioritySet MPU_vTaskPrioritySet
#define xTaskGetHandle MPU_xTaskGetHandle
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
#define xTaskCreateRestrictedStatic MPU_xTaskCreateRestrictedStatic
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
#define xTaskGetStaticBuffers MPU_xTaskGetStaticBuffers
#define uxTaskPriorityGetFromISR MPU_uxTaskPriorityGetFromISR
#define xTaskResumeFromISR MPU_xTaskResumeFromISR
#define xTaskGetApplicationTaskTagFromISR MPU_xTaskGetApplicationTaskTagFromISR
#define xTaskGenericNotifyFromISR MPU_xTaskGenericNotifyFromISR
#define vTaskGenericNotifyGiveFromISR MPU_vTaskGenericNotifyGiveFromISR
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/* Map standard queue.h API functions to the MPU equivalents. */ /* Map standard queue.h API functions to the MPU equivalents. */
#define xQueueGenericSend MPU_xQueueGenericSend #define xQueueGenericSend MPU_xQueueGenericSend
#define xQueueReceive MPU_xQueueReceive #define xQueueReceive MPU_xQueueReceive
@@ -97,75 +123,159 @@ only for ports that are using the MPU. */
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
#define vQueueDelete MPU_vQueueDelete
#define xQueueCreateMutex MPU_xQueueCreateMutex
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
#define xQueueGenericCreate MPU_xQueueGenericCreate
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
#define xQueueCreateSet MPU_xQueueCreateSet
#define xQueueAddToSet MPU_xQueueAddToSet #define xQueueAddToSet MPU_xQueueAddToSet
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
#define xQueueSelectFromSet MPU_xQueueSelectFromSet #define xQueueSelectFromSet MPU_xQueueSelectFromSet
#define xQueueGenericReset MPU_xQueueGenericReset
#if ( configQUEUE_REGISTRY_SIZE > 0 ) #if ( configQUEUE_REGISTRY_SIZE > 0 )
#define vQueueAddToRegistry MPU_vQueueAddToRegistry #define vQueueAddToRegistry MPU_vQueueAddToRegistry
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
#define pcQueueGetName MPU_pcQueueGetName #define pcQueueGetName MPU_pcQueueGetName
#endif #endif /* #if ( configQUEUE_REGISTRY_SIZE > 0 ) */
/* 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. */
#define vQueueDelete MPU_vQueueDelete
#define xQueueCreateMutex MPU_xQueueCreateMutex
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
#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. */ /* Map standard timer.h API functions to the MPU equivalents. */
#define xTimerCreate MPU_xTimerCreate
#define xTimerCreateStatic MPU_xTimerCreateStatic
#define pvTimerGetTimerID MPU_pvTimerGetTimerID #define pvTimerGetTimerID MPU_pvTimerGetTimerID
#define vTimerSetTimerID MPU_vTimerSetTimerID #define vTimerSetTimerID MPU_vTimerSetTimerID
#define xTimerIsTimerActive MPU_xTimerIsTimerActive #define xTimerIsTimerActive MPU_xTimerIsTimerActive
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall #define xTimerGenericCommand MPU_xTimerGenericCommand
#define pcTimerGetName MPU_pcTimerGetName #define pcTimerGetName MPU_pcTimerGetName
#define vTimerSetReloadMode MPU_vTimerSetReloadMode #define vTimerSetReloadMode MPU_vTimerSetReloadMode
#define uxTimerGetReloadMode MPU_uxTimerGetReloadMode #define uxTimerGetReloadMode MPU_uxTimerGetReloadMode
#define xTimerGetPeriod MPU_xTimerGetPeriod #define xTimerGetPeriod MPU_xTimerGetPeriod
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
#define xTimerGenericCommand MPU_xTimerGenericCommand
#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. */ /* Map standard event_group.h API functions to the MPU equivalents. */
#define xEventGroupCreate MPU_xEventGroupCreate
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
#define xEventGroupWaitBits MPU_xEventGroupWaitBits #define xEventGroupWaitBits MPU_xEventGroupWaitBits
#define xEventGroupClearBits MPU_xEventGroupClearBits #define xEventGroupClearBits MPU_xEventGroupClearBits
#define xEventGroupSetBits MPU_xEventGroupSetBits #define xEventGroupSetBits MPU_xEventGroupSetBits
#define xEventGroupSync MPU_xEventGroupSync #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 #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 /* Map standard message/stream_buffer.h API functions to the MPU
equivalents. */ * equivalents. */
#define xStreamBufferSend MPU_xStreamBufferSend #define xStreamBufferSend MPU_xStreamBufferSend
#define xStreamBufferReceive MPU_xStreamBufferReceive #define xStreamBufferReceive MPU_xStreamBufferReceive
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
#define vStreamBufferDelete MPU_vStreamBufferDelete
#define xStreamBufferIsFull MPU_xStreamBufferIsFull #define xStreamBufferIsFull MPU_xStreamBufferIsFull
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
#define xStreamBufferReset MPU_xStreamBufferReset
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel #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 xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic #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 /* Remove the privileged function macro, but keep the PRIVILEGED_DATA
macro so applications can place data in privileged access sections * macro so applications can place data in privileged access sections
(useful when using statically allocated objects). */ * (useful when using statically allocated objects). */
#define PRIVILEGED_FUNCTION #define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
#define FREERTOS_SYSTEM_CALL #define FREERTOS_SYSTEM_CALL
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
#define vGrantAccessToTask( xTask, xTaskToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) )
#define vRevokeAccessToTask( xTask, xTaskToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToRevokeAccess ) )
#define vGrantAccessToSemaphore( xTask, xSemaphoreToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToGrantAccess ) )
#define vRevokeAccessToSemaphore( xTask, xSemaphoreToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToRevokeAccess ) )
#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 */ #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
/* Ensure API functions go in the privileged execution section. */ /* Ensure API functions go in the privileged execution section. */
@@ -180,10 +290,8 @@ only for ports that are using the MPU. */
#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 */
+117 -45
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!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
@@ -33,51 +34,43 @@
#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
#if portBYTE_ALIGNMENT == 16
#define portBYTE_ALIGNMENT_MASK ( 0x000f ) #define portBYTE_ALIGNMENT_MASK ( 0x000f )
#endif #elif portBYTE_ALIGNMENT == 8
#if portBYTE_ALIGNMENT == 8
#define portBYTE_ALIGNMENT_MASK ( 0x0007 ) #define portBYTE_ALIGNMENT_MASK ( 0x0007 )
#endif #elif portBYTE_ALIGNMENT == 4
#if portBYTE_ALIGNMENT == 4
#define portBYTE_ALIGNMENT_MASK ( 0x0003 ) #define portBYTE_ALIGNMENT_MASK ( 0x0003 )
#endif #elif portBYTE_ALIGNMENT == 2
#if portBYTE_ALIGNMENT == 2
#define portBYTE_ALIGNMENT_MASK ( 0x0001 ) #define portBYTE_ALIGNMENT_MASK ( 0x0001 )
#endif #elif portBYTE_ALIGNMENT == 1
#if portBYTE_ALIGNMENT == 1
#define portBYTE_ALIGNMENT_MASK ( 0x0000 ) #define portBYTE_ALIGNMENT_MASK ( 0x0000 )
#endif #else /* if portBYTE_ALIGNMENT == 32 */
#ifndef portBYTE_ALIGNMENT_MASK
#error "Invalid portBYTE_ALIGNMENT definition" #error "Invalid portBYTE_ALIGNMENT definition"
#endif /* if portBYTE_ALIGNMENT == 32 */
#ifndef portUSING_MPU_WRAPPERS
#define portUSING_MPU_WRAPPERS 0
#endif #endif
#ifndef portNUM_CONFIGURABLE_REGIONS #ifndef portNUM_CONFIGURABLE_REGIONS
@@ -92,9 +85,16 @@ must be set in the compiler's include path. */
#define portARCH_NAME NULL #define portARCH_NAME NULL
#endif #endif
#ifndef configSTACK_ALLOCATION_FROM_SEPARATE_HEAP
/* Defaults to 0 for backward compatibility. */
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */
#include "mpu_wrappers.h" #include "mpu_wrappers.h"
@@ -106,20 +106,34 @@ extern "C" {
*/ */
#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,
BaseType_t xRunPrivileged,
xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION;
#else #else
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters,
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 ) #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) 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, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
#endif TaskFunction_t pxCode,
void * pvParameters ) PRIVILEGED_FUNCTION;
#endif #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;
@@ -161,11 +175,34 @@ 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 * pvPortCalloc( size_t xNum,
size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFree( void * pv ) 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.
@@ -188,12 +225,47 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
*/ */
#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
/**
* @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
/**
* @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 #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */
#endif /* PORTABLE_H */ #endif /* PORTABLE_H */
+22 -15
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
@@ -35,14 +36,18 @@
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 )
@@ -59,14 +64,18 @@ definition here is not suitable for your application. */
#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
#else #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5a5a5a5a5aULL
#else
#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 */
@@ -95,6 +104,7 @@ itself. */
#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_EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
@@ -109,7 +119,7 @@ itself. */
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ #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
@@ -119,6 +129,3 @@ itself. */
#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,17 +45,25 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*
* 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
#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->pxStack ) \ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + 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 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -63,14 +72,14 @@
/* 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 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -78,7 +87,7 @@
#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; \
\ \
@@ -89,7 +98,7 @@
{ \ { \
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 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -97,7 +106,7 @@
#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, \
@@ -113,7 +122,7 @@
{ \ { \
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 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -126,4 +135,3 @@
#endif /* STACK_MACROS_H */ #endif /* STACK_MACROS_H */
+334 -248
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!
*/ */
/* /*
@@ -55,9 +56,11 @@
#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,37 +350,37 @@ 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
*/ */
@@ -317,12 +392,12 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
/** /**
* 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,39 +449,39 @@ 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
*/ */
@@ -418,12 +493,12 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
/** /**
* 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,29 +548,29 @@ 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
*/ */
@@ -507,12 +582,12 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
/** /**
* 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,39 +624,39 @@ 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
*/ */
@@ -593,9 +668,9 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
/** /**
* 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 uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
uint8_t ucStreamBufferGetStreamBufferType( 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
+137 -43
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!
*/ */
@@ -34,23 +35,25 @@
#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 )
@@ -85,12 +88,13 @@ 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 );
* *
@@ -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.
@@ -189,7 +193,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
* 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.
@@ -227,7 +231,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
#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
@@ -235,7 +239,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
/** /**
* 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 );
@@ -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.
@@ -357,7 +361,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
#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;
@@ -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,7 +549,8 @@ 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,
@@ -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,7 +794,8 @@ 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,
@@ -871,7 +881,8 @@ 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,
@@ -934,7 +945,8 @@ 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,
@@ -1007,7 +1019,8 @@ 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,
@@ -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 )
/** /**
@@ -1184,7 +1198,10 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* } * }
* @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,
@@ -1218,7 +1235,10 @@ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void
* 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,13 +1260,28 @@ 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;
/**
* BaseType_t xTimerGetReloadMode( 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.
*/
BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
/** /**
* UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ); * UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer );
@@ -1288,22 +1323,81 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
*/ */
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 uxTimerNumber ) PRIVILEGED_FUNCTION;
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) 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 */
+77 -49
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,17 +21,28 @@
* 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
*----------------------------------------------------------*/ *----------------------------------------------------------*/
@@ -37,23 +50,34 @@
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. */
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
/* The list end value is the highest possible value in the list to /* The list end value is the highest possible value in the list to
ensure it remains at the end of the list. */ * ensure it remains at the end of the list. */
pxList->xListEnd.xItemValue = portMAX_DELAY; pxList->xListEnd.xItemValue = portMAX_DELAY;
/* The list end next and previous pointers point to itself so we know /* The list end next and previous pointers point to itself so we know
when the list is empty. */ * 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.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. */ 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. */
/* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */
#if ( configUSE_MINI_LIST_ITEM == 0 )
{
pxList->xListEnd.pvOwner = NULL;
pxList->xListEnd.pxContainer = NULL;
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
}
#endif
pxList->uxNumberOfItems = ( UBaseType_t ) 0U; pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
/* Write known values into the list if /* Write known values into the list if
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
} }
@@ -65,25 +89,26 @@ void vListInitialiseItem( ListItem_t * const pxItem )
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;
@@ -100,25 +125,26 @@ ListItem_t * const pxIndex = pxList->pxIndex;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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 * 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 * 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 * 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 * 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 * the iteration loop below will not end. Therefore the value is checked
first, and the algorithm slightly modified if necessary. */ * first, and the algorithm slightly modified if necessary. */
if( xValueOfInsertion == portMAX_DELAY ) if( xValueOfInsertion == portMAX_DELAY )
{ {
pxIterator = pxList->xListEnd.pxPrevious; pxIterator = pxList->xListEnd.pxPrevious;
@@ -126,31 +152,34 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
else else
{ {
/* *** NOTE *********************************************************** /* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are * If you find your application is crashing here then likely causes are
listed below. In addition see https://www.freertos.org/FAQHelp.html for * listed below. In addition see https://www.FreeRTOS.org/FAQHelp.html for
more tips, and ensure configASSERT() is defined! * more tips, and ensure configASSERT() is defined!
https://www.freertos.org/a00110.html#configASSERT * https://www.FreeRTOS.org/a00110.html#configASSERT
*
1) Stack overflow - * 1) Stack overflow -
see https://www.freertos.org/Stacks-and-stack-overflow-checking.html * see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html
2) Incorrect interrupt priority assignment, especially on Cortex-M * 2) Incorrect interrupt priority assignment, especially on Cortex-M
parts where numerically high priority values denote low actual * parts where numerically high priority values denote low actual
interrupt priorities, which can seem counter intuitive. See * interrupt priorities, which can seem counter intuitive. See
https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition
of configMAX_SYSCALL_INTERRUPT_PRIORITY on * of configMAX_SYSCALL_INTERRUPT_PRIORITY on
https://www.freertos.org/a00110.html * https://www.FreeRTOS.org/a00110.html
3) Calling an API function from within a critical section or when * 3) Calling an API function from within a critical section or when
the scheduler is suspended, or calling an API function that does * the scheduler is suspended, or calling an API function that does
not end in "FromISR" from an interrupt. * not end in "FromISR" from an interrupt.
4) Using a queue or semaphore before it has been initialised or * 4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing * before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?). * 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.
**********************************************************************/ **********************************************************************/
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. */ 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. */
{ {
/* There is nothing to do here, just iterating to the wanted /* There is nothing to do here, just iterating to the wanted
insertion position. */ * insertion position. */
} }
} }
@@ -160,7 +189,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
pxIterator->pxNext = pxNewListItem; pxIterator->pxNext = pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the /* Remember which list the item is in. This allows fast removal of the
item later. */ * item later. */
pxNewListItem->pxContainer = pxList; pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++; ( pxList->uxNumberOfItems )++;
@@ -170,7 +199,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
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;
@@ -195,4 +224,3 @@ List_t * const pxList = pxItemToRemove->pxContainer;
return pxList->uxNumberOfItems; return pxList->uxNumberOfItems;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
@@ -37,36 +38,29 @@
#error This port can only be used when the project options are configured to enable hardware floating point support. #error This port can only be used when the project options are configured to enable hardware floating point support.
#endif #endif
#ifndef configSYSTICK_CLOCK_HZ
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
/* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else
/* The way the SysTick is clocked is not modified in case it is not the same
as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
#endif
/* Constants required to manipulate the core. Registers first... */ /* Constants required to manipulate the core. Registers first... */
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
/* ...then bits in the registers. */ /* ...then bits in the registers. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL )
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 /* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7
r0p1 port. */ * r0p1 port. */
#define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) #define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) )
#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL )
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
/* Constants required to check the validity of an interrupt priority. */ /* Constants required to check the validity of an interrupt priority. */
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) #define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
@@ -93,17 +87,29 @@ r0p1 port. */
#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) #define portMAX_24_BIT_NUMBER ( 0xffffffUL )
/* For strict compliance with the Cortex-M spec the task start address should /* For strict compliance with the Cortex-M spec the task start address should
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
/* A fiddle factor to estimate the number of SysTick counts that would have /* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle * occurred while the SysTick counter is stopped during tickless idle
calculations. */ * calculations. */
#define portMISSED_COUNTS_FACTOR ( 45UL ) #define portMISSED_COUNTS_FACTOR ( 94UL )
/* Let the user override the default SysTick clock rate. If defined by the
* user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the
* configuration register. */
#ifndef configSYSTICK_CLOCK_HZ
#define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ )
/* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT )
#else
/* Select the option to clock SysTick not at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 )
#endif
/* Let the user override the pre-loading of the initial LR with the address of /* Let the user override the pre-loading of the initial LR with the address of
prvTaskExitError() in case it messes up unwinding of the stack in the * prvTaskExitError() in case it messes up unwinding of the stack in the
debugger. */ * debugger. */
#ifdef configTASK_RETURN_ADDRESS #ifdef configTASK_RETURN_ADDRESS
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
#else #else
@@ -142,7 +148,7 @@ static void prvTaskExitError( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
variable. */ * variable. */
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
@@ -184,13 +190,15 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
interrupt. */ * interrupt. */
/* Offset added to account for the way the MCU uses the stack on entry/exit /* Offset added to account for the way the MCU uses the stack on entry/exit
of interrupts, and to ensure alignment. */ * of interrupts, and to ensure alignment. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */
@@ -204,7 +212,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
/* A save method is being used that requires each task to maintain its /* A save method is being used that requires each task to maintain its
own exec return value. */ * own exec return value. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portINITIAL_EXC_RETURN; *pxTopOfStack = portINITIAL_EXC_RETURN;
@@ -219,22 +227,23 @@ static void prvTaskExitError( void )
volatile uint32_t ulDummy = 0; volatile uint32_t ulDummy = 0;
/* A function that implements a task must not exit or attempt to return to /* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it * its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ). * should instead call vTaskDelete( NULL ).
*
Artificially force an assert() to be triggered if configASSERT() is * Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */ * defined, then stop here so application writers can catch the error. */
configASSERT( uxCriticalNesting == ~0UL ); configASSERT( uxCriticalNesting == ~0UL );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
while( ulDummy == 0 ) while( ulDummy == 0 )
{ {
/* This file calls prvTaskExitError() after the scheduler has been /* This file calls prvTaskExitError() after the scheduler has been
started to remove a compiler warning about the function being defined * started to remove a compiler warning about the function being defined
but never called. ulDummy is used purely to quieten other warnings * but never called. ulDummy is used purely to quieten other warnings
about code appearing after this function is called - making ulDummy * about code appearing after this function is called - making ulDummy
volatile makes the compiler think the function could return and * volatile makes the compiler think the function could return and
therefore not output an 'unreachable code' warning for code that appears * therefore not output an 'unreachable code' warning for code that appears
after it. */ * after it. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -261,9 +270,9 @@ void vPortSVCHandler( void )
static void prvPortStartFirstTask( void ) static void prvPortStartFirstTask( void )
{ {
/* Start the first task. This also clears the bit that indicates the FPU is /* Start the first task. This also clears the bit that indicates the FPU is
in use in case the FPU was used before the scheduler was started - which * in use in case the FPU was used before the scheduler was started - which
would otherwise result in the unnecessary leaving of space in the SVC stack * would otherwise result in the unnecessary leaving of space in the SVC stack
for lazy saving of FPU registers. */ * for lazy saving of FPU registers. */
__asm volatile ( __asm volatile (
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n" " ldr r0, [r0] \n"
@@ -277,6 +286,7 @@ static void prvPortStartFirstTask( void )
" isb \n" " isb \n"
" svc 0 \n" /* System call to start first task. */ " svc 0 \n" /* System call to start first task. */
" nop \n" " nop \n"
" .ltorg \n"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -286,32 +296,29 @@ static void prvPortStartFirstTask( void )
*/ */
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
/* This port can be used on all revisions of the Cortex-M7 core other than /* This port can be used on all revisions of the Cortex-M7 core other than
the r0p1 parts. r0p1 parts should use the port from the * the r0p1 parts. r0p1 parts should use the port from the
/source/portable/GCC/ARM_CM7/r0p1 directory. */ * /source/portable/GCC/ARM_CM7/r0p1 directory. */
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
#if ( configASSERT_DEFINED == 1 ) #if ( configASSERT_DEFINED == 1 )
{ {
volatile uint32_t ulOriginalPriority; volatile uint8_t ucOriginalPriority;
volatile uint32_t ulImplementedPrioBits = 0;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile uint8_t ucMaxPriorityValue; volatile uint8_t ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API /* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in * functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible. * ensure interrupt entry is as fast and simple as possible.
*
Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ucOriginalPriority = *pucFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all /* Determine the number of priority bits available. First write to all
possible bits. */ * possible bits. */
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */ /* Read the value back to see how many bits stuck. */
@@ -320,50 +327,71 @@ BaseType_t xPortStartScheduler( void )
/* Use the same mask on the maximum system call priority. */ /* Use the same mask on the maximum system call priority. */
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Check that the maximum system call priority is nonzero after
* accounting for the number of priority bits supported by the
* hardware. A priority of 0 is invalid because setting the BASEPRI
* register to 0 unmasks all interrupts, and interrupts with priority 0
* cannot be masked using BASEPRI.
* See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( ucMaxSysCallPriority );
/* Check that the bits not implemented in hardware are zero in
* configMAX_SYSCALL_INTERRUPT_PRIORITY. */
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U );
/* Calculate the maximum acceptable priority group value for the number /* Calculate the maximum acceptable priority group value for the number
of bits read back. */ * of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{ {
ulMaxPRIGROUPValue--; ulImplementedPrioBits++;
ucMaxPriorityValue <<= ( uint8_t ) 0x01; ucMaxPriorityValue <<= ( uint8_t ) 0x01;
} }
#ifdef __NVIC_PRIO_BITS if( ulImplementedPrioBits == 8 )
{ {
/* Check the CMSIS configuration that defines the number of /* When the hardware implements 8 priority bits, there is no way for
priority bits matches the number of priority bits actually queried * the software to configure PRIGROUP to not have sub-priorities. As
from the hardware. */ * a result, the least significant bit is always used for sub-priority
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); * and there are 128 preemption priorities and 2 sub-priorities.
*
* This may cause some confusion in some cases - for example, if
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
* priority interrupts will be masked in Critical Sections as those
* are at the same preemption priority. This may appear confusing as
* 4 is higher (numerically lower) priority than
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
* to 4, this confusion does not happen and the behaviour remains the same.
*
* The following assert ensures that the sub-priority bit in the
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
* confusion. */
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
ulMaxPRIGROUPValue = 0;
} }
#endif else
#ifdef configPRIO_BITS
{ {
/* Check the FreeRTOS configuration that defines the number of ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
priority bits matches the number of priority bits actually queried
from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
} }
#endif
/* Shift the priority group value back to its position within the AIRCR /* Shift the priority group value back to its position within the AIRCR
register. */ * register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original /* Restore the clobbered interrupt priority register to its original
value. */ * value. */
*pucFirstUserPriorityRegister = ulOriginalPriority; *pucFirstUserPriorityRegister = ucOriginalPriority;
} }
#endif /* conifgASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/* Make PendSV and SysTick the lowest priority interrupts. */ /* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
vPortSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */ /* Initialise the critical nesting count ready for the first task. */
@@ -379,11 +407,11 @@ BaseType_t xPortStartScheduler( void )
prvPortStartFirstTask(); prvPortStartFirstTask();
/* Should never get here as the tasks will now be executing! Call the task /* Should never get here as the tasks will now be executing! Call the task
exit error function to prevent compiler warnings about a static function * exit error function to prevent compiler warnings about a static function
not being called in the case that the application writer overrides this * not being called in the case that the application writer overrides this
functionality by defining configTASK_RETURN_ADDRESS. Call * functionality by defining configTASK_RETURN_ADDRESS. Call
vTaskSwitchContext() so link time optimisation does not remove the * vTaskSwitchContext() so link time optimisation does not remove the
symbol. */ * symbol. */
vTaskSwitchContext(); vTaskSwitchContext();
prvTaskExitError(); prvTaskExitError();
@@ -395,7 +423,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( uxCriticalNesting == 1000UL ); configASSERT( uxCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -406,10 +434,10 @@ void vPortEnterCritical( void )
uxCriticalNesting++; uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so /* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API * assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if * functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the * the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */ * assert function also uses a critical section. */
if( uxCriticalNesting == 1 ) if( uxCriticalNesting == 1 )
{ {
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
@@ -421,6 +449,7 @@ void vPortExitCritical( void )
{ {
configASSERT( uxCriticalNesting ); configASSERT( uxCriticalNesting );
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if( uxCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@@ -488,16 +517,16 @@ void xPortPendSVHandler( void )
void xPortSysTickHandler( void ) void xPortSysTickHandler( void )
{ {
/* The SysTick runs at the lowest interrupt priority, so when this interrupt /* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to * executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
} }
@@ -509,7 +538,7 @@ void xPortSysTickHandler( void )
__attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
{ {
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements; uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft;
TickType_t xModifiableIdleTime; TickType_t xModifiableIdleTime;
/* Make sure the SysTick reload value does not overflow the counter. */ /* Make sure the SysTick reload value does not overflow the counter. */
@@ -518,116 +547,125 @@ void xPortSysTickHandler( void )
xExpectedIdleTime = xMaximumPossibleSuppressedTicks; xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
} }
/* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
/* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way
through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation )
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ * method as that will mask interrupts that should exit sleep mode. */
__asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "cpsid i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* If a context switch is pending or a task is waiting for the scheduler /* If a context switch is pending or a task is waiting for the scheduler
to be unsuspended then abandon the low power entry. */ * to be unsuspended then abandon the low power entry. */
if( eTaskConfirmSleepModeStatus() == eAbortSleep ) if( eTaskConfirmSleepModeStatus() == eAbortSleep )
{ {
/* Restart from whatever is left in the count register to complete /* Re-enable interrupts - see comments above the cpsid instruction
this tick period. */ * above. */
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Reset the reload register to the value required for normal tick
periods. */
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
/* Re-enable interrupts - see comments above the cpsid instruction()
above. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
} }
else else
{ {
/* Stop the SysTick momentarily. The time the SysTick is stopped for
* is accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT );
/* Use the SysTick current-value register to determine the number of
* SysTick decrements remaining until the next tick interrupt. If the
* current-value register is zero, then there are actually
* ulTimerCountsForOneTick decrements remaining, not zero, because the
* SysTick requests the interrupt when decrementing from 1 to 0. */
ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG;
if( ulSysTickDecrementsLeft == 0 )
{
ulSysTickDecrementsLeft = ulTimerCountsForOneTick;
}
/* Calculate the reload value required to wait xExpectedIdleTime
* tick periods. -1 is used because this code normally executes part
* way through the first tick period. But if the SysTick IRQ is now
* pending, then clear the IRQ, suppressing the first tick, and correct
* the reload value to reflect that the second tick period is already
* underway. The expected idle time is always at least two ticks. */
ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 )
{
portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT;
ulReloadValue -= ulTimerCountsForOneTick;
}
if( ulReloadValue > ulStoppedTimerCompensation )
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Set the new reload value. */ /* Set the new reload value. */
portNVIC_SYSTICK_LOAD_REG = ulReloadValue; portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
/* Clear the SysTick count flag and set the count value back to /* Clear the SysTick count flag and set the count value back to
zero. */ * zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
set its parameter to 0 to indicate that its implementation contains * set its parameter to 0 to indicate that its implementation contains
its own wait for interrupt or wait for event instruction, and so wfi * its own wait for interrupt or wait for event instruction, and so wfi
should not be executed again. However, the original expected idle * should not be executed again. However, the original expected idle
time variable must remain unmodified, so a copy is taken. */ * time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
out of sleep mode to execute immediately. see comments above * out of sleep mode to execute immediately. See comments above
__disable_interrupt() call above. */ * the cpsid instruction above. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* Disable interrupts again because the clock is about to be stopped /* Disable interrupts again because the clock is about to be stopped
and interrupts that execute while the clock is stopped will increase * and interrupts that execute while the clock is stopped will increase
any slippage between the time maintained by the RTOS and calendar * any slippage between the time maintained by the RTOS and calendar
time. */ * time. */
__asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "cpsid i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* Disable the SysTick clock without reading the /* Disable the SysTick clock without reading the
portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_CTRL_REG register to ensure the
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
the time the SysTick is stopped for is accounted for as best it can * the time the SysTick is stopped for is accounted for as best it can
be, but using the tickless mode will inevitably result in some tiny * be, but using the tickless mode will inevitably result in some tiny
drift of the time maintained by the kernel with respect to calendar * drift of the time maintained by the kernel with respect to calendar
time*/ * time*/
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT );
/* Determine if the SysTick clock has already counted to zero and /* Determine whether the SysTick has already counted to zero. */
been set back to the current reload value (the reload back being
correct for the entire expected idle time) or if the SysTick is yet
to count to zero (in which case an interrupt other than the SysTick
must have brought the system out of sleep mode). */
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
uint32_t ulCalculatedLoadValue; uint32_t ulCalculatedLoadValue;
/* The tick interrupt is already pending, and the SysTick count /* The tick interrupt ended the sleep (or is now pending), and
reloaded with ulReloadValue. Reset the * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick * with whatever remains of the new tick period. */
period. */
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* Don't allow a tiny value, or values that have somehow /* Don't allow a tiny value, or values that have somehow
underflowed because the post sleep hook did something * underflowed because the post sleep hook did something
that took too long. */ * that took too long or because the SysTick current-value register
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) * is zero. */
if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
{ {
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
} }
@@ -635,34 +673,79 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
/* As the pending tick will be processed as soon as this /* As the pending tick will be processed as soon as this
function exits, the tick value maintained by the tick is stepped * function exits, the tick value maintained by the tick is stepped
forward by one less than the time spent waiting. */ * forward by one less than the time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL; ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
} }
else else
{ {
/* Something other than the tick interrupt ended the sleep. /* Something other than the tick interrupt ended the sleep. */
Work out how long the sleep lasted rounded to complete tick
periods (not the ulReload value which accounted for part /* Use the SysTick current-value register to determine the
ticks). */ * number of SysTick decrements remaining until the expected idle
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; * time would have ended. */
ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG;
#if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT )
{
/* If the SysTick is not using the core clock, the current-
* value register might still be zero here. In that case, the
* SysTick didn't load from the reload register, and there are
* ulReloadValue decrements remaining in the expected idle
* time, not zero. */
if( ulSysTickDecrementsLeft == 0 )
{
ulSysTickDecrementsLeft = ulReloadValue;
}
}
#endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */
/* Work out how long the sleep lasted rounded to complete tick
* periods (not the ulReload value which accounted for part
* ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft;
/* How many complete tick periods passed while the processor /* How many complete tick periods passed while the processor
was waiting? */ * was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick /* The reload value is set to whatever fraction of a single tick
period remains. */ * period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
} }
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again,
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If
value. */ * the SysTick is not using the core clock, temporarily configure it to
* use the core clock. This configuration forces the SysTick to load
* from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next
* cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready
* to receive the standard value immediately. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods ); #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT )
{
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
}
#else
{
/* The temporary usage of the core clock has served its purpose,
* as described above. Resume usage of the other clock. */
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{
/* The partial tick period already ended. Be sure the SysTick
* counts it only once. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0;
}
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
}
#endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */
/* Step the tick to account for any tick periods that elapsed. */
vTaskStepTick( ulCompleteTickPeriods );
/* Exit with interrupts enabled. */ /* Exit with interrupts enabled. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
@@ -693,7 +776,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
/* Configure SysTick to interrupt at the requested rate. */ /* Configure SysTick to interrupt at the requested rate. */
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -707,7 +790,8 @@ static void vPortEnableVFP( void )
" \n" " \n"
" orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */
" str r1, [r0] \n" " str r1, [r0] \n"
" bx r14 " " bx r14 \n"
" .ltorg \n"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -729,47 +813,45 @@ static void vPortEnableVFP( void )
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for /* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above * an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Interrupts that use the FreeRTOS API must not be left at their * Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority, * default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid. * and therefore also guaranteed to be invalid.
*
FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. * interrupt entry is as fast and simple as possible.
*
The following links provide detailed information: * The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */ * https://www.FreeRTOS.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
} }
/* Priority grouping: The interrupt controller (NVIC) allows the bits /* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that * that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define * define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
If the application only uses CMSIS libraries for interrupt * If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M * configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries * scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value * assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredictable behaviour. */ * of zero will result in unpredictable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
@@ -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.
@@ -56,16 +59,21 @@ 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
#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 #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -73,6 +81,7 @@ typedef unsigned long UBaseType_t;
#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. */
@@ -82,14 +91,14 @@ typedef unsigned long UBaseType_t;
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 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -106,8 +115,8 @@ extern void vPortExitCritical( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -132,6 +141,7 @@ not necessary for to use this port. They are defined so the common demo files
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; return ucReturn;
} }
@@ -219,7 +229,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
); );
/* 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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -235,9 +245,10 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
#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"
@@ -49,27 +51,53 @@ task.h is included from an application file. */
#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 #endif
#ifndef configHEAP_CLEAR_MEMORY_ON_FREE
#define configHEAP_CLEAR_MEMORY_ON_FREE 0
#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 /* 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. */ * heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 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,47 +108,45 @@ 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;
BlockLink_t * pxPreviousBlock;
BlockLink_t * pxNewBlockLink;
void * pvReturn = NULL; 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();
@@ -130,25 +156,29 @@ void *pvReturn = NULL;
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
/* 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 ) if( xWantedSize > 0 )
{
/* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
{ {
xWantedSize += xHeapStructSize; 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 );
if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
{
xWantedSize += xAdditionalRequiredSize;
}
else
{
xWantedSize = 0;
}
} }
else else
{ {
@@ -156,16 +186,28 @@ void *pvReturn = NULL;
} }
} }
else else
{
xWantedSize = 0;
}
}
else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
/* Check the block size we are trying to allocate 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( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
{
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{ {
/* Traverse the list from the start (lowest address) block until /* Traverse the list from the start (lowest address) block until
one of adequate size is found. */ * one of adequate size is found. */
pxPreviousBlock = &xStart; pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock; pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{ {
pxPreviousBlock = pxBlock; pxPreviousBlock = pxBlock;
@@ -173,30 +215,30 @@ void *pvReturn = NULL;
} }
/* If the end marker was reached then a block of adequate size /* If the end marker was reached then a block of adequate size
was not found. */ * was not found. */
if( pxBlock != pxEnd ) if( pxBlock != pxEnd )
{ {
/* Return the memory space pointed to - jumping over the /* Return the memory space pointed to - jumping over the
BlockLink_t structure at its start. */ * BlockLink_t structure at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
/* This block is being returned for use so must be taken out /* This block is being returned for use so must be taken out
of the list of free blocks. */ * of the list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into /* If the block is larger than required it can be split into
two. */ * two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
{ {
/* This block is to be split into two. Create a new /* This block is to be split into two. Create a new
block following the number of bytes requested. The void * block following the number of bytes requested. The void
cast is used to prevent byte alignment warnings from the * cast is used to prevent byte alignment warnings from the
compiler. */ * compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
/* Calculate the sizes of two blocks split from the /* Calculate the sizes of two blocks split from the
single block. */ * single block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize; pxBlock->xBlockSize = xWantedSize;
@@ -220,8 +262,8 @@ void *pvReturn = NULL;
} }
/* The block is being returned - it is allocated and owned /* The block is being returned - it is allocated and owned
by the application and has no "next" block. */ * by the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit; heapALLOCATE_BLOCK( pxBlock );
pxBlock->pxNextFreeBlock = NULL; pxBlock->pxNextFreeBlock = NULL;
xNumberOfSuccessfulAllocations++; xNumberOfSuccessfulAllocations++;
} }
@@ -248,7 +290,6 @@ void *pvReturn = NULL;
{ {
if( pvReturn == NULL ) if( pvReturn == NULL )
{ {
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook(); vApplicationMallocFailedHook();
} }
else else
@@ -256,7 +297,7 @@ void *pvReturn = NULL;
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
#endif #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */
configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn; return pvReturn;
@@ -271,23 +312,27 @@ 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();
{ {
@@ -330,69 +375,86 @@ void vPortInitialiseBlocks( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvHeapInit( void ) void * pvPortCalloc( size_t xNum,
size_t xSize )
{
void * pv = NULL;
if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 )
{
pv = pvPortMalloc( xNum * xSize );
if( pv != NULL )
{
( void ) memset( pv, 0, xNum * xSize );
}
}
return pv;
}
/*-----------------------------------------------------------*/
static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */
{ {
BlockLink_t * pxFirstFreeBlock; BlockLink_t * pxFirstFreeBlock;
uint8_t * pucAlignedHeap; uint8_t * pucAlignedHeap;
size_t uxAddress; portPOINTER_SIZE_TYPE uxAddress;
size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
/* Ensure the heap starts on a correctly aligned boundary. */ /* Ensure the heap starts on a correctly aligned boundary. */
uxAddress = ( size_t ) ucHeap; uxAddress = ( portPOINTER_SIZE_TYPE ) ucHeap;
if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
{ {
uxAddress += ( portBYTE_ALIGNMENT - 1 ); uxAddress += ( portBYTE_ALIGNMENT - 1 );
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK );
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; xTotalHeapSize -= ( size_t ) ( uxAddress - ( portPOINTER_SIZE_TYPE ) ucHeap );
} }
pucAlignedHeap = ( uint8_t * ) uxAddress; pucAlignedHeap = ( uint8_t * ) uxAddress;
/* xStart is used to hold a pointer to the first item in the list of free /* 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. */ * blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0; xStart.xBlockSize = ( size_t ) 0;
/* pxEnd is used to mark the end of the list of free blocks and is inserted /* pxEnd is used to mark the end of the list of free blocks and is inserted
at the end of the heap space. */ * at the end of the heap space. */
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress = ( portPOINTER_SIZE_TYPE ) ( pucAlignedHeap + xTotalHeapSize );
uxAddress -= xHeapStructSize; uxAddress -= xHeapStructSize;
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK );
pxEnd = ( void * ) uxAddress; pxEnd = ( BlockLink_t * ) uxAddress;
pxEnd->xBlockSize = 0; pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL; pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the /* 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. */ * entire heap space, minus the space taken by pxEnd. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock = ( BlockLink_t * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->xBlockSize = ( size_t ) ( uxAddress - ( portPOINTER_SIZE_TYPE ) pxFirstFreeBlock );
pxFirstFreeBlock->pxNextFreeBlock = pxEnd; pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
/* Only one block exists - and it covers the entire usable heap space. */ /* Only one block exists - and it covers the entire usable heap space. */
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
xFreeBytesRemaining = 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 prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVILEGED_FUNCTION */
{ {
BlockLink_t * pxIterator; BlockLink_t * pxIterator;
uint8_t * puc; uint8_t * puc;
/* Iterate through the list until a block is found that has a higher address /* Iterate through the list until a block is found that has a higher address
than the block being inserted. */ * than the block being inserted. */
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{ {
/* Nothing to do here, just iterate to the right position. */ /* Nothing to do here, just iterate to the right position. */
} }
/* Do the block being inserted, and the block it is being inserted after /* Do the block being inserted, and the block it is being inserted after
make a contiguous block of memory? */ * make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator; puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{ {
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
@@ -404,8 +466,9 @@ uint8_t *puc;
} }
/* Do the block being inserted, and the block it is being inserted before /* Do the block being inserted, and the block it is being inserted before
make a contiguous block of memory? */ * make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert; puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{ {
if( pxIterator->pxNextFreeBlock != pxEnd ) if( pxIterator->pxNextFreeBlock != pxEnd )
@@ -425,9 +488,9 @@ uint8_t *puc;
} }
/* If the block being inserted plugged a gab, so was merged with the block /* 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 * 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 * already been set, and should not be set here as that would make it point
to itself. */ * to itself. */
if( pxIterator != pxBlockToInsert ) if( pxIterator != pxBlockToInsert )
{ {
pxIterator->pxNextFreeBlock = pxBlockToInsert; pxIterator->pxNextFreeBlock = pxBlockToInsert;
@@ -449,13 +512,13 @@ size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY use
pxBlock = xStart.pxNextFreeBlock; pxBlock = xStart.pxNextFreeBlock;
/* pxBlock will be NULL if the heap has not been initialised. The heap /* pxBlock will be NULL if the heap has not been initialised. The heap
is initialised automatically when the first allocation is made. */ * is initialised automatically when the first allocation is made. */
if( pxBlock != NULL ) if( pxBlock != NULL )
{ {
do while( pxBlock != pxEnd )
{ {
/* Increment the number of blocks and record the largest block seen /* Increment the number of blocks and record the largest block seen
so far. */ * so far. */
xBlocks++; xBlocks++;
if( pxBlock->xBlockSize > xMaxSize ) if( pxBlock->xBlockSize > xMaxSize )
@@ -469,12 +532,12 @@ size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY use
} }
/* Move to the next block in the chain until the last block is /* Move to the next block in the chain until the last block is
reached. */ * reached. */
pxBlock = pxBlock->pxNextFreeBlock; pxBlock = pxBlock->pxNextFreeBlock;
} while( pxBlock != pxEnd );
} }
} }
xTaskResumeAll(); }
( void ) xTaskResumeAll();
pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize; pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize; pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;
@@ -489,4 +552,4 @@ size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY use
} }
taskEXIT_CRITICAL(); 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
+255 -236
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,18 +21,17 @@
* 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!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdlib.h> #include <stdlib.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"
@@ -43,23 +44,24 @@ task.h is included from an application file. */
#endif #endif
/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified /* 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 * 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 * for the header files above, but not in this file, in order to generate the
correct privileged Vs unprivileged linkage and placement. */ * correct privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */
/* This entire source file will be skipped if the application is not configured /* This entire source file will be skipped if the application is not configured
to include software timer functionality. This #if is closed at the very bottom * to include software timer functionality. This #if is closed at the very bottom
of this file. If you want to include software timer functionality then ensure * of this file. If you want to include software timer functionality then ensure
configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ * configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
#if ( configUSE_TIMERS == 1 ) #if ( configUSE_TIMERS == 1 )
/* Misc definitions. */ /* Misc definitions. */
#define tmrNO_DELAY ( TickType_t ) 0U #define tmrNO_DELAY ( ( TickType_t ) 0U )
#define tmrMAX_TIME_BEFORE_OVERFLOW ( ( TickType_t ) -1 )
/* The name assigned to the timer service task. This can be overridden by /* The name assigned to the timer service task. This can be overridden by
defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ * defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */
#ifndef configTIMER_SERVICE_TASK_NAME #ifndef configTIMER_SERVICE_TASK_NAME
#define configTIMER_SERVICE_TASK_NAME "Tmr Svc" #define configTIMER_SERVICE_TASK_NAME "Tmr Svc"
#endif #endif
@@ -72,30 +74,30 @@ defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */
/* The definition of the timers themselves. */ /* The definition of the timers themselves. */
typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */
{ {
const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const char * pcTimerName; /**< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ ListItem_t xTimerListItem; /**< Standard linked list item as used by all kernel features for event management. */
TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ TickType_t xTimerPeriodInTicks; /**< How quickly and often the timer expires. */
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ void * pvTimerID; /**< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ TimerCallbackFunction_t pxCallbackFunction; /**< The function that will be called when the timer expires. */
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ UBaseType_t uxTimerNumber; /**< An ID assigned by trace tools such as FreeRTOS+Trace */
#endif #endif
uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ uint8_t ucStatus; /**< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */
} xTIMER; } xTIMER;
/* The old xTIMER name is maintained above then typedefed to the new Timer_t /* The old xTIMER name is maintained above then typedefed to the new Timer_t
name below to enable the use of older kernel aware debuggers. */ * name below to enable the use of older kernel aware debuggers. */
typedef xTIMER Timer_t; typedef xTIMER Timer_t;
/* The definition of messages that can be sent and received on the timer queue. /* The definition of messages that can be sent and received on the timer queue.
Two types of message can be queued - messages that manipulate a software timer, * Two types of message can be queued - messages that manipulate a software timer,
and messages that request the execution of a non-timer related callback. The * and messages that request the execution of a non-timer related callback. The
two message types are defined in two separate structures, xTimerParametersType * two message types are defined in two separate structures, xTimerParametersType
and xCallbackParametersType respectively. */ * and xCallbackParametersType respectively. */
typedef struct tmrTimerParameters typedef struct tmrTimerParameters
{ {
TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ TickType_t xMessageValue; /**< An optional value used by a subset of commands, for example, when changing the period of a timer. */
Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ Timer_t * pxTimer; /**< The timer to which the command will be applied. */
} TimerParameter_t; } TimerParameter_t;
@@ -107,16 +109,16 @@ typedef struct tmrCallbackParameters
} CallbackParameters_t; } CallbackParameters_t;
/* The structure that contains the two message types, along with an identifier /* The structure that contains the two message types, along with an identifier
that is used to determine which message type is valid. */ * that is used to determine which message type is valid. */
typedef struct tmrTimerQueueMessage typedef struct tmrTimerQueueMessage
{ {
BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ BaseType_t xMessageID; /**< The command being sent to the timer service task. */
union union
{ {
TimerParameter_t xTimerParameters; TimerParameter_t xTimerParameters;
/* Don't include xCallbackParameters if it is not going to be used as /* Don't include xCallbackParameters if it is not going to be used as
it makes the structure (and therefore the timer queue) larger. */ * it makes the structure (and therefore the timer queue) larger. */
#if ( INCLUDE_xTimerPendFunctionCall == 1 ) #if ( INCLUDE_xTimerPendFunctionCall == 1 )
CallbackParameters_t xCallbackParameters; CallbackParameters_t xCallbackParameters;
#endif /* INCLUDE_xTimerPendFunctionCall */ #endif /* INCLUDE_xTimerPendFunctionCall */
@@ -124,14 +126,14 @@ typedef struct tmrTimerQueueMessage
} DaemonTaskMessage_t; } DaemonTaskMessage_t;
/*lint -save -e956 A manual analysis and inspection has been used to determine /*lint -save -e956 A manual analysis and inspection has been used to determine
which static variables must be declared volatile. */ * which static variables must be declared volatile. */
/* The list in which active timers are stored. Timers are referenced in expire /* The list in which active timers are stored. Timers are referenced in expire
time order, with the nearest expiry time at the front of the list. Only the * time order, with the nearest expiry time at the front of the list. Only the
timer service task is allowed to access these lists. * timer service task is allowed to access these lists.
xActiveTimerList1 and xActiveTimerList2 could be at function scope but that * xActiveTimerList1 and xActiveTimerList2 could be at function scope but that
breaks some kernel aware debuggers, and debuggers that reply on removing the * breaks some kernel aware debuggers, and debuggers that reply on removing the
static qualifier. */ * static qualifier. */
PRIVILEGED_DATA static List_t xActiveTimerList1; PRIVILEGED_DATA static List_t xActiveTimerList1;
PRIVILEGED_DATA static List_t xActiveTimerList2; PRIVILEGED_DATA static List_t xActiveTimerList2;
PRIVILEGED_DATA static List_t * pxCurrentTimerList; PRIVILEGED_DATA static List_t * pxCurrentTimerList;
@@ -145,16 +147,6 @@ PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
/* If static allocation is supported then the application must provide the
following callback function - which enables the application to optionally
provide the memory that will be used by the timer task as the task's stack
and TCB. */
extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );
#endif
/* /*
* Initialise the infrastructure used by the timer service task if it has not * Initialise the infrastructure used by the timer service task if it has not
* been initialised already. * been initialised already.
@@ -178,13 +170,26 @@ static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
* Insert the timer into either xActiveTimerList1, or xActiveTimerList2, * Insert the timer into either xActiveTimerList1, or xActiveTimerList2,
* depending on if the expire time causes a timer counter overflow. * depending on if the expire time causes a timer counter overflow.
*/ */
static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer,
const TickType_t xNextExpiryTime,
const TickType_t xTimeNow,
const TickType_t xCommandTime ) PRIVILEGED_FUNCTION;
/*
* Reload the specified auto-reload timer. If the reloading is backlogged,
* clear the backlog, calling the callback for each additional reload. When
* this function returns, the next expiry time is after xTimeNow.
*/
static void prvReloadTimer( Timer_t * const pxTimer,
TickType_t xExpiredTime,
const TickType_t xTimeNow ) PRIVILEGED_FUNCTION;
/* /*
* An active timer has reached its expire time. Reload the timer if it is an * An active timer has reached its expire time. Reload the timer if it is an
* auto-reload timer, then call its callback. * auto-reload timer, then call its callback.
*/ */
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; static void prvProcessExpiredTimer( const TickType_t xNextExpireTime,
const TickType_t xTimeNow ) PRIVILEGED_FUNCTION;
/* /*
* The tick count has overflowed. Switch the timer lists after ensuring the * The tick count has overflowed. Switch the timer lists after ensuring the
@@ -210,7 +215,8 @@ static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIV
* If a timer has expired, process it. Otherwise, block the timer service task * If a timer has expired, process it. Otherwise, block the timer service task
* until either a timer does expire or a command is received. * until either a timer does expire or a command is received.
*/ */
static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime,
BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION;
/* /*
* Called after a Timer_t structure has been allocated either statically or * Called after a Timer_t structure has been allocated either statically or
@@ -218,7 +224,7 @@ static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseTy
*/ */
static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ static void prvInitialiseNewTimer( 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,
Timer_t * pxNewTimer ) PRIVILEGED_FUNCTION; Timer_t * pxNewTimer ) PRIVILEGED_FUNCTION;
@@ -229,9 +235,9 @@ BaseType_t xTimerCreateTimerTask( void )
BaseType_t xReturn = pdFAIL; BaseType_t xReturn = pdFAIL;
/* This function is called when the scheduler is started if /* This function is called when the scheduler is started if
configUSE_TIMERS is set to 1. Check that the infrastructure used by the * configUSE_TIMERS is set to 1. Check that the infrastructure used by the
timer service task has been created/initialised. If timers have already * timer service task has been created/initialised. If timers have already
been created then the initialisation will already have been performed. */ * been created then the initialisation will already have been performed. */
prvCheckForValidListAndQueue(); prvCheckForValidListAndQueue();
if( xTimerQueue != NULL ) if( xTimerQueue != NULL )
@@ -256,7 +262,7 @@ BaseType_t xReturn = pdFAIL;
xReturn = pdPASS; xReturn = pdPASS;
} }
} }
#else #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
{ {
xReturn = xTaskCreate( prvTimerTask, xReturn = xTaskCreate( prvTimerTask,
configTIMER_SERVICE_TASK_NAME, configTIMER_SERVICE_TASK_NAME,
@@ -281,7 +287,7 @@ BaseType_t xReturn = pdFAIL;
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 ) TimerCallbackFunction_t pxCallbackFunction )
{ {
@@ -292,10 +298,10 @@ BaseType_t xReturn = pdFAIL;
if( pxNewTimer != NULL ) if( pxNewTimer != NULL )
{ {
/* Status is thus far zero as the timer is not created statically /* Status is thus far zero as the timer is not created statically
and has not been started. The auto-reload bit may get set in * and has not been started. The auto-reload bit may get set in
prvInitialiseNewTimer. */ * prvInitialiseNewTimer. */
pxNewTimer->ucStatus = 0x00; pxNewTimer->ucStatus = 0x00;
prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
} }
return pxNewTimer; return pxNewTimer;
@@ -308,7 +314,7 @@ BaseType_t xReturn = pdFAIL;
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 ) StaticTimer_t * pxTimerBuffer )
@@ -318,8 +324,8 @@ BaseType_t xReturn = pdFAIL;
#if ( configASSERT_DEFINED == 1 ) #if ( configASSERT_DEFINED == 1 )
{ {
/* Sanity check that the size of the structure used to declare a /* Sanity check that the size of the structure used to declare a
variable of type StaticTimer_t equals the size of the real timer * variable of type StaticTimer_t equals the size of the real timer
structure. */ * structure. */
volatile size_t xSize = sizeof( StaticTimer_t ); volatile size_t xSize = sizeof( StaticTimer_t );
configASSERT( xSize == sizeof( Timer_t ) ); configASSERT( xSize == sizeof( Timer_t ) );
( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */
@@ -333,11 +339,11 @@ BaseType_t xReturn = pdFAIL;
if( pxNewTimer != NULL ) if( pxNewTimer != NULL )
{ {
/* Timers can be created statically or dynamically so note this /* Timers can be created statically or dynamically so note this
timer was created statically in case it is later deleted. The * timer was created statically in case it is later deleted. The
auto-reload bit may get set in prvInitialiseNewTimer(). */ * auto-reload bit may get set in prvInitialiseNewTimer(). */
pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED; pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED;
prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
} }
return pxNewTimer; return pxNewTimer;
@@ -348,7 +354,7 @@ BaseType_t xReturn = pdFAIL;
static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ static void prvInitialiseNewTimer( 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,
Timer_t * pxNewTimer ) Timer_t * pxNewTimer )
@@ -356,29 +362,32 @@ static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e97
/* 0 is not a valid value for xTimerPeriodInTicks. */ /* 0 is not a valid value for xTimerPeriodInTicks. */
configASSERT( ( xTimerPeriodInTicks > 0 ) ); configASSERT( ( xTimerPeriodInTicks > 0 ) );
if( pxNewTimer != NULL )
{
/* Ensure the infrastructure used by the timer service task has been /* Ensure the infrastructure used by the timer service task has been
created/initialised. */ * created/initialised. */
prvCheckForValidListAndQueue(); prvCheckForValidListAndQueue();
/* Initialise the timer structure members using the function /* Initialise the timer structure members using the function
parameters. */ * parameters. */
pxNewTimer->pcTimerName = pcTimerName; pxNewTimer->pcTimerName = pcTimerName;
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
pxNewTimer->pvTimerID = pvTimerID; pxNewTimer->pvTimerID = pvTimerID;
pxNewTimer->pxCallbackFunction = pxCallbackFunction; pxNewTimer->pxCallbackFunction = pxCallbackFunction;
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
if( uxAutoReload != pdFALSE )
if( xAutoReload != pdFALSE )
{ {
pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
} }
traceTIMER_CREATE( pxNewTimer ); traceTIMER_CREATE( pxNewTimer );
} }
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) BaseType_t xTimerGenericCommand( TimerHandle_t xTimer,
const BaseType_t xCommandID,
const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait )
{ {
BaseType_t xReturn = pdFAIL; BaseType_t xReturn = pdFAIL;
DaemonTaskMessage_t xMessage; DaemonTaskMessage_t xMessage;
@@ -386,7 +395,7 @@ DaemonTaskMessage_t xMessage;
configASSERT( xTimer ); configASSERT( xTimer );
/* Send a message to the timer service task to perform a particular action /* Send a message to the timer service task to perform a particular action
on a particular timer definition. */ * on a particular timer definition. */
if( xTimerQueue != NULL ) if( xTimerQueue != NULL )
{ {
/* Send a command to the timer service task to start the xTimer timer. */ /* Send a command to the timer service task to start the xTimer timer. */
@@ -424,7 +433,7 @@ DaemonTaskMessage_t xMessage;
TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )
{ {
/* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been
started, then xTimerTaskHandle will be NULL. */ * started, then xTimerTaskHandle will be NULL. */
configASSERT( ( xTimerTaskHandle != NULL ) ); configASSERT( ( xTimerTaskHandle != NULL ) );
return xTimerTaskHandle; return xTimerTaskHandle;
} }
@@ -439,30 +448,31 @@ Timer_t *pxTimer = xTimer;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) void vTimerSetReloadMode( TimerHandle_t xTimer,
const BaseType_t xAutoReload )
{ {
Timer_t * pxTimer = xTimer; Timer_t * pxTimer = xTimer;
configASSERT( xTimer ); configASSERT( xTimer );
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
if( uxAutoReload != pdFALSE ) if( xAutoReload != pdFALSE )
{ {
pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
} }
else else
{ {
pxTimer->ucStatus &= ~tmrSTATUS_IS_AUTORELOAD; pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_AUTORELOAD );
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer )
{ {
Timer_t * pxTimer = xTimer; Timer_t * pxTimer = xTimer;
UBaseType_t uxReturn; BaseType_t xReturn;
configASSERT( xTimer ); configASSERT( xTimer );
taskENTER_CRITICAL(); taskENTER_CRITICAL();
@@ -470,17 +480,22 @@ UBaseType_t uxReturn;
if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) == 0 ) if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) == 0 )
{ {
/* Not an auto-reload timer. */ /* Not an auto-reload timer. */
uxReturn = ( UBaseType_t ) pdFALSE; xReturn = pdFALSE;
} }
else else
{ {
/* Is an auto-reload timer. */ /* Is an auto-reload timer. */
uxReturn = ( UBaseType_t ) pdTRUE; xReturn = pdTRUE;
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
return uxReturn; return xReturn;
}
UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer )
{
return ( UBaseType_t ) xTimerGetReloadMode( xTimer );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -495,6 +510,30 @@ TickType_t xReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
StaticTimer_t ** ppxTimerBuffer )
{
BaseType_t xReturn;
Timer_t * pxTimer = xTimer;
configASSERT( ppxTimerBuffer != NULL );
if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) != 0 )
{
*ppxTimerBuffer = ( StaticTimer_t * ) pxTimer;
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
return xReturn;
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/
const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{ {
Timer_t * pxTimer = xTimer; Timer_t * pxTimer = xTimer;
@@ -504,43 +543,48 @@ Timer_t *pxTimer = xTimer;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) static void prvReloadTimer( Timer_t * const pxTimer,
TickType_t xExpiredTime,
const TickType_t xTimeNow )
{
/* Insert the timer into the appropriate list for the next expiry time.
* If the next expiry time has already passed, advance the expiry time,
* call the callback function, and try again. */
while( prvInsertTimerInActiveList( pxTimer, ( xExpiredTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xExpiredTime ) != pdFALSE )
{
/* Advance the expiry time. */
xExpiredTime += pxTimer->xTimerPeriodInTicks;
/* Call the timer callback. */
traceTIMER_EXPIRED( pxTimer );
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
}
}
/*-----------------------------------------------------------*/
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime,
const TickType_t xTimeNow )
{ {
BaseType_t xResult;
Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
/* Remove the timer from the list of active timers. A check has already /* Remove the timer from the list of active timers. A check has already
been performed to ensure the list is not empty. */ * been performed to ensure the list is not empty. */
( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
traceTIMER_EXPIRED( pxTimer );
/* If the timer is an auto-reload timer then calculate the next /* If the timer is an auto-reload timer then calculate the next
expiry time and re-insert the timer in the list of active timers. */ * expiry time and re-insert the timer in the list of active timers. */
if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
{ {
/* The timer is inserted into a list using a time relative to anything prvReloadTimer( pxTimer, xNextExpireTime, xTimeNow );
other than the current time. It will therefore be inserted into the
correct list relative to the time this task thinks it is now. */
if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE )
{
/* The timer expired before it was added to the active timer
list. Reload it now. */
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
}
}
else
{
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;
mtCOVERAGE_TEST_MARKER();
} }
/* Call the timer callback. */ /* Call the timer callback. */
traceTIMER_EXPIRED( pxTimer );
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@@ -555,12 +599,10 @@ BaseType_t xListWasEmpty;
#if ( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) #if ( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 )
{ {
extern void vApplicationDaemonTaskStartupHook( void );
/* Allow the application writer to execute some code in the context of /* Allow the application writer to execute some code in the context of
this task at the point the task starts executing. This is useful if the * this task at the point the task starts executing. This is useful if the
application includes initialisation code that would benefit from * application includes initialisation code that would benefit from
executing after the scheduler has been started. */ * executing after the scheduler has been started. */
vApplicationDaemonTaskStartupHook(); vApplicationDaemonTaskStartupHook();
} }
#endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */
@@ -568,11 +610,11 @@ BaseType_t xListWasEmpty;
for( ; ; ) for( ; ; )
{ {
/* Query the timers list to see if it contains any timers, and if so, /* Query the timers list to see if it contains any timers, and if so,
obtain the time at which the next timer will expire. */ * obtain the time at which the next timer will expire. */
xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );
/* If a timer has expired, process it. Otherwise, block this task /* If a timer has expired, process it. Otherwise, block this task
until either a timer does expire, or a command is received. */ * until either a timer does expire, or a command is received. */
prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );
/* Empty the command queue. */ /* Empty the command queue. */
@@ -581,7 +623,8 @@ BaseType_t xListWasEmpty;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime,
BaseType_t xListWasEmpty )
{ {
TickType_t xTimeNow; TickType_t xTimeNow;
BaseType_t xTimerListsWereSwitched; BaseType_t xTimerListsWereSwitched;
@@ -589,11 +632,12 @@ BaseType_t xTimerListsWereSwitched;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
/* Obtain the time now to make an assessment as to whether the timer /* Obtain the time now to make an assessment as to whether the timer
has expired or not. If obtaining the time causes the lists to switch * has expired or not. If obtaining the time causes the lists to switch
then don't process this timer as any timers that remained in the list * then don't process this timer as any timers that remained in the list
when the lists were switched will have been processed within the * when the lists were switched will have been processed within the
prvSampleTimeNow() function. */ * prvSampleTimeNow() function. */
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
if( xTimerListsWereSwitched == pdFALSE ) if( xTimerListsWereSwitched == pdFALSE )
{ {
/* The tick count has not overflowed, has the timer expired? */ /* The tick count has not overflowed, has the timer expired? */
@@ -605,15 +649,15 @@ BaseType_t xTimerListsWereSwitched;
else else
{ {
/* The tick count has not overflowed, and the next expire /* The tick count has not overflowed, and the next expire
time has not been reached yet. This task should therefore * time has not been reached yet. This task should therefore
block to wait for the next expire time or a command to be * block to wait for the next expire time or a command to be
received - whichever comes first. The following line cannot * received - whichever comes first. The following line cannot
be reached unless xNextExpireTime > xTimeNow, except in the * be reached unless xNextExpireTime > xTimeNow, except in the
case when the current timer list is empty. */ * case when the current timer list is empty. */
if( xListWasEmpty != pdFALSE ) if( xListWasEmpty != pdFALSE )
{ {
/* The current timer list is empty - is the overflow list /* The current timer list is empty - is the overflow list
also empty? */ * also empty? */
xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList ); xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList );
} }
@@ -622,9 +666,9 @@ BaseType_t xTimerListsWereSwitched;
if( xTaskResumeAll() == pdFALSE ) if( xTaskResumeAll() == pdFALSE )
{ {
/* Yield to wait for either a command to arrive, or the /* Yield to wait for either a command to arrive, or the
block time to expire. If a command arrived between the * block time to expire. If a command arrived between the
critical section being exited and this yield then the yield * critical section being exited and this yield then the yield
will not cause the task to block. */ * will not cause the task to block. */
portYIELD_WITHIN_API(); portYIELD_WITHIN_API();
} }
else else
@@ -646,13 +690,14 @@ static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty )
TickType_t xNextExpireTime; TickType_t xNextExpireTime;
/* Timers are listed in expiry time order, with the head of the list /* Timers are listed in expiry time order, with the head of the list
referencing the task that will expire first. Obtain the time at which * referencing the task that will expire first. Obtain the time at which
the timer with the nearest expiry time will expire. If there are no * the timer with the nearest expiry time will expire. If there are no
active timers then just set the next expire time to 0. That will cause * active timers then just set the next expire time to 0. That will cause
this task to unblock when the tick count overflows, at which point the * this task to unblock when the tick count overflows, at which point the
timer lists will be switched and the next expiry time can be * timer lists will be switched and the next expiry time can be
re-assessed. */ * re-assessed. */
*pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );
if( *pxListWasEmpty == pdFALSE ) if( *pxListWasEmpty == pdFALSE )
{ {
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
@@ -690,7 +735,10 @@ PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Va
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer,
const TickType_t xNextExpiryTime,
const TickType_t xTimeNow,
const TickType_t xCommandTime )
{ {
BaseType_t xProcessTimerNow = pdFALSE; BaseType_t xProcessTimerNow = pdFALSE;
@@ -700,11 +748,11 @@ BaseType_t xProcessTimerNow = pdFALSE;
if( xNextExpiryTime <= xTimeNow ) if( xNextExpiryTime <= xTimeNow )
{ {
/* Has the expiry time elapsed between the command to start/reset a /* Has the expiry time elapsed between the command to start/reset a
timer was issued, and the time the command was processed? */ * timer was issued, and the time the command was processed? */
if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
{ {
/* The time between a command being issued and the command being /* The time between a command being issued and the command being
processed actually exceeds the timers period. */ * processed actually exceeds the timers period. */
xProcessTimerNow = pdTRUE; xProcessTimerNow = pdTRUE;
} }
else else
@@ -717,8 +765,8 @@ BaseType_t xProcessTimerNow = pdFALSE;
if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )
{ {
/* If, since the command was issued, the tick count has overflowed /* If, since the command was issued, the tick count has overflowed
but the expiry time has not, then the timer must have already passed * but the expiry time has not, then the timer must have already passed
its expiry time and should be processed immediately. */ * its expiry time and should be processed immediately. */
xProcessTimerNow = pdTRUE; xProcessTimerNow = pdTRUE;
} }
else else
@@ -735,7 +783,7 @@ static void prvProcessReceivedCommands( void )
{ {
DaemonTaskMessage_t xMessage; DaemonTaskMessage_t xMessage;
Timer_t * pxTimer; Timer_t * pxTimer;
BaseType_t xTimerListsWereSwitched, xResult; BaseType_t xTimerListsWereSwitched;
TickType_t xTimeNow; TickType_t xTimeNow;
while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */
@@ -743,13 +791,13 @@ TickType_t xTimeNow;
#if ( INCLUDE_xTimerPendFunctionCall == 1 ) #if ( INCLUDE_xTimerPendFunctionCall == 1 )
{ {
/* Negative commands are pended function calls rather than timer /* Negative commands are pended function calls rather than timer
commands. */ * commands. */
if( xMessage.xMessageID < ( BaseType_t ) 0 ) if( xMessage.xMessageID < ( BaseType_t ) 0 )
{ {
const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters );
/* The timer uses the xCallbackParameters member to request a /* The timer uses the xCallbackParameters member to request a
callback be executed. Check the callback is not NULL. */ * callback be executed. Check the callback is not NULL. */
configASSERT( pxCallback ); configASSERT( pxCallback );
/* Call the function. */ /* Call the function. */
@@ -763,11 +811,11 @@ TickType_t xTimeNow;
#endif /* INCLUDE_xTimerPendFunctionCall */ #endif /* INCLUDE_xTimerPendFunctionCall */
/* Commands that are positive are timer commands rather than pended /* Commands that are positive are timer commands rather than pended
function calls. */ * function calls. */
if( xMessage.xMessageID >= ( BaseType_t ) 0 ) if( xMessage.xMessageID >= ( BaseType_t ) 0 )
{ {
/* The messages uses the xTimerParameters member to work on a /* The messages uses the xTimerParameters member to work on a
software timer. */ * software timer. */
pxTimer = xMessage.u.xTimerParameters.pxTimer; pxTimer = xMessage.u.xTimerParameters.pxTimer;
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */ if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */
@@ -783,11 +831,11 @@ TickType_t xTimeNow;
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue );
/* In this case the xTimerListsWereSwitched parameter is not used, but /* In this case the xTimerListsWereSwitched parameter is not used, but
it must be present in the function call. prvSampleTimeNow() must be * it must be present in the function call. prvSampleTimeNow() must be
called after the message is received from xTimerQueue so there is no * called after the message is received from xTimerQueue so there is no
possibility of a higher priority task adding a message to the message * possibility of a higher priority task adding a message to the message
queue with a time that is ahead of the timer daemon task (because it * queue with a time that is ahead of the timer daemon task (because it
pre-empted the timer daemon task after the xTimeNow value was set). */ * pre-empted the timer daemon task after the xTimeNow value was set). */
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
switch( xMessage.xMessageID ) switch( xMessage.xMessageID )
@@ -796,37 +844,37 @@ TickType_t xTimeNow;
case tmrCOMMAND_START_FROM_ISR: case tmrCOMMAND_START_FROM_ISR:
case tmrCOMMAND_RESET: case tmrCOMMAND_RESET:
case tmrCOMMAND_RESET_FROM_ISR: case tmrCOMMAND_RESET_FROM_ISR:
case tmrCOMMAND_START_DONT_TRACE :
/* Start or restart a timer. */ /* Start or restart a timer. */
pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;
if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE )
{ {
/* The timer expired before it was added to the active /* The timer expired before it was added to the active
timer list. Process it now. */ * timer list. Process it now. */
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
traceTIMER_EXPIRED( pxTimer );
if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
{ {
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); prvReloadTimer( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow );
configASSERT( xResult ); }
( void ) xResult; else
} {
else pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
{ }
mtCOVERAGE_TEST_MARKER();
} /* Call the timer callback. */
traceTIMER_EXPIRED( pxTimer );
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
break; break;
case tmrCOMMAND_STOP: case tmrCOMMAND_STOP:
case tmrCOMMAND_STOP_FROM_ISR: case tmrCOMMAND_STOP_FROM_ISR:
/* The timer has already been removed from the active list. */ /* The timer has already been removed from the active list. */
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
break; break;
case tmrCOMMAND_CHANGE_PERIOD: case tmrCOMMAND_CHANGE_PERIOD:
@@ -836,11 +884,11 @@ TickType_t xTimeNow;
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
/* The new period does not really have a reference, and can /* The new period does not really have a reference, and can
be longer or shorter than the old one. The command time is * be longer or shorter than the old one. The command time is
therefore set to the current time, and as the period cannot * therefore set to the current time, and as the period cannot
be zero the next expiry time can only be in the future, * be zero the next expiry time can only be in the future,
meaning (unlike for the xTimerStart() case above) there is * meaning (unlike for the xTimerStart() case above) there is
no fail case that needs to be handled here. */ * no fail case that needs to be handled here. */
( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
break; break;
@@ -848,24 +896,24 @@ TickType_t xTimeNow;
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{ {
/* The timer has already been removed from the active list, /* The timer has already been removed from the active list,
just free up the memory if the memory was dynamically * just free up the memory if the memory was dynamically
allocated. */ * allocated. */
if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 )
{ {
vPortFree( pxTimer ); vPortFree( pxTimer );
} }
else else
{ {
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
} }
} }
#else #else /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
{ {
/* If dynamic allocation is not enabled, the memory /* If dynamic allocation is not enabled, the memory
could not have been dynamically allocated. So there is * could not have been dynamically allocated. So there is
no need to free the memory - just mark the timer as * no need to free the memory - just mark the timer as
"not active". */ * "not active". */
pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
} }
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
break; break;
@@ -881,55 +929,21 @@ TickType_t xTimeNow;
static void prvSwitchTimerLists( void ) static void prvSwitchTimerLists( void )
{ {
TickType_t xNextExpireTime, xReloadTime; TickType_t xNextExpireTime;
List_t * pxTemp; List_t * pxTemp;
Timer_t *pxTimer;
BaseType_t xResult;
/* The tick count has overflowed. The timer lists must be switched. /* The tick count has overflowed. The timer lists must be switched.
If there are any timers still referenced from the current timer list * If there are any timers still referenced from the current timer list
then they must have expired and should be processed before the lists * then they must have expired and should be processed before the lists
are switched. */ * are switched. */
while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )
{ {
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
/* Remove the timer from the list. */ /* Process the expired timer. For auto-reload timers, be careful to
pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ * process only expirations that occur on the current list. Further
( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); * expirations must wait until after the lists are switched. */
traceTIMER_EXPIRED( pxTimer ); prvProcessExpiredTimer( xNextExpireTime, tmrMAX_TIME_BEFORE_OVERFLOW );
/* Execute its callback, then send a command to restart the timer if
it is an auto-reload timer. It cannot be restarted here as the lists
have not yet been switched. */
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
{
/* Calculate the reload value, and if the reload value results in
the timer going into the same timer list then it has already expired
and the timer should be re-inserted into the current list so it is
processed again within this loop. Otherwise a command should be sent
to restart the timer to ensure it is only inserted into a list after
the lists have been swapped. */
xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );
if( xReloadTime > xNextExpireTime )
{
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
}
else
{
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
} }
pxTemp = pxCurrentTimerList; pxTemp = pxCurrentTimerList;
@@ -941,8 +955,8 @@ BaseType_t xResult;
static void prvCheckForValidListAndQueue( void ) static void prvCheckForValidListAndQueue( void )
{ {
/* Check that the list from which active timers are referenced, and the /* Check that the list from which active timers are referenced, and the
queue used to communicate with the timer service, have been * queue used to communicate with the timer service, have been
initialised. */ * initialised. */
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
if( xTimerQueue == NULL ) if( xTimerQueue == NULL )
@@ -955,9 +969,9 @@ static void prvCheckForValidListAndQueue( void )
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
{ {
/* The timer queue is allocated statically in case /* The timer queue is allocated statically in case
configSUPPORT_DYNAMIC_ALLOCATION is 0. */ * configSUPPORT_DYNAMIC_ALLOCATION is 0. */
static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ PRIVILEGED_DATA static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ PRIVILEGED_DATA static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue );
} }
@@ -965,7 +979,7 @@ static void prvCheckForValidListAndQueue( void )
{ {
xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
} }
#endif #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
#if ( configQUEUE_REGISTRY_SIZE > 0 ) #if ( configQUEUE_REGISTRY_SIZE > 0 )
{ {
@@ -1031,7 +1045,8 @@ void *pvReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) void vTimerSetTimerID( TimerHandle_t xTimer,
void * pvNewID )
{ {
Timer_t * const pxTimer = xTimer; Timer_t * const pxTimer = xTimer;
@@ -1047,13 +1062,16 @@ Timer_t * const pxTimer = xTimer;
#if ( INCLUDE_xTimerPendFunctionCall == 1 ) #if ( INCLUDE_xTimerPendFunctionCall == 1 )
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
BaseType_t * pxHigherPriorityTaskWoken )
{ {
DaemonTaskMessage_t xMessage; DaemonTaskMessage_t xMessage;
BaseType_t xReturn; BaseType_t xReturn;
/* Complete the message with the function parameters and post it to the /* Complete the message with the function parameters and post it to the
daemon task. */ * daemon task. */
xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;
xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
@@ -1071,18 +1089,21 @@ Timer_t * const pxTimer = xTimer;
#if ( INCLUDE_xTimerPendFunctionCall == 1 ) #if ( INCLUDE_xTimerPendFunctionCall == 1 )
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
TickType_t xTicksToWait )
{ {
DaemonTaskMessage_t xMessage; DaemonTaskMessage_t xMessage;
BaseType_t xReturn; BaseType_t xReturn;
/* This function can only be called after a timer has been created or /* This function can only be called after a timer has been created or
after the scheduler has been started because, until then, the timer * after the scheduler has been started because, until then, the timer
queue does not exist. */ * queue does not exist. */
configASSERT( xTimerQueue ); configASSERT( xTimerQueue );
/* Complete the message with the function parameters and post it to the /* Complete the message with the function parameters and post it to the
daemon task. */ * daemon task. */
xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK;
xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
@@ -1110,7 +1131,8 @@ Timer_t * const pxTimer = xTimer;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) void vTimerSetTimerNumber( TimerHandle_t xTimer,
UBaseType_t uxTimerNumber )
{ {
( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber; ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber;
} }
@@ -1119,9 +1141,6 @@ Timer_t * const pxTimer = xTimer;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This entire source file will be skipped if the application is not configured /* This entire source file will be skipped if the application is not configured
to include software timer functionality. If you want to include software timer * to include software timer functionality. If you want to include software timer
functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ * functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
#endif /* configUSE_TIMERS == 1 */ #endif /* configUSE_TIMERS == 1 */
+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 FreeRTOS
) )
@@ -117,6 +135,11 @@ add_library(USB_Device_Library OBJECT)
# Create USB_Device_Library static library # Create USB_Device_Library static library
add_library(USB_Device_Library OBJECT) 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)
# Create FreeRTOS static library
add_library(FreeRTOS OBJECT)
target_sources(FreeRTOS PRIVATE ${FreeRTOS_Src})
target_link_libraries(FreeRTOS PUBLIC stm32cubemx) target_link_libraries(FreeRTOS PUBLIC stm32cubemx)
# Add STM32CubeMX generated application sources to the project # Add STM32CubeMX generated application sources to the project
+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);