当前位置: 首页 > news >正文

rtthread学习笔记系列(4/5/6/7/15/16)

文章目录

  • 4. 杂项
    • 4.1 检查是否否是2的幂
  • 5. 预编译命令
    • void类型和rt_noreturn类型的区别
  • 6.map文件分析
  • 7.汇编.s文件
    • 7.1 汇编指令
      • 7.1.1 BX
      • 7.1.2 LR链接寄存器
      • 7.1.4 []的作用
      • 7.1.4 简单的指令
    • 7.2 MSR
    • 7.3 PRIMASK寄存器
    • 7.4.中断启用禁用
    • 7.3 HardFault_Handler
  • 15 ARM指针寄存器
  • 16 IDLE线程
    • 16.1 defunct流程

https://github.com/wdfk-prog/RT-Thread-Study

4. 杂项

4.1 检查是否否是2的幂

  • 检查sz_blk是否是2的幂。原理如下:

如果一个数是2的幂,那么它的二进制表示中只有一个位是1,其余都是0。例如,2(10),4(100),8(1000)等。
当我们从这个数中减去1时,所有从最右边的1开始到最左边的所有位都会翻转。例如,4(100)减去1变成3(011)。
因此,如果一个数是2的幂,那么这个数与它自己减去1的结果进行位与运算,会得到0。因为没有位同时在两个数中都是1。
反之,如果一个数不是2的幂,那么它至少有一个位不是1,这样减去1之后,至少有一个位在两个数中都是1,位与运算的结果不为0。
这个技巧在编程中经常被用来快速检查一个数是否是2的幂,因为它比循环或递归方法更高效。

#define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)

5. 预编译命令


#define __RT_STRINGIFY(x...)        #x#define RT_STRINGIFY(x...)          __RT_STRINGIFY(x)#define rt_section(x)               __attribute__((section(x)))#define rt_used                     __attribute__((used))#define rt_align(n)                 __attribute__((aligned(n)))#define rt_weak                     __attribute__((weak))#define rt_typeof                   __typeof__#define rt_noreturn                 __attribute__ ((noreturn))#define rt_inline                   static __inline#define rt_always_inline            static inline __attribute__((always_inline))

-__RT_STRINGIFY(x...)RT_STRINGIFY(x...):这两个宏用于将参数转换为字符串。__RT_STRINGIFY直接将参数转换为字符串,而 RT_STRINGIFY则通过 __RT_STRINGIFY间接完成转换,以确保参数先被宏展开再转换为字符串。

-rt_section(x):这个宏用于将特定的函数或变量放入指定的段(section)中。

-rt_noreturn:这个宏用于指示函数不会返回。这对于像 exit()abort()这样的函数很有用。

rt_noreturn 是一个函数属性,用于告诉编译器这个函数不会返回到调用者。这个属性可以帮助编译器进行优化。

在C语言中,大多数函数在完成它们的工作后都会返回到调用者。然而,有些函数,如 exit()abort(),在被调用后不会返回。这是因为它们会终止程序的执行,或者跳转到其他的执行流程,而不是返回到原来的位置。当编译器看到一个函数被声明为 noreturn,它就知道这个函数不会返回到调用者。这样,编译器就可以省略一些针对函数返回的代码生成和优化。例如,编译器可能不需要保存寄存器的值,或者不需要在函数调用后生成一些可能永远不会执行的代码。

void类型和rt_noreturn类型的区别

void类型的函数和带有 rt_noreturn属性的函数之间的主要区别在于它们的行为,而不仅仅是它们的返回值。

void类型的函数确实没有返回值,但这并不意味着它们不会返回到调用者。当 void函数完成其工作后,控制权会返回到调用该函数的代码。

然而,带有 rt_noreturn属性的函数永远不会返回到调用者。这意味着一旦调用了这样的函数,程序的控制流就不会回到原来的位置。这对于像 exit()abort()这样的函数来说是非常有用的,因为这些函数在被调用后会终止程序的执行,或者跳转到其他的执行流程。

