UCOS-III 系统移植

1. 移植前准备

1.1 源码下载

UCOS-III Kernel Source   https://github.com/weston-embedded/uC-OS3.git

Micriμm CPU Source : https://github.com/weston-embedded/uC-CPU.git

Micriμm Lib Source: https://github.com/weston-embedded/uC-LIB.git 

1.2. 源码介绍

1.2.1 源码组织结构图

1.2.2 源码简介

1)应用层模块

2)BSP 与板子相关的BSP模块 (需要移植) 主要为系统时钟、时间戳相关API

3)µC-OS3/Source 内核源码 与CPU无关的模块

4)µC-OS3/Ports 与CPU相关的模块 (需要移植 )

5)uC-CPU 与特定平台CPU相关的模块(由uc-cpu提供)

6)uC-LIB 与CPU无关的库函数模块

7) µC-OS3/Cfg 配置头文件(需要配置的部分)

调用关系: UC/OS-III/Ports-->uC-CPU --> CPU_BSP

2. 移植配置列表

1)移植 uC-OS3 CPU 相关部分: os_cpu.h, os_cpu_a.asm,  os_cpu_c.c

2)移植 uC/CPU 相关部分: cpu_a.asm , cpu_c.c

3)移植板级支持包(BSP) 部分: bsp.c ,bsp.h

4)配置UC/OS-III 以下部分:

 µC/OS-III 功能配置 (os_cfg.h)

µC/OS-III 堆栈、系统任务和其他数据大小 (os_cfg_app.h)

µC/OS-III 数据类型 (os_type.h)

具体配置参考: http://t.csdnimg.cn/GNZcY

3. 移植 uC-OS3 CPU

3.1 找到MCU使用的CPU架构

以GD32F303为例,翻阅其手册,查找CPU对应的架构信息如下:

3.2 找到CPU架构对应的文件

        在uC-OS3/Ports目录下查找ARMv7-M,找到 ARMv7-M路径: ARM-Cortex-M/ARMv7-M

3.3 开发编译环境列表

ARM-Cortex-M/ARMv7-M 目录下有4个文件夹,分别对应不同的编译器

  • ARM: ARM公司提供的编译器,如Keil MDK开发环境。
  • CCS: TI的Code Composer Studio编译器。
  • GNU: GNU工具链(如GCC)
  • IAR: IAR 开发环境

3.4 使用Keil MDK编译器

uC-OS3/Template/bsp_os_dt.c , 有以下系统时钟相关接口需要移植:

BSP_OS_TickInit()     //初始化系统时钟滴答定时器     
BSP_OS_TickISR()      //系统时钟滴答中断服务程序

uC-OS3/Ports/Template目录里的os_cpu.h ,有以下上下文切换相关接口需要实现:   

void  OSCtxSw              (void);  // 任务级上下文切换,触发PendSV异常
void  OSIntCtxSw           (void);  // 中断上下文中进行任务切换,触发PendSV异常
void  OSStartHighRdy       (void);  // 启动最高优先级的就绪任务
void  OS_CPU_PendSVHandler (void);  // PendSV 异常处理程序,用切换当前任务的上下文到下一个准备就绪的任务 

查看MCU的CPU架构及所选开发环境对应的文件

uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_c.c

uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/ARM/os_cpu_a.asm

已实现上述的所有接口,如果原厂没有实现的接口,则需要实现以上接口

3.4.1 BSP_OS_TickInit 接口实现

此函数接口用于初始化系统滴答定时器,设置操作系统时钟中断,该函数必须在 OSStart() 调用之后,并且在处理器初始化完成后调用。

优先级设置需要考虑系统中其他中断的优先级配置,确保实时操作系统的滴答计时器中断能够按期触发。

以下是伪代码描述:

void BSP_OS_TickInit(CPU_INT32U freq) {Install the interrupt vector for the timer used to generate tick interrupts; // 安装定时器中断向量Configure the timer to generate interrupts at 'freq' Hz; // 配置定时器以产生指定频率的中断Enable timer interrupts; // 启用定时器中断
}

以下是ARM-Cortex-M/ARMv7-M/os_cpu_c.c已实现的接口:

