FreeRTOS学习——Systick中断、SVC中断、PendSV中断
FreeRTOS学习——接口宏portmacro.h,仅用于记录自己阅读与学习源码
FreeRTOS Kernel V10.5.1
port :GCC/ARM_CM7
文章目录
- Systick
- 源码
- 触发方式
- SVC
- 源码
- 触发方式
- PendSV
- 源码
- 触发方式
- 相关汇编指令
Systick
源码
在Systick中断xPortSysTickHandler中,只做了一件事,那就是挂起PendSV中断。
所以其实切换任务是在PendSV中断执行的。
void xPortSysTickHandler( void )
{/* SysTick以最低的中断优先级运行 */portDISABLE_INTERRUPTS();{/* Increment the RTOS tick. */if( xTaskIncrementTick() != pdFALSE ){/* 上下文切换在 PendSV 中断 中执行* 挂起 PendSV 中断. */portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;}}portENABLE_INTERRUPTS();
}
触发方式
在开启调度器时,会调用定时器中断设置函数vPortSetupTimerInterrupt,以生成 tick 中断,如下:
vTaskStartScheduler →
xPortStartScheduler →
vPortSetupTimerInterrupt
配置系统的滴答定时器,以允许操作系统根据配置的频率生成定时中断,从而支持任务的调度和管理
__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
{/* 低功耗模式,这里先不做分析. */#if ( configUSE_TICKLESS_IDLE == 1 ){ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );}#endif /* configUSE_TICKLESS_IDLE *//* 停止和清除SysTick. */portNVIC_SYSTICK_CTRL_REG = 0UL;/*将控制寄存器设置为0,停止SysTick*/portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;/*将当前值寄存器清零。*//* 配置SysTick. *//* 设置加载寄存器,将SysTick的计数重加载为目标计数值*/portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;/* 设置SysTick的控制寄存器,以启用时钟、启用中断和使能SysTick*/portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
}
这几个值分别是
#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 )#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( 1000 )#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
然后就会按照设定的时间(默认1ms)周期性的触发Systick中断
SVC
源码
void vPortSVCHandler( void )
{__asm volatile ( /* volatile表示不能移除或重排序这段代码. */" ldr r3, pxCurrentTCBConst2 \n"/* 将pxCurrentTCB的地址加载到r3中. */" ldr r1, [r3] \n"/* 从r3指向的位置读取当前任务控制块(TCB)的地址并将其存储在r1中. */" ldr r0, [r1] \n"/* 从r1指向的位置读取数据,即当前任务控制块中的第一个元素,所以r0中保存的就是当前任务栈的栈顶地址. */" ldmia r0!, {r4-r11, r14} \n"/* 栈中弹出寄存器r4到r11和r14(链接寄存器),这里使用ldmia指令(加载多寄存器),!表示更新指针r0,指向下一个数据. */" msr psp, r0 \n"/* 将恢复后的任务栈指针r0存入psp,这样就恢复了当前任务的执行上下文. */" isb \n"/* 指令同步屏障,确保之前的指令在接下来的指令执行之前完成*/" mov r0, #0 \n"/* 将寄存器r0清零,准备设置中断优先级屏蔽*/" msr basepri, r0 \n"/* 将basepri设置为0,意味着没有设置优先级屏蔽,允许所有中断*/" bx r14 \n"/* 通过bx指令跳转到r14寄存器中保存的地址,通常是返回到被中断的任务执行*/" \n"" .align 4 \n"/* 确保下一条指令或数据在4字节边界对齐*/"pxCurrentTCBConst2: .word pxCurrentTCB \n"/* 定义一个标签pxCurrentTCBConst2,并将pxCurrentTCB的地址存储到这个标签中,以便在前面的ldr指令中使用*/);
}
- 获取当前任务控制块pxCurrentTCB的栈顶地址
- 将r4-r11, r14手动出栈
- 将当前栈顶指针存入psp
- 开中断
ldr r3, pxCurrentTCBConst2:将pxCurrentTCBConst2的值(即pxCurrentTCB的地址)加载到寄存器r3中。
ldr r1, [r3]:从r3指向的内存地址加载当前任务控制块(TCB)的地址到r1中。
ldr r0, [r1]:从r1指向的TCB地址加载当前任务栈的栈顶地址到r0中。
ldmia r0!, {r4-r11, r14}:从r0指向的栈中弹出寄存器r4到r11和r14,!表示更新r0的值,指向下一个数据。
msr psp, r0:将恢复后的任务栈指针r0存入PSP(进程栈指针)。
mov r0, #0:将寄存器r0清零。
msr basepri, r0:将basepri寄存器设置为0,允许所有中断。
bx r14:跳转到返回地址。
pxCurrentTCBConst2: .word pxCurrentTCB:定义标签pxCurrentTCBConst2并将pxCurrentTCB的地址存储在该位置
触发方式
SVC(Supervisor Call)中断是通过软件触发的中断
SVC指令:软件通过执行 SVC 指令显式地请求中断,svc 0
当SVC指令被执行后,处理器会根据中断向量表中的信息跳转到相应的SVC中断处理函数,执行SVC指令时,处理器会自动保存当前的上下文,并将处理器的模式切换为特权模式,从而允许执行受限的操作
在开启调度器时,会调用开始第一个任务函数,如下
vTaskStartScheduler →
xPortStartScheduler →
prvPortStartFirstTask
static void prvPortStartFirstTask( void )
{/* 开始第一个任务。这也清除了指示FPU正在使用的位,以防FPU在调度器启动之前被使用,* 否则会导致SVC堆栈中不必要的空间留下,以延迟保存FPU寄存器。 */__asm volatile (" ldr r0, =0xE000ED08 \n"/* 加载NVIC偏移寄存器的地址到r0寄存器,这个寄存器用于访问系统控制块(SCB)的基地址. */" ldr r0, [r0] \n"" ldr r0, [r0] \n"/* 读取两次,从SCB中加载系统栈指针(MSP)的值到r0寄存器*/" msr msp, r0 \n"/* 将r0中的值设置为主栈指针(MSP),这标志着栈的开始. */" mov r0, #0 \n"/* 清除控制寄存器中指示FPU正在使用的位,以确保不保留之前的状态. */" msr control, r0 \n"" cpsie i \n"/* 开中断. */" cpsie f \n"" dsb \n"" isb \n"" svc 0 \n"/* 触发SVC异常. */" nop \n"" .ltorg \n");
}
- 获取系统堆栈指针MSP
- 清除FPU正在使用的位
- 开中断
- 触发SVC异常
PendSV
源码
void xPortPendSVHandler( void )
{/* This is a naked function. */__asm volatile(" mrs r0, psp \n"/* 读取当前进程的栈指针(Process Stack Pointer),将其值存入寄存器 r0*/" isb \n"/* 指令同步屏障*/" \n"" ldr r3, pxCurrentTCBConst \n"/* 将pxCurrentTCB的地址加载到寄存器 r3. */" ldr r2, [r3] \n"/* 从r3指向的位置读取当前任务控制块(TCB)的地址并将其存储在r2中. */" \n"" tst r14, #0x10 \n"/* 测试链接寄存器 r14 的第 4 位,判断当前任务是否使用浮点单元(FPU). */" it eq \n"/* 如果第 4 位为 1(即使用 FPU 上下文),则执行接下来的语句*/" vstmdbeq r0!, {s16-s31} \n"/* 如果使用 FPU 上下文,则将 FPU 的高寄存器(s16 到 s31)压入栈中*/" \n"" stmdb r0!, {r4-r11, r14} \n"/* 将寄存器 r4 到 r11 及 r14 压入栈中. */" str r0, [r2] \n"/* 将新的栈顶指针值保存到 TCB 中. */" \n"" stmdb sp!, {r0, r3} \n"/* 将目前的栈指针和 TCB 地址压入主栈,以便恢复,这里入栈是 MSP*/" mov r0, %0 \n"/* 将最大可用优先级(configMAX_SYSCALL_INTERRUPT_PRIORITY)加载到 r0 中*/" cpsid i \n"/* 禁止中断. */" msr basepri, r0 \n"/* 设置优先级屏蔽寄存器(Base Priority),关中断*/" dsb \n"/* 数据同步屏障*/" isb \n"/* 指令同步屏障*/" cpsie i \n"/* 启用中断 */" bl vTaskSwitchContext \n"/* 调用任务切换的上下文切换函数*/" mov r0, #0 \n"" msr basepri, r0 \n"/* 恢复 Base Priority 为 0,开中断*/" ldmia sp!, {r0, r3} \n"/* 从主栈中恢复之前保存的 r0 和 r3*/" \n"" ldr r1, [r3] \n"/* 从r3指向的位置读取当前任务控制块(已经更新过了)的地址并将其存储在r1中. */" ldr r0, [r1] \n"/* 从r1指向的位置读取数据,即当前任务控制块中的第一个元素,所以r0中保存的就是当前任务栈的栈顶地址*/" \n"" ldmia r0!, {r4-r11, r14} \n"/* 从栈中弹出保存的核心寄存器r4-r11 和 r14. */" \n"" tst r14, #0x10 \n"/* 再次判断是否使用 FPU 上下文. */" it eq \n"/* 如果使用 FPU,上下文则执行下一条指令*/" vldmiaeq r0!, {s16-s31} \n"/* 如果使用 FPU,则从栈中弹出高寄存器(s16 到 s31)*/" \n"" msr psp, r0 \n"/* 将恢复后的栈指针值写入PSP,以便切换到新的任务的栈中. */" isb \n"/* 指令同步屏障*/" \n"#ifdef WORKAROUND_PMU_CM001 /* XMC4000特定勘误表解决方法. 这里不用管*/#if WORKAROUND_PMU_CM001 == 1" push { r14 } \n"" pop { pc } \n"#endif#endif" \n"" bx r14 \n"/* 返回到调用该处理程序的位置*/" \n"/* 将后面的数据对齐到 4 字节*/" .align 4 \n""pxCurrentTCBConst: .word pxCurrentTCB \n"::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ));
}
在PendSV中干了两件事
一是保存当前任务的现场
- 获取当前任务控制块pxCurrentTCB的栈顶地址
- 将核心寄存器入栈(其他寄存器在进入中断之前已经自动入栈)
- 保存栈顶指针
二是恢复最新任务的现场
- 调用任务切换的上下文切换函数,然后pxCurrentTCBConst中指向的值就已经变成了新的TCB的地址,但是pxCurrentTCBConst本身的内存地址是不变得
- 获取最新任务控制块pxCurrentTCB的栈顶地址
- 将核心寄存器出栈(其他寄存器在退出中断之后会自动出栈)
- 将栈顶指针值写入PSP
这样就完成了上下文的切换, 在进入中断前后,堆栈指针的变化是:
- 进入中断前,使用PSP,PSP指向旧任务的栈顶
- 在中断中,使用MSP
- 退出中断后,使用PSP,PSP指向新任务的栈顶
任务切换函数vTaskSwitchContext →
taskSELECT_HIGHEST_PRIORITY_TASK →
listGET_OWNER_OF_NEXT_ENTRY
经过此函数后,pxCurrentTCBConst已经指向了新的TCB
触发方式
1 在Systick handle中触发
/* 上下文切换在 PendSV 中断 中执行* 挂起 PendSV 中断. */portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
2 taskYIELD();
通过调用taskYIELD来触发
#define portYIELD() \{ \/* Set a PendSV to request a context switch. */ \portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \\/* Barriers are normally not required but do ensure the code is completely \* within the specified behaviour for the architecture. */ \__asm volatile ( "dsb" ::: "memory" ); \__asm volatile ( "isb" ); \}
相关汇编指令
- ldr:加载寄存器指令,用于从内存中加载数据到寄存器中。
- ldmia:加载多寄存器指令,可以一次性将多个内存单元的数据加载到多个寄存器中。
- msr:移动至特权寄存器的指令,用于设置某些特定的寄存器。
- isb:指令同步屏障,用于确保指令执行的顺序,确保之前的指令在接下来的指令执行之前完成
- dsb:数据同步屏障,该指令确保所有之前的读写操作在继续执行后续指令之前完成
- mov:数据传送指令,用于将一个常数值或寄存器的值移动到另一个寄存器。
- bx:分支和交换指令,用于跳转到r14寄存器中保存的地址。
- .align:伪指令,用于确保下一条指令或数据在指定的字节边界对齐。
- .word:伪指令,定义一个字(4字节)并将值存储到该位置。
- nop用于在代码中占用一个执行周期,但不进行任何操作,常常针对时序和代码结构进行调整
- .ltorg用于生成字面量池,为代码中使用的常量提供存储空间。通过将常量放置在易于访问的位置,它提高了程序的整体性能。
- 开关中断指令
CPSID I ;PRIMASK=1 ;关中断 (硬件错误异常 不关)
CPSIE I ;PRIMASK=0 ;开中断
CPSID F ;FAULTMASK=1 ;关异常(硬件错误异常 也关)
CPSIE F ;FAULTMASK=0 ;开异常
本人菜鸟,欢迎大佬们甄误
相关文章:
FreeRTOS学习——Systick中断、SVC中断、PendSV中断
FreeRTOS学习——接口宏portmacro.h,仅用于记录自己阅读与学习源码 FreeRTOS Kernel V10.5.1 port :GCC/ARM_CM7 文章目录 Systick源码触发方式 SVC源码触发方式 PendSV源码触发方式 相关汇编指令 Systick 源码 在Systick中断xPortSysTickHandler中&am…...
汇量科技大数据面试题及参考答案
如何在 SQL 中处理三个字段完全一样的去重?在 Scala 中又该如何实现? 在 SQL 中,可以使用多种方法来处理三个字段完全一样的去重。一种常见的方法是使用 DISTINCT 关键字结合多个字段来实现。例如,假设有表 table_name,包含字段 field1、field2 和 field3,可以使用以下 S…...
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.AVL树
1.AVL 树 1.1AVL 树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查 找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii 和E.M.Landis在1962…...
Python 的数据类型与操作
一、常用内置类型(Built - in Types) Python 拥有多种内置数据类型,这些类型满足了各种编程需求,从简单的数据存储到复杂的数据结构表示。 1. 数值类型(Numeric Types) 整数(int)&a…...
Python燃烧废气排放推断算法模型
🎯要点 宏观能耗场景模型参数化输入数据,分析可视化输出结果,使用场景时间序列数据模型及定量和定性指标使用线图和箱线图、饼图、散点图、堆积条形图、桑基图等可视化模型输出结果根据气体排放过程得出其时间序列关系,使用推断模…...
Qt中多语言的操作(以QtCreator为例)
1、首先,我们在代码中与文本相关的且需要支持多语言的地方,用tr来包含多语言key(多语言key是我们自己定义的),如下 //举例 QPushButton* btnnew QPushButton(this); btn->move(20,20); btn->resize(100,50); //…...
计算机毕业设计 社区医疗服务系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
html+css学习
html 元素 html元素是HTML的根元素,一个文档只能有一个,其他所有元素都是其后代元素 html有一个属性为lang,其作用是: 帮助语言合成工具确定要使用的发音帮助翻译工具确定要使用的翻译规则 当属性lang“en”则表示告诉其浏览器…...
2.gitlab ce 细粒度的权限控制
需求: 在提交merge reqeust时,必须指定审核人,并且要选审核人清单里的 有个code owners应该可以做到(gitlab ce应该也可以用) 下面是参考的文档 细粒度的代码权限怎么做?极狐GitLab 代码所有者来帮忙 -…...
G - Merchant Takahashi / F - Useless for LIS
G - Merchant Takahashi 首先考虑暴力 DP。 设最后一步走到编号 ii 的城镇的方案的最大收益为 fifi,则每次集市相当于是 fTi←fj−C∣Ti−j∣Pi(1≤j≤n)。 这样每次可以通过枚举 j 来转移,这样总时间复杂度是 O(nm) 的&…...
自然语言处理实例
引子:基于聊天机器人项目的自然语言处理(NLP)学习路线 自然语言处理(Natural Language Processing,简称 NLP)是人工智能的重要分支,旨在帮助计算机理解、生成和处理人类语言。NLP 技术广泛应用于搜索引擎、机器翻译、语音识别、文本摘要、情感分析、对话系统等领域。为…...
『功能项目』主角属性值显示【75】
本章项目成果展示 我们打开上一篇74穿戴装备的项目, 本章要做的事情是制作主角属性界面,实现在面板上显示主角的攻击力等数值 制作一个简易的主角界面(创建Image与Text显示即可) 创建一个空物体 重命名为PlayerInfo 在其子级下创…...
单片机嵌入式编程中常用技术点
Open CV,QT,Linux,多线程,网络编程,文件编程在单片机嵌入式编程中,这些技术在单片机嵌入式编程中的作用: 一、OpenCV 在单片机嵌入式编程中,虽然单片机的计算能力相对有限…...
【毕业论文+源码】基于ASP+NET的人事管理系统
引言 人事管理系统是针对企业内部人事管理设计,分角色实现对公司部门及各部门员工的增、删、改、查以及对员工考勤的管理。 编写目的: 在系统需求分析的基础上,对需求分析中产生的功能模块进行过程描述,设计功能模块的内部细节&…...
计算机毕业设计 校园志愿者管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
速通LLaMA2:《Llama 2: Open Foundation and Fine-Tuned Chat Models》全文解读
文章目录 概览LLaMA和LLaMA2的区别AbstractIntroductionPretrainingFine-tuning1. 概括2、Supervised Fine-Tuning(SFT)3、⭐Reinforcement Learning with Human Feedback(RLHF)🔺总览Training Objectives:…...
如何使用VM中win10搭建Hfish蜜罐(危险感知平台)。从下载到部署详细教程
得而不惜就该死。 -----古月方源 引言:最近跟一个老师做东西,叫我搞清楚蜜罐的搭建和一些底层逻辑,所以记录一下。 一、实验准备 (一)win10虚拟机 (若有需要可以后台私信) (二&…...
Rust: AES 加密算法库
在Rust中,进行AES加密通常会用到一些现有的库,因为Rust标准库中并不直接提供AES加密的API。一个非常流行的库是crypto-box或者更广泛使用的ring库,但ring库由于依赖问题有时可能难以编译,另一个常用的库是cryptography的Rust绑定&…...
计算机网络34——Windows内存管理
1、计算机体系结构 2、内存管理 分为连续分配管理和非连续分配管理 在块内存在的未使用空间叫内部碎片,在块外存在的未使用空间叫外部碎片 固定分区分配可能出现内部碎片,动态分区分配可能出现外部碎片 3、逻辑地址和实际地址的互相转换 4、缺页中断 …...
Redisson 总结
1. 基础使用 1.1 引入依赖 <dependencies><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId></dependency> </dependencies>包含的依赖如下 1.2 配置文件 其实默认主机就…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