所以,rt_noreturn并不是关于函数的返回值的,而是关于函数是否会返回到调用者。这个属性可以帮助编译器进行更好的优化,因为编译器知道一旦调用了 rt_noreturn函数,就不需要生成任何后续的代码。希望这个解释对你有所帮助!

6.map文件分析


Image$$ER_IROM1$$Base                    0x90000000   Number         0  anon$$obj.o ABSOLUTE__Vectors                                0x90000000   Data           4  startup_stm32h750xx.o(RESET)__Vectors_End                            0x90000298   Data           0  startup_stm32h750xx.o(RESET)__main                                   0x90000299   Thumb Code     0  entry.o(.ARM.Collect$$$$00000000)_main_stk                                0x90000299   Thumb Code     0  entry2.o(.ARM.Collect$$$$00000001)_main_scatterload                        0x9000029d   Thumb Code     0  entry5.o(.ARM.Collect$$$$00000004)__main_after_scatterload                 0x900002a1   Thumb Code     0  entry5.o(.ARM.Collect$$$$00000004)_main_clock                              0x900002a1   Thumb Code     0  entry7b.o(.ARM.Collect$$$$00000008)_main_cpp_init                           0x900002a1   Thumb Code     0  entry8b.o(.ARM.Collect$$$$0000000A)_main_init                               0x900002a1   Thumb Code     0  entry9a.o(.ARM.Collect$$$$0000000B)__rt_final_cpp                           0x900002a9   Thumb Code     0  entry10a.o(.ARM.Collect$$$$0000000D)__rt_final_exit                          0x900002a9   Thumb Code     0  entry11a.o(.ARM.Collect$$$$0000000F)rt_hw_interrupt_disable                  0x900002ad   Thumb Code     8  context_rvds.o(.text)rt_hw_interrupt_enable                   0x900002b5   Thumb Code     6  context_rvds.o(.text)rt_hw_context_switch                     0x900002bb   Thumb Code    32  context_rvds.o(.text)rt_hw_context_switch_interrupt           0x900002bb   Thumb Code     0  context_rvds.o(.text)PendSV_Handler                           0x900002db   Thumb Code   108  context_rvds.o(.text)rt_hw_context_switch_to                  0x90000347   Thumb Code    76  context_rvds.o(.text)rt_hw_interrupt_thread_switch            0x90000393   Thumb Code     2  context_rvds.o(.text)HardFault_Handler                        0x90000395   Thumb Code    56  context_rvds.o(.text)MemManage_Handler                        0x90000395   Thumb Code     0  context_rvds.o(.text)rt_memcpy                                0x900003e9   Thumb Code     0  rt_memcpy_rvds.o(.text)Reset_Handler                            0x9000060d   Thumb Code     8  startup_stm32h750xx.o(.text)
  1. Reset_Handler 根据链接脚本设置 ENTRY(Reset_Handler);应为RAM首地址位置;实际并不是

原因:

  • 在汇编启动文件中,首先设置了向量表,再设置复位函数

; Vector Table Mapped to Address 0 at ResetAREA    RESET, DATA, READONLYEXPORT  __VectorsEXPORT  __Vectors_EndEXPORT  __Vectors_Size__Vectors       DCD     __initial_sp                      ; Top of StackDCD     Reset_Handler                     ; Reset Handler

-Reset_Handler 编写中调用 SystemInit__main


Reset_Handler    PROCEXPORT  Reset_Handler                    [WEAK]IMPORT  SystemInitIMPORT  __mainLDR     R0, =SystemInitBLX     R0LDR     R0, =__mainBX      R0ENDP

-__main中执行rtt初始化:https://www.rt-thread.org/document/api/group___system_init.html#details

7.汇编.s文件

https://zhuanlan.zhihu.com/p/98888285

7.1 汇编指令