voidOS_CPU_SysTickInit(CPU_INT32U  cnts)
{CPU_INT32U  prio;CPU_INT32U  basepri;// 设置 BASEPRI 边界basepri = (CPU_INT32U)(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));CPU_REG_SYST_RVR = cnts - 1u;  // 设置重载寄存器// 设置 SysTick 处理程序的优先级prio = CPU_REG_SCB_SHPRI3;prio &= 0x00FFFFFFu;prio |= (basepri << 24u);CPU_REG_SCB_SHPRI3 = prio;// 启用计时器CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_CLKSOURCE | CPU_REG_SYST_CSR_ENABLE;// 启用计时器中断CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_TICKINT;}

3.4.2 BSP_OS_TickISR 接口实现

此接口函数用于处理系统时钟滴答(SysTick)中断

以下是该函数的伪代码描述:

BSP_OS_TickISR:OS_CTX_SAVE                ; 保存当前任务的上下文Disable Interrupts         ; 禁用中断OSIntNestingCtr++          ; 增加中断嵌套计数器if (OSIntNestingCtr == 1) {OSTCBCurPtr->StkPtr = SP ; 如果这是第一个中断,保存任务堆栈指针}Clear tick interrupt       ; 清除滴答中断标志OSTimeTick()               ; 调用OSTimeTick,通知发生了一个滴答OSIntExit()                ; 通知µC/OS-III中断处理结束OS_CTX_RESTORE             ; 恢复任务的上下文Return from Interrupt/Exception ; 返回到被中断的任务

以下是ARM-Cortex-M/ARMv7-M/os_cpu_c.c已实现的接口:

void OS_CPU_SysTickHandler(void)
{CPU_SR_ALLOC();CPU_CRITICAL_ENTER();OSIntEnter();  /* 通知uC/OS-III我们正在进入一个ISR */CPU_CRITICAL_EXIT();OSTimeTick();  /* 调用uC/OS-III的OSTimeTick() */OSIntExit();  /* 通知uC/OS-III我们正在离开ISR */
}

3.4.3 OSCtxSw 接口移植

该函数接口实现任务级上下文切换,以下是该函数的汇编实现伪代码:

                             ; (1) 通过软中断调用OSCtxSw
OSCtxSw:OS_CTX_SAVE              ; (2) 保存当前任务的CPU上下文LDR     R0, =OSTCBCurPtrLDR     R0, [R0]STR     SP, [R0]         ; (3) 将当前任务的堆栈指针保存到其TCBBL      OSTaskSwHookLDR     R0, =OSPrioHighRdyLDR     R0, [R0]STR     R0, =OSPrioCurLDR     R0, =OSTCBHighRdyPtrLDR     R0, [R0]LDR     SP, [R0]         ; (4) 从新任务的TCB中获取堆栈指针OS_CTX_RESTORE           ; (5) 恢复新任务的CPU上下文BX      LR               ; (6) 从中断返回,恢复PC和SR

以下是ARM-Cortex-M/ARMv7-M/ARM/os_cpu_a.asm已实现的接口:

OSCtxSw
OSIntCtxSwLDR     R0, =NVIC_INT_CTRL      ; Trigger the PendSV exception (causes context switch)LDR     R1, =NVIC_PENDSVSETSTR     R1, [R0]BX      LR

3.4.4 OSIntCtxSw 接口移植

此函数用于在中断上下文中进行任务切换,以下为该函数的汇编实现伪代码:

在所有嵌套的ISR结束时由 OSIntExit() 调用
OSIntCtxSw:BL      OSTaskSwHookLDR     R0, =OSPrioHighRdyLDR     R0, [R0]STR     R0, =OSPrioCurLDR     R0, =OSTCBHighRdyPtrLDR     R0, [R0]LDR     SP, [R0]OS_CTX_RESTOREBX      LR

以下是ARM-Cortex-M/ARMv7-M/ARM/os_cpu_a.asm已实现的接口:

OSCtxSw
OSIntCtxSwLDR     R0, =NVIC_INT_CTRL      ; Trigger the PendSV exception (causes context switch)LDR     R1, =NVIC_PENDSVSETSTR     R1, [R0]BX      LR

3.4.5 OSStartHighRdy 接口移植

此函数用于启动最高优先级的就绪任务,以下是该函数的汇编实现伪代码:

OSStartHighRdy:BL      OSTaskSwHook                                      ; 调用任务切换钩子函数LDR     R0, =OSTCBHighRdyPtr                              ; 获取最高优先级任务的TCB指针LDR     R0, [R0]LDR     SP, [R0]                                          ; (1) 获取最高优先级任务的堆栈指针OS_CTX_RESTORE                                            ; (2) 恢复新任务的CPU上下文BX      LR                                                ; (3) 从中断返回,恢复PC和SR

以下是ARM-Cortex-M/ARMv7-M/ARM/os_cpu_a.asm已实现的接口:

OSStartHighRdyCPSID   I                                                   ; Prevent interruption during context switchMOV32   R0, NVIC_SYSPRI14                                   ; Set the PendSV exception priorityMOV32   R1, NVIC_PENDSV_PRISTRB    R1, [R0]MOVS    R0, #0                                              ; Set the PSP to 0 for initial context switch callMSR     PSP, R0MOV32   R0, OS_CPU_ExceptStkBase                            ; Initialize the MSP to the OS_CPU_ExceptStkBaseLDR     R1, [R0]MSR     MSP, R1BL      OSTaskSwHook                                        ; Call OSTaskSwHook() for FPU Push & PopMOV32   R0, OSPrioCur                                       ; OSPrioCur   = OSPrioHighRdy;MOV32   R1, OSPrioHighRdyLDRB    R2, [R1]STRB    R2, [R0]MOV32   R0, OSTCBCurPtr                                     ; OSTCBCurPtr = OSTCBHighRdyPtr;MOV32   R1, OSTCBHighRdyPtrLDR     R2, [R1]STR     R2, [R0]LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;MSR     PSP, R0                                             ; Load PSP with new process SPMRS     R0, CONTROLORR     R0, R0, #2BIC     R0, R0, #4                                          ; Clear FPCA bit to indicate FPU is not in useMSR     CONTROL, R0ISB                                                         ; Sync instruction streamLDMFD    SP!, {R4-R11, LR}                                  ; Restore r4-11, lr from new process stackLDMFD    SP!, {R0-R3}                                       ; Restore r0, r3LDMFD    SP!, {R12, LR}                                     ; Load R12 and LRLDMFD    SP!, {R1, R2}                                      ; Load PC and discard xPSRCPSIE    IBX       R1

3.4.6 OS_CPU_PendSVHandler 接口实现

此接口函数用于引发上下文切换,以下是该函数的实现步骤和详细代码

获取进程堆栈指针:将进程堆栈指针(PSP)保存到R0

保存剩余寄存器:将寄存器R4-R11和R14保存到进程堆栈

保存进程堆栈指针:将进程堆栈指针保存到当前任务的TCB中

调用OSTaskSwHook:执行任务切换钩子函数

更新当前任务和准备就绪任务:更新当前任务的优先级和TCB指针

获取新任务堆栈指针:从准备就绪任务的TCB中获取堆栈指针,并将其加载到PSP中

恢复寄存器:从新任务堆栈恢复寄存器R4-R11和R14

恢复上下文:从异常返回,恢复剩余上下文

以下是ARM-Cortex-M/ARMv7-M/ARM/os_cpu_a.asm已实现的接口:

OS_CPU_PendSVHandler:CPSID   I                               ; 禁止中断MOV32   R2, OS_KA_BASEPRI_Boundary      ; 设置BASEPRI优先级LDR     R1, [R2]MSR     BASEPRI, R1DSBISBCPSIE   IMRS     R0, PSP                         ; 获取进程堆栈指针IF {FPU} != "SoftVFP"TST       R14, #0x10IT        EQVSTMDBEQ  R0!, {S16-S31}            ; 如果任务使用FPU,保存高位FPU寄存器ENDIFSTMFD   R0!, {R4-R11, R14}              ; 保存R4-R11和R14寄存器MOV32   R5, OSTCBCurPtr                 ; 保存当前任务的堆栈指针LDR     R1, [R5]STR     R0, [R1]MOV     R4, LR                          ; 保存LR寄存器值BL      OSTaskSwHook                    ; 调用任务切换钩子函数MOV32   R0, OSPrioCur                   ; 更新当前任务优先级MOV32   R1, OSPrioHighRdyLDRB    R2, [R1]STRB    R2, [R0]MOV32   R1, OSTCBHighRdyPtr             ; 更新当前任务的TCB指针LDR     R2, [R1]STR     R2, [R5]ORR     LR, R4, #0x04                   ; 确保异常返回使用进程堆栈LDR     R0, [R2]                        ; 获取新任务的堆栈指针LDMFD   R0!, {R4-R11, R14}              ; 恢复R4-R11和R14寄存器IF {FPU} != "SoftVFP"TST       R14, #0x10IT        EQVLDMIAEQ  R0!, {S16-S31}            ; 恢复高位FPU寄存器ENDIFMSR     PSP, R0                         ; 加载新的进程堆栈指针MOV32   R2, #0                          ; 恢复BASEPRI优先级CPSID   IMSR     BASEPRI, R2DSBISBCPSIE   IBX      LR                              ; 异常返回,将恢复剩余上下文ALIGNEND

4. 移植 uC/CPU

uC-CPU/BSP/Template/bsp_cpu.c 有以下CPU时间戳相关接口需要实现:

CPU_TS_TmrInit()   //CPU 时间戳计时器初始化
CPU_TS_TmrRd()     //获取当前 CPU 时间戳计时器的计数值 
CPU_TS32_to_uSec() //将时间戳计数转换为微秒
如果启用了 CPU 时间戳或 CPU 中断禁用时间测量功能,必须实现这些接口

uC-CPU/Template/cpu_a.asm 有以下接口需要实现:

CPU_IntDis     ;禁用中断
CPU_IntEn      ;启用中断
CPU_SR_Save    ;保存CPU状态寄存器
CPU_SR_Restore ;恢复CPU状态寄存器
CPU_CntLeadZeros;计数前导零

uC-CPU/ARM-Cortex-M/ARMv7-M/ARM/cpu_a.asm 已实现上述接口

4.1 CPU_TS_TmrInit() 接口移植

该接口是CPU 时间戳计时器初始化函数 , 该计时器用于记录精确的时间戳或测量 CPU 禁用中断的时间。以下是基于GD32F303的实现代码:

void  CPU_TS_TmrInit (void)
{CPU_INT32U  fclk_freq;fclk_freq = BSP_CPU_ClkFreq();BSP_REG_DEM_CR     |= (CPU_INT32U)BSP_BIT_DEM_CR_TRCENA;    /* Enable Cortex-M4's DWT CYCCNT reg.                   */BSP_REG_DWT_CYCCNT  = (CPU_INT32U)0u;BSP_REG_DWT_CR     |= (CPU_INT32U)BSP_BIT_DWT_CR_CYCCNTENA;CPU_TS_TmrFreqSet((CPU_TS_TMR_FREQ)fclk_freq);
}

4.2 CPU_TS_TmrRd 接口移植

该 函数用于获取当前 CPU 时间戳计时器的计数值,以下是基于GD32F303的实现代码:

CPU_TS_TMR  CPU_TS_TmrRd (void)
{CPU_TS_TMR  ts_tmr_cnts;ts_tmr_cnts = (CPU_TS_TMR)BSP_REG_DWT_CYCCNT;return (ts_tmr_cnts);
}

4.3 CPU_TS32_to_uSec 接口移植

该函数用于将时间戳计数转换为微秒,以下是基于GD32F303的实现代码:

CPU_INT64U  CPU_TS32_to_uSec (CPU_TS32  ts_cnts)
{CPU_INT64U  ts_us;CPU_INT64U  fclk_freq;fclk_freq = BSP_CPU_ClkFreq();ts_us     = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);return (ts_us);
}

