QP服务类型

确认:(仅在RC QP中)只有在响应方成功写入消息之后,才会将ack数据包发送回请求方。 如果请求者未发送确认,它将根据QP的属性重新发送邮件。 如果没有来自QP的确认(或否定),它将报告存在错误(超过重试次数)。

如果响应方发生任何类型的错误(保护,资源等),则将向请求方发送一个确认,并报告存在错误。

译自:https://www.rdmamojo.com/2013/06/01/which-queue-pair-type-to-use/

可靠连接(RC)QP

一个RC QP以可靠的方式连接到了一个RC QP(即发送和接收消息)。 可以确保消息最多从一次请求者传递到响应者一次,而且顺序没有损坏。 支持的最大消息大小最大为2GB(取决于支持的RDMA设备属性,该值可能会更低)。 RC QP支持发送操作(无立即),RDMA写操作(无立即),RDMA读操作和原子操作(取决于原子操作中的RDMA设备支持级别)。

如果消息大小大于路径MTU,则在发送数据的一侧将其分段,然后在接收器的一侧进行重组。

一旦响应者确认消息已被读/写到其内存,请求者就认为消息操作已完成。

一旦将消息读/写到其(本地)内存,响应者就​​认为消息操作已完成。

不可靠的连接(UC)QP

一个UC QP正在以一种不可靠的方式连接(即发送和接收消息)到一个UC QP。 无法保证对方会收到邮件:损坏或乱序的数据包会被静默丢弃。 如果数据包被丢弃,则它所属的整个消息都将被丢弃。 在这种情况下,响应者不会停止,而是继续接收传入的数据包。 包的顺序不能保证。 支持的最大消息大小最大为2GB(此值可能会更低,取决于支持的RDMA设备属性)。 RC QP支持发送操作(无立即)和RDMA写操作(无立即)。

如果消息大小大于路径MTU,则在发送数据的一侧将其分段,然后在接收器的一侧进行重组。

一旦所有消息发送到结构,请求者就认为消息操作已完成。

响应器以正确的顺序接收到完整的消息并将其写入其(本地)内存后,它便认为消息操作已完成。

不可靠的数据报(UD)QP

一个QP可能以一种不可靠的方式以单播(一对一)或多播(一对多)的方式向任何其他UD QP发送和接收消息。 无法保证对方会收到邮件:损坏或乱序的数据包会被静默丢弃。 包的顺序不能保证。 支持的最大消息大小是最大路径MTU。 UD QP仅支持发送操作。

一旦(一个数据包)消息发送到结构,请求者就认为消息操作已完成。

一旦收到完整的消息并将数据写入其(本地)内存,响应器便认为消息操作已完成。

选择正确的QP类型

选择正确的QP类型对于应用程序的更正和可伸缩性至关重要。

如果满足以下条件,则应选择RC QP:

  • 需要面料的可靠性
  • 交换矩阵大小不大或群集大小不大,但并非所有节点都将流量发送到同一节点(一个受害者)

RC QP的几种用途可以是:RDMA上的FTP或RDMA上的文件系统。

如果满足以下条件,则应选择UC QP:

  • 不需要结构的可靠性(即可靠性根本不重要,或者由应用程序负责)
  • 交换矩阵大小不大或群集大小不大,但并非所有节点都将流量发送到同一节点(一个受害者)
  • 大消息(超过路径MTU)正在发送

UC QP的一种用途是:RDMA上的视频。

如果满足以下条件,则应选择UD QP:

  • 不需要结构的可靠性(即可靠性根本不重要,或者由应用程序负责)
  • 结构的大小很大,所有节点和每个节点都将消息发送到结构中的任何其他节点。 UD是解决可伸缩性问题的最佳解决方案之一。
  • 需要多播消息

UD QP的一种用途是:RDMA语音。

摘要

下表描述了每种QP传输服务类型的特征:

MetricUDUCRC
Opcode: SEND (w/o immediate)SupportedSupportedSupported
Opcode: RDMA Write (w/o immediate)Not supportedSupportedSupported
Opcode: RDMA ReadNot supportedNot supportedSupported
Opcode: Atomic operationsNot supportedNot supportedSupported
ReliabilityNoNoYes
Connection typeDatagram (One to any/many)Connected (one to one)Connected (one to one)
Maximum message sizeMaximum path MTU2 GB2 GB
MulticastsupportedNot supportedNot supported
<think>好的,我现在需要帮用户了解如何将QP/C移植到FreeRTOS。首先,我得先确认自己对这两个框架的理解是否正确。QP/C是一个基于活动对象的实时框架,而FreeRTOS是一个广泛使用的实时操作系统。用户的需求是集成这两者,所以需要找到移植的方法和步骤。 首先,我应该回忆一下QP/C移植到其他RTOS的一般步骤。根据之前的引用,QP提供了可移植性层和端口,可能需要修改QEP和QF的组件,适配FreeRTOS的任务管理、同步机制等。用户提到的引用[1]和[2]提到QP已经支持多个RTOS,包括FreeRTOS,所以可能有现有的端口可以参考。 接下来,我需要考虑具体的步骤。首先可能需要获取QP/C的源码和FreeRTOS的源码,然后配置QP的移植层。这里可能涉及到修改头文件,比如qep_port.h和qf_port.h,设置正确的宏定义和函数接口。例如,任务创建函数需要调用FreeRTOS的xTaskCreate,队列需要使用FreeRTOS的QueueHandle_t等。 然后,同步机制如互斥锁、信号量需要替换为FreeRTOS的实现。QP中的事件队列可能要用FreeRTOS的队列或者消息缓冲区。内存管理方面,QP可能有自己的内存池,需要调整为FreeRTOS的pvPortMalloc和vPortFree。 接下来,测试和验证是关键步骤。需要确保任务调度正确,事件传递无误,并且没有资源泄漏。可能还需要调整优先级设置,确保活动对象的优先级与FreeRTOS的配置兼容。 用户可能还关心具体的示例代码或现有的端口,根据引用[1],QP为多个RTOS提供了即用型示例,所以应该建议用户查看QP官方提供的FreeRTOS端口示例,并参考官方文档。此外,引用[3]提到FreeRTOS的特点,比如任务调度和通信机制,这些在集成时需要特别注意。 需要注意的常见问题包括堆栈大小设置、优先级反转处理、中断服务例程中的API调用是否符合FreeRTOS要求。可能还需要配置FreeRTOS的宏,如configUSE_PREEMPTION和configUSE_TIME_SLICING,以匹配QP/C的需求。 总结步骤应该是:获取源码、配置移植层、适配任务和同步机制、处理内存管理、测试验证、参考示例和文档。同时提醒用户注意调试和常见问题,如堆栈溢出或优先级配置错误。</think>### QP/C移植到FreeRTOS的步骤详解 #### 1. **环境准备** - **获取QP/C源码**:从Quantum Leaps官网下载QP/C框架,确保版本兼容FreeRTOS[^2]。 - **集成FreeRTOS**:将FreeRTOS内核源码加入项目目录,例如使用`FreeRTOS-Kernel/include`和`FreeRTOS-Kernel/portable`。 #### 2. **移植层配置** - **修改头文件**: - **`qep_port.h`**:定义与FreeRTOS兼容的事件类型和宏,例如: ```c #define QF_CRIT_ENTRY() taskENTER_CRITICAL() #define QF_CRIT_EXIT() taskEXIT_CRITICAL() ``` - **`qf_port.h`**:配置任务管理接口,重定向到FreeRTOS函数: ```c #define QF_TASK(x) void x(void *pvParameters) #define Q_ACTIVE_START(me_, prio_, qSto_, qLen_, stkSto_, stkLen_, par_) \ xTaskCreate((me_), #me_, (stkLen_)/sizeof(StackType_t), (par_), (prio_), NULL) ``` #### 3. **任务与同步机制适配** - **活动对象任务化**:将QP的活动对象映射为FreeRTOS任务。例如: ```c static void AO_Blinky_task(void *pvParameters) { QActive_ctor(&AO_Blinky->super, Q_STATE_CAST(&Blinky_initial)); QF_run(); // 启动QP框架事件循环 } ``` - **事件队列实现**:使用FreeRTOS队列存储事件: ```c #define QF_EQUEUE_TYPE QueueHandle_t #define QACTIVE_EQUEUE_INIT(equeue_, stkSize_) \ (equeue_) = xQueueCreate((stkSize_), sizeof(QEvt*)) ``` #### 4. **内存管理适配** - **动态内存分配**:替换QP默认内存池为FreeRTOS的`pvPortMalloc`: ```c #define QF_POOL_INIT(p_, size_, n_) \ (p_) = pvPortMalloc((n_) * (size_)) #define QF_POOL_EVENT_INIT(p_, n_) \ (p_) = pvPortMalloc((n_) * sizeof(QEvt)) ``` #### 5. **中断处理与时间管理** - **系统时钟集成**:利用FreeRTOS的`vTaskDelay`或硬件定时器驱动QP的时钟节拍: ```c void SysTick_Handler(void) { QF_TICK_X(0U, &l_SysTick_Handler); // 触发QP时间事件 } ``` - **中断服务例程(ISR)**:确保中断中调用的QP函数符合FreeRTOS的`FromISR`规范。 #### 6. **验证与调试** - **基础功能测试**:创建两个活动对象,通过事件触发LED闪烁,验证任务调度和事件传递。 - **性能分析**:使用FreeRTOS的`uxTaskGetStackHighWaterMark`检查任务堆栈使用,避免溢出。 - **优先级配置**:确保活动对象优先级在FreeRTOS的`configMAX_PRIORITIES`范围内。 #### 7. **示例参考** - **QP官方示例**:查看`qp/ports/freertos`目录下的工程模板,例如`blinky`示例。 - **关键代码片段**: ```c // main.c int main(void) { QF_init(); // 初始化QP框架 QActive_start(AO_Blinky, 1, &blinkyQueueSto[0], 10, NULL, 0, 0); vTaskStartScheduler(); // 启动FreeRTOS调度器 return 0; } ``` #### 8. **常见问题** - **堆栈不足**:通过`uxTaskGetStackHighWaterMark`调整`configMINIMAL_STACK_SIZE`。 - **优先级反转**:使用FreeRTOS的互斥量优先级继承(`configUSE_MUTEXES`)。 - **事件丢失**:增大队列长度或使用`Q_NEW_REF()`动态创建事件。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值