7.1.1 BX

  • BX指令:在ARM汇编语言中,BX指令用于跳转到指令中所指定的目标地址。这个目标地址可以是ARM指令,也可以是Thumb指令。BX指令的格式为:BX {条件} 目标地址。这个指令的特点是它可以改变处理器的状态,从ARM状态切换到Thumb状态,或者从Thumb状态切换到ARM状态。这种状态切换的功能使得BX指令在实现子程序调用和处理器工作状态切换时非常有用。

7.1.2 LR链接寄存器

  • LR链接寄存器:在ARM架构中,链接寄存器(Link Register,简称LR)通常用于存储子程序返回地址。当执行BL(带返回的跳转指令)或BLX(带返回和状态切换的跳转指令)时,处理器会将下一条指令的地址保存到LR中。然后,当子程序执行完毕后,可以通过将LR的内容加载到程序计数器(PC)中,从而返回到调用者。这种机制使得子程序的调用和返回变得非常方便和高效。

  • 在用户模式下,LR(或R14)用作链接寄存器,用于存储子程序调用时的返回地址。如果返回地址存储在堆栈上,它也可以用作通用寄存器。

    在异常处理模式中,LR 保存异常的返回地址,或者如果在异常内执行子例程调用,则保存子例程返回地址。如果返回地址存储在堆栈中,LR 可以用作通用寄存器。

7.1.4 []的作用

  • 在这段ARM汇编代码中,LDR r3, [r2] 是一条加载指令。这条指令的作用是从内存中加载数据。

  • r3 和 r2 是寄存器,它们是CPU中用于临时存储数据的小存储区。在这个上下文中,r3 和 r2 只是寄存器的名称,它们没有特殊的含义,只是用于标识这些寄存器。

    [r2] 的含义是:使用 r2 寄存器中的值作为内存地址,从该地址加载数据。[] 的作用是表示间接寻址,也就是说,我们不是直接使用 r2 的值,而是使用 r2 中的值作为一个内存地址,从这个地址中获取数据。

    所以,LDR r3, [r2] 的整体含义是:从内存中的 r2 所指向的地址加载数据,然后将这些数据存储到 r3 寄存器中。这就是这条指令的作用。

7.1.4 简单的指令

  • LDR: 将地址加载到寄存器中。
  • CMP: 比较两个操作数的值。
  • BEQ

7.2 MSR

  • MSR指令[1][2][3][4]:在ARM汇编语言中,MSR(Move to Status Register)指令用于将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。MSR指令通常用于恢复或改变程序状态寄存器的内容。例如,当需要修改状态寄存器的内容时,可以通过“读取-修改-写回”指令序列完成。这种操作通常用于切换处理器模式、或者允许/禁止IRQ/FIQ中断等。

7.3 PRIMASK寄存器

  • PRIMASK寄存器[5][6][7]:在ARM Cortex-M处理器中,PRIMASK寄存器用于控制中断的优先级,允许屏蔽(禁止)特定优先级的中断。PRIMASK寄存器是一个单比特(bit)的寄存器,只有两个有效的取值:0和1。当PRIMASK寄存器的值为0时,表示所有中断都可以触发。当PRIMASK寄存器的值为1时,会禁止所有可屏蔽的中断。这意味着通过设置 PRIMASK 寄存器为 1,可以禁用所有中断,从而实现临界区的保护或者实现禁止中断的功能。

7.4.中断启用禁用


/** rt_base_t rt_hw_interrupt_disable();*/.global rt_hw_interrupt_disable.type rt_hw_interrupt_disable, %functionrt_hw_interrupt_disable://将PRIMASK写入RO寄存器MRS     r0, PRIMASK//设置CPSID为I,用于禁用中断CPSID   IBX      LR/** void rt_hw_interrupt_enable(rt_base_t level);*/.global rt_hw_interrupt_enable.type rt_hw_interrupt_enable, %functionrt_hw_interrupt_enable://从RO取回PRIMASKMSR     PRIMASK, r0BX      LR
  • 由于将PRIMASK的值暂存在r0中,执行临界段代码时r0值会不会改变?