5. 移植验证

5.1. 构建工程目录

├── app // 应用程序

├── bsp // 板级支持包,包含系统需要移植的接口及硬件相关库文件及接口

        └── gd32f30x

                ├── bsp.c //需要移植的接口

                ├── bsp.h

                ├── gd32f30x_it.c

                ├── gd32f30x_it.h

                ├── gd32f30x_libopt.h

                ├── Library

                ├── mdk-project

├── uC-CFG //把 uC-CPU 及uC-OS3 需要配置的文件集中到此文件夹

├── uC-CPU

├── uC-LIB

└── uC-OS3

5.2  构建Keil工程 

5.3 编译验证

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/42208.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多方SQL计算场景下,如何达成双方共识,确认多方计算作业的安全性

安全多方计算在SQL场景下的限制 随着MPC、隐私计算等概念的流行&#xff0c; 诸多政府机构、金融企业开始考虑参与到多方计算的场景中&#xff0c; 扩展数据的应用价值。 以下面这个场景为例&#xff0c; 银行可能希望获取水电局和税务局的数据&#xff0c;来综合计算得到各…

DolphinScheduler-3.1.9 资源中心实践

前言 目前DolphinScheduler最新的稳定版本是 3.1.9 &#xff0c;基于此做些探索&#xff0c;逐渐深化学习路径&#xff0c;以便于加深理解。 3.2.1 是最新的版本。目前的稳定版本是 3.1.9 基础环境&#xff1a;Hadoop3.3, Java 8, Python3, MacOS14.2.1 一、本地伪分布式安装…

