68 lines
2.5 KiB
C++
68 lines
2.5 KiB
C++
/**
|
|||
|
|
* @file ethercat_slave.h
|
||
|
|
* @brief EtherCAT 从站周期处理接口与 PDO 双缓冲(ping-pong)结构。
|
||
|
|
* @note 周期 ISR 调用 periodicIsr() 完成输入 PDO 读取 + 输出 PDO 写入;
|
||
|
|
* 应用层通过 getLatestInputs()/setOutputs() 与周期路径无锁交换数据。
|
||
|
|
*/
|
||
|
|
#ifndef COMM_ETHERCAT_SLAVE_H
|
||
|
|
#define COMM_ETHERCAT_SLAVE_H
|
||
|
|
|
||
|
|
#include <cstdint>
|
||
|
|
#include <cstddef>
|
||
|
|
|
||
|
|
/** @brief 默认 PDO 大小(可按需调整)。 */
|
||
|
|
constexpr size_t CONFIG_ETHERCAT_PDO_SIZE = 32U;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief PDO 数据缓冲(输入/输出共用结构)。
|
||
|
|
* @note 周期 ISR 与应用层通过双缓冲无锁交换。
|
||
|
|
*/
|
||
|
|
struct PdoBuffer {
|
||
|
|
uint8_t data[CONFIG_ETHERCAT_PDO_SIZE] = {0}; /**< 数据载荷。 */
|
||
|
|
size_t len = 0U; /**< 有效数据长度。 */
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief EtherCAT 从站周期处理。
|
||
|
|
* @note 周期路径(periodicIsr)必须极简:读输入→写输出→翻转指针→置位任务。
|
||
|
|
*/
|
||
|
|
class EthercatSlave {
|
||
|
|
public:
|
||
|
|
/** @brief 初始化 ESC 与双缓冲。 */
|
||
|
|
static void init();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief 周期中断处理(由 SYNC0 EXTI 触发)。
|
||
|
|
* @note 放入 RAM 执行段(.ramfunc)以降低 Flash 等待带来的抖动。
|
||
|
|
* 流程:读输入 PDO → 写输出 PDO → 翻转输入缓冲指针 → 置位 TASK_ETHERCAT_PROCESS。
|
||
|
|
*/
|
||
|
|
static void periodicIsr();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief 获取最新输入 PDO(主循环调用,无锁)。
|
||
|
|
* @return const PdoBuffer* 最新输入缓冲只读指针;周期 ISR 不会修改该缓冲。
|
||
|
|
*/
|
||
|
|
static const PdoBuffer* getLatestInputs();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief 设置下次周期要发送的输出 PDO(主循环调用)。
|
||
|
|
* @param[in] outputs 输出数据指针(内容会被拷贝到内部输出缓冲)。
|
||
|
|
* @note 调用方在 ISR 不持有期间调用即可,内部使用乒乓缓冲避免竞争。
|
||
|
|
*/
|
||
|
|
static void setOutputs(const PdoBuffer *outputs);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief 应用层 PDO 映射入口(非实时,由 TASK_ETHERCAT_PROCESS 调用)。
|
||
|
|
* @note 留接口,具体映射逻辑由协议栈后续实现。
|
||
|
|
*/
|
||
|
|
static void process();
|
||
|
|
|
||
|
|
private:
|
||
|
|
static PdoBuffer s_inputs[2]; /**< 输入双缓冲(pong-pong)。 */
|
||
|
|
static PdoBuffer s_outputs[2]; /**< 输出双缓冲(ping-pong)。 */
|
||
|
|
static volatile uint8_t s_inputReadIndex; /**< ISR 当前写入索引;getLatestInputs 读另一个。 */
|
||
|
|
static volatile uint8_t s_outputWriteIndex; /**< 应用层写入索引;ISR 读另一个。 */
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif /* COMM_ETHERCAT_SLAVE_H */
|