https://club.rt-thread.org/ask/question/d5156cdf3abb63a1.html

7.3 HardFault_Handler


.global HardFault_Handler.type HardFault_Handler, %functionHardFault_Handler:/* 获取当前上下文 */MRS     r0, msp                 /* 从处理程序获取故障上下文 */TST     lr, #0x04               /* 如果!EXC_RETURN[2] */BEQ     _get_sp_doneMRS     r0, psp                 /* 从线程获取故障上下文 */_get_sp_done:STMFD   r0!, {r4 - r11}         /* 压入r4 - r11寄存器 */#if defined (__VFP_FP__) && !defined(__SOFTFP__)STMFD   r0!, {lr}               /* 压入标志的占位符 */#endifSTMFD   r0!, {lr}               /* 压入exec_return寄存器 */TST     lr, #0x04               /* 如果!EXC_RETURN[2] */BEQ     _update_mspMSR     psp, r0                 /* 更新堆栈指针到PSP */B       _update_done_update_msp:MSR     msp, r0                 /* 更新堆栈指针到MSP */_update_done:PUSH    {LR}BL      rt_hw_hard_fault_exception  /* 调用硬件故障异常处理函数 */POP     {LR}ORR     lr, lr, #0x04BX      lr  /* 返回 */

15 ARM指针寄存器

https://blog.csdn.net/zhuguanlin121/article/details/120883025

-堆栈指针r13 SP:每一种异常模式都有其自己独立的r13,它通常指向异常模式所专用的堆栈,也就是说五种异常模式、非异常模式(用户模式和系统模式),都有各自独立的堆栈,用不同的堆栈指针来索引。这样当ARM进入异常模式的时候,程序就可以把一般通用寄存器压入堆栈,返回时再出栈,保证了各种模式下程序的状态的完整性。

栈顶指针(Stack Pointer)是寄存器页的核心,用以指向系统栈的栈顶位置,某些情况下也可以作为通用寄存器来使用,例如,在 ARM Cortex M 内核中,SP 可以作为 R13 来使用。由于栈是函数式语言的核心,在操作系统中 SP 的地位举足轻重,以 RT-Thread 为例,每个用户任务都有独享的栈,任务的切换几乎就是栈的切换,也就是栈顶指针的切换,我们可以毫不夸张的说:栈顶指针就是每个任务的生命线。

-连接寄存器r14 LR:每种模式下r14都有自身版组,它有两个特殊功能。

(1)保存子程序返回地址。使用BL或BLX时,跳转指令自动把返回地址放入r14中;子程序通过把r14复制到PC来实现返回,通常用下列指令之一:

(2)当异常发生时,异常模式的r14用来保存异常返回地址,将r14如栈可以处理嵌套中断。

(3) LR 本质上相当于一个深度为 1 的硬件栈,支持且仅支持 1 级函数调用。

PC 指针(Program Counter)和 LR 指针(Link Return)是寄存器页的核心,用于实现流水线的执

行和分支,详细内容我们在本章的开头已经详细讨论过。LR 寄存器在某些情况下也可以作为通用寄存

器来使用,例如,在 ARM Cortex M 内核中,LR 可以作为 R14 来使用。

-程序计数器r15 PC:PC是有读写限制的。当没有超过读取限制的时候,读取的值是指令的地址加上8个字节,由于ARM指令总是以字对齐的,故bit[1:0]总是00。当用str或stm存储PC的时候,偏移量有可能是8或12等其它值。在V3及以下版本中,写入bit[1:0]的值将被忽略,而在V4及以上版本写入r15的bit[1:0]必须为00,否则后果不可预测。

IF 阶段从什么地址读取指令是由 PC 指针控制的,修改其值就可以实现程序的分支。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