学习笔记——动态路由——IS-IS中间系统到中间系统(开销)

四、IS-IS开销 1、IS-IS 开销简介 在IS-IS协议刚面世时&#xff0c;互联网网络结构还非常简单&#xff0c;因此IS-IS早期的版本中只使用了6bit来描述链路开销&#xff0c;链路开销的取值范围是1-63。一条路由的开销范围只有10bit&#xff0c;取值范围是0-1023。 随着计…

前端实现无缝自动滚动动画

1. 前言: 前端使用HTMLCSS实现一个无缝滚动的列表效果 示例图: 2. 源码 html部分源码: <!--* Author: wangZhiyu <w3209605851163.com>* Date: 2024-07-05 23:33:20* LastEditTime: 2024-07-05 23:49:09* LastEditors: wangZhiyu <w3209605851163.com>* File…

【ubuntu】安装(升级)显卡驱动,黑屏|双屏无法使用问题解决方法

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 ubuntu 安装(升级)显卡驱动&#xff0c;黑屏|双屏无法使用问题解决方法 由于项目需要&#xff0c;对显卡驱动进行升级。升级完就黑屏。。。。&#xff0…

Fast R-CNN(论文阅读)

论文名&#xff1a;Fast R-CNN 论文作者&#xff1a;Ross Girshick 期刊/会议名&#xff1a;ICCV 2015 发表时间&#xff1a;2015-9 ​论文地址&#xff1a;https://arxiv.org/pdf/1504.08083 源码&#xff1a;https://github.com/rbgirshick/fast-rcnn 摘要 这篇论文提出了一…