16 IDLE线程

  • cleanup 会在线程退出时,被空闲线程回调一次以执行用户设置的清理现场等工作。

16.1 defunct流程

  1. rt_thread_defunct_enqueue 将退出线程和分离线程插入到defunct链表中
  2. IDLE线程会在空闲时,执行defunct链表中的线程,将线程节点从链表中移除
  3. 从对象容器中移除线程对象
  4. 执行线程清除函数,释放线程控制块

相关文章:

rtthread学习笔记系列(4/5/6/7/15/16)

文章目录 4. 杂项4.1 检查是否否是2的幂 5. 预编译命令void类型和rt_noreturn类型的区别 6.map文件分析7.汇编.s文件7.1 汇编指令7.1.1 BX7.1.2 LR链接寄存器7.1.4 []的作用7.1.4 简单的指令 7.2 MSR7.3 PRIMASK寄存器7.4.中断启用禁用7.3 HardFault_Handler 15 ARM指针寄存器1…...

【拒绝算法PUA】3065. 超过阈值的最少操作数 I

系列文章目录 【拒绝算法PUA】0x00-位运算 【拒绝算法PUA】0x01- 区间比较技巧 【拒绝算法PUA】0x02- 区间合并技巧 【拒绝算法PUA】0x03 - LeetCode 排序类型刷题 【拒绝算法PUA】LeetCode每日一题系列刷题汇总-2025年持续刷新中 C刷题技巧总结: [温习C/C]0x04 刷…...

今日总结 2025-01-14

学习目标 掌握运用 VSCode 开发 uni - app 的配置流程。学会将配置完善的项目作为模板上传至 Git,实现复用。项目启动 创建项目:借助 Vue - Cli 方式创建项目,推荐从国内地址 https://gitee.com/dcloud/uni - preset - vue/repository/archiv…...

关于扫描模型 拓扑 和 传递贴图工作流笔记

关于MAYA拓扑和传递贴图的操作笔记 一、拓扑低模: 1、拓扑工作区位置: 1、准备出 目标 高模。 (高模的状态如上 ↑ )。 2、打开顶点吸附,和建模工具区,选择四边形绘制. 2、拓扑快捷键使…...

C#知识|泛型Generic概念与方法

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 关于泛型在前面学习记录过 《泛型集合List相关方法》、《Dictionary泛型集合的使用总结》&#xff1b; 其中泛型集合 List<T>、Dictionary<k,v>所在的命名空间为&#xff1a;System.Collection.Generic…...

centos 8 中安装Docker

注&#xff1a;本次样式安装使用的是centos8 操作系统。 1、镜像下载 具体的镜像下载地址各位可以去官网下载&#xff0c;选择适合你们的下载即可&#xff01; 1、CentOS官方下载地址&#xff1a;https://vault.centos.org/ 2、阿里云开源镜像站下载&#xff1a;centos安装包…...

vscode vue 自动格式化

vscode vue 自动格式化 安装Prettier和Vetur插件 选择设置&#xff0c;并且转到编辑文件。增加如下内容。 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","[vue]": {"editor.defaultFor…...

Webpack 5 混淆插件terser-webpack-plugin生命周期作用时机和使用注意事项

参考案例代码 海南酷森科技有限公司/webpack-simple-demo Terser&#xff08;简要的/简短的&#xff09; 混淆依据 混淆是发生在代码已经 bundle 之后的事情 变量或者函数在被引用或赋值时才能被混淆 孤立的函数或者变量可能会被移除&#xff0c;但不会被混淆&#xff0c;要…...

MQTT(Message Queuing Telemetry Transport)协议

文章目录 一、MQTT 的原理1. 通信模型2. 核心概念3. 工作流程 二、MQTT 的优势1. 轻量级2. 异步通信3. 可靠性4. 实时性5. 支持断线重连6. 跨平台支持7. 安全性 三、MQTT 的典型应用场景四、与其他协议的对比 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;…...