BAT-致敬精简

什么是bat bat是windows的批处理程序&#xff0c;可以批量完成一些操作&#xff0c;方便快速。 往往我们可以出通过 winR键来打开指令窗口&#xff0c;这里输入的就是bat指令 这里就是bat界面 节约时间就是珍爱生命--你能想象以下2分钟的操作&#xff0c;bat只需要1秒钟 我…

考虑数据库粒度的设计-提升效率

目录 概要 场景 设计思路 小结 概要 公开的资料显示&#xff0c;数据库粒度是&#xff1a;“在数据库领域&#xff0c;特别是数据仓库的设计中&#xff0c;粒度是一个核心概念&#xff0c;它直接影响到数据分析的准确性和存储效率。粒度的设定涉及到数据的详细程度和精度&…

【JVM基础篇】Java的四种垃圾回收算法介绍

文章目录 垃圾回收算法垃圾回收算法的历史和分类垃圾回收算法的评价标准标记清除算法优缺点 复制算法优缺点 标记整理算法&#xff08;标记压缩算法&#xff09;优缺点 分代垃圾回收算法&#xff08;常用&#xff09;JVM参数设置使用Arthas查看内存分区垃圾回收执行流程分代GC算…

【SpringBoot】IDEA查看spring bean的依赖关系

前因&#xff1a;在研究springcloud config组件时&#xff0c;我发现config-server包下的EnvironmentController可以响应客户端的请求&#xff0c;但EnvironmentController并不在启动类所在的包路径下&#xff0c;所以我推测它是作为某个Bean方法在生效&#xff0c;寻找bean的依…

DAY1: 实习前期准备

文章目录 VS Code安装的插件C/CCMakeGitHub CopilotRemote-SSH收获 VS Code 下载链接&#xff1a;https://code.visualstudio.com 安装的插件 C/C 是什么&#xff1a;C/C IntelliSense, debugging, and code browsing. 为什么&#xff1a;初步了解如何在VS Code里使用C输出…

关于小爱同学自定义指令执行

1.前言 之前买了小爱同学音响&#xff0c;一直想让其让我的生活变得更智能&#xff0c;编写一些程序来完成一些自动化任务&#xff0c;但是经过搜索发现&#xff0c;官方开发者平台不能用了&#xff0c;寻找api阶段浪费了我很长时间。最后在github 开源项目发现了俩个比较关键…

13.SQL注入-宽字节

SQL注入-宽字节 含义&#xff1a; MySQL是用的PHP语言&#xff0c;然后PHP有addslashes()等函数&#xff0c;这类函数会自动过滤 ’ ‘’ null 等这些敏感字符&#xff0c;将它们转义成’ ‘’ \null&#xff1b;然后宽字节字符集比如GBK它会自动把两个字节的字符识别为一个汉…

内容营销专家刘鑫炜:网站排名需考虑哪些SEO优化技巧?

网站排名的SEO优化技巧包括&#xff1a; 1. 关键词研究&#xff1a;了解目标受众的搜索关键词&#xff0c;将这些关键词合理地应用在网站的标题、描述、正文和标签中&#xff0c;有助于提高网站排名。 2. 内容优化&#xff1a;创建高质量、有价值的内容&#xff0c;可以吸引搜…

Qt源码解析之QObject

省去大部分virtual和public方法后&#xff0c;Qobject主要剩下以下成员&#xff1a; //qobject.h class Q_CORE_EXPORT Qobject{Q_OBJECTQ_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged)Q_DECLARE_PRIVATE(QObject) public:Q_I…

STM32-OC输出比较和PWM

本内容基于江协科技STM32视频内容&#xff0c;整理而得。 文章目录 1. OC输出比较和PWM1.1 OC输出比较1.2 PWM&#xff08;脉冲宽度调制&#xff09;1.3 输出比较通道&#xff08;高级&#xff09;1.4 输出比较通道&#xff08;通用&#xff09;1.5 输出比较模式1.6 PWM基本结…

MATLAB常用语句总结7

MATLAB总结7&#xff1a;常见错误归纳 本篇专门用于记录一些应试技巧 文章目录 MATLAB总结7&#xff1a;常见错误归纳前言一、一些小定义和小技巧二、蒙塔卡罗求解方法1.函数的定义2.函数引用3.代码量较少的蒙塔卡罗 三、函数引用与多变量四、矩阵引用五、非线性函数&#xff…

14-39 剑和诗人13 - 顶级大模型测试分析和建议

​​​​​ 随着对高级语言功能的需求不断飙升&#xff0c;市场上涌现出大量语言模型&#xff0c;每种模型都拥有独特的优势和功能。然而&#xff0c;驾驭这个错综复杂的生态系统可能是一项艰巨的任务&#xff0c;开发人员和研究人员经常面临选择最适合其特定需求的模型的挑战。…

哈弗架构和冯诺伊曼架构

文章目录 1. 计算机体系结构 2. 哈弗架构&#xff08;Harvard Architecture&#xff09; 3. 改进的哈弗架构 4. 冯诺伊曼架构&#xff08;Von Neumann Architecture&#xff09; 5. 结构对比 1. 计算机体系结构 计算机体系结构是指计算机系统的组织和实现方式&#xff0c…

Python | Leetcode Python题解之第220题存在重复元素III

题目&#xff1a; 题解&#xff1a; class Solution(object):def containsNearbyAlmostDuplicate(self, nums, k, t):from sortedcontainers import SortedSetst SortedSet()left, right 0, 0res 0while right < len(nums):if right - left > k:st.remove(nums[left]…