【MySQL学习笔记】MySQL存储过程

存储过程 1、基础语法2、变量2.1 系统变量2.2 用户自定义变量2.3 局部变量 3、if 流程控制4、参数5、case 流程控制6、循环结构6.1 while 循环6.2 repeat 循环6.3 loop 循环 7、游标 存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合&#xff0c;调用存储过程可以…...

Vue2+OpenLayers实现折线绘制、起始点标记和轨迹打点的完整功能(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、代码实现 3.1、HTML页面 3.2、初始化变量 3.3、创建起始点位 3.4、遍历轨迹点 3.5、画折线 3.6、初始化弹窗信息 3.7、初始化地图上标点的点击事件 3.8、完整代码 四、Gitee源码 一、案例截图 二、安装OpenLayers库 n…...

基于Spring Boot的城市垃圾分类管理系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

linux: 文本编辑器vim

文本编辑器 vi的工作模式 (vim和vi一致) 进入vim的方法 方法一:输入 vim 文件名 此时左下角有 "文件名" 文件行数,字符数量 方法一: 输入 vim 新文件名 此时新建了一个文件并进入vim,左下角有 "文件名"[New File] 灰色的长方形就是光标,输入文字,左下…...

Eclipse Debug 调试

关于Eclipse的Debug调试功能&#xff0c;有几点重要的信息可以分享。 Debug的启动方式&#xff1a;Eclipse提供了多种启动程序调试的方式&#xff0c;包括通过菜单(Run –> Debug)、点击“绿色臭虫”图标、右键选择Debug As以及使用快捷键(F11)【0†source】。 调试中最常用…...

vue3+ts的<img :src=““ >写法

vue3ts的<img :src"" >写法<img :src"datasetImage" alt"数据分布示意图" /><script setup lang"ts">const datasetImage ref();datasetImage.value new URL(../../../assets/images/login-background.jpg, impo…...

《心血管成像的深度学习》论文精读

Deep Learning for Cardiovascular Imaging 重要性&#xff1a;由深度学习 (DL) 的进步推动的人工智能 (AI) 有可能重塑心血管成像 (CVI) 领域。虽然 CVI 的 DL 仍处于起步阶段&#xff0c;但研究正在加速&#xff0c;以帮助获取、处理和/或解释各种模式下的 CVI&#xff0c;其…...

RDP、VNC、SSH 三种登陆方式的差异解析

一、引言 在计算机系统管理和远程访问的领域中&#xff0c;RDP&#xff08;Remote Desktop Protocol&#xff0c;远程桌面协议&#xff09;、VNC&#xff08;Virtual Network Computing&#xff0c;虚拟网络计算&#xff09;和 SSH&#xff08;Secure Shell&#xff09;是三种广…...

3d 可视化库 vister部署笔记

目录 vister 开源地址: python版本: 在python3.10以上版本安装 viser, 测试ok的案例: 立方体mesh选中 SMPL-X可视化 ok 推理代码: vister 开源地址: GitHub - nerfstudio-project/viser: Web-based 3D visualization + Python python版本: 在python3.10以上版本…...

操作系统八股文学习笔记

总结来自于javaguide,本文章仅供个人学习复习 javaguide操作系统八股 文章目录 操作系统基础什么是操作系统?操作系统主要有哪些功能?常见的操作系统有哪些?用户态和内核态为什么要有用户态和内核态?只有一个内核态不行嘛?用户态和内核态是如何切换的?系统调用 进程和线程…...

k8s基础(6)—Kubernetes-存储

Kubernetes-存储概述 k8s的持久券简介 Kubernetes的持久卷&#xff08;PersistentVolume, PV&#xff09;和持久卷声明&#xff08;PersistentVolumeClaim, PVC&#xff09;为用户在Kubernetes中使用卷提供了抽象。PV是集群中的一块存储&#xff0c;PVC是对这部分存储的请求。…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...