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

RISCV学习(5)GD32VF103 MCU架构了解

RISCV学习(5)GD32VF103 MCU架构了解

1、芯片内核功能简介

GD32VF103 MCU架构,采用Bumblebee内核,芯来科技(Nuclei System Technology)与台湾晶心科技(Andes Technology)联合开发,由芯来科技(Nuclei System Technology)提供授权以及技术支持等服务。

架构特点:

  • CPU 内核(CPU Core)
    • 2 级变长流水线架构,采用一流的处理器架构设计,实现业界最高的能效比与最低的成本。
    • 简单的动态分支预测器。
    • 指令预取单元,能够按顺序预取两条指令, 从而隐藏指令的访存延迟。
    • 支持机器模式(Machine Mode)和用户模式(User Mode)。
  • 支持指令集架构(ISA, Instruction Set Architecture)
    • Bumblebee内核支持32位的RISC-V指令集架构,支持RV32IMAC指令子集的组合。
    • 硬件支持非对齐(Misalign)的存储器访问操作(Load/Store 指令)
  • 总线接口
    • 支持 32 比特宽的标准 AHB-Lite 系统总线接口,用于访问外部指令和数据。
    • 支持 32 比特宽的指令局部存储器(Instruction Local Memory, ILM)总线接口(支持标准的 AHB-Lite 或 SRAM 接口协议),用于连接私有的指令局部存储器
    • 支持 32 比特宽的数据局部存储器(Data Local Memory, DLM)总线接口(支持标准的 AHB-Lite 或 SRAM 接口协议),用于连接私有的数据局部存储器。
    • 支持 32 比特宽的私有设备总线(Private Peripheral Interface, PPI),支持标准的 APB接口协议,用于连接私有的外设
  • 调试功能
    • 支持标准 JTAG 接口。
    • 支持 RISC-V 调试标准。
    • 支持 4 个硬件断点(Hardware Breakpoints)。
    • 支持成熟的交互式调试工具
  • 低功耗管理
    • 支持 WFI(Wait For Interrupt)与 WFE(Wait For Event)进入休眠模式。
    • 支持两级休眠模式:浅度休眠与深度休眠
  • 内核私有的计时器单元(Machine Timer,简称 TIMER)
    • 64 比特宽的实时计时器,支持产生 RISC-V 标准定义的计时器中断。
  • 增强的内核中断控制器(Enhanced Core Level Interrupt Controller, ECLIC)
    • 支持 RISC-V 标准定义的的软件中断、计时器中断和外部中断。
    • 支持数十个外部中断源,中断源的数目和分配请参见具体 MCU 芯片的数据手册。
    • 支持 16 个中断级别和优先级,支持软件动态可编程修改中断级别和中断优先级的数值。
    • 支持基于中断级别的中断嵌套。
    • 支持快速向量中断处理机制。
    • 支持快速中断咬尾机制。
  • 支持NMI,不可屏蔽中断
    架构图如下图所示:
    在这里插入图片描述
    • ILM 和DLM:指令/数据 局部memory,AHB Lite(AHB的简单版本,高性能/低功耗的嵌入式版本)接口访问,周期基本可达到1 Cycle,相当于ARM 的TCM。
    • 访问SRAM或者外部memory,则需要经过system bus总线,总线周期会高一些,
    • RISCV的版本为 1.1版本,更高级的版本模式等有变化,比如有4个模式等等。

2、芯片指令集

  • RV32 架构: 32 位地址空间,通用寄存器宽度 32 位。
  • I:支持 32 个通用整数寄存器。
  • M: 支持整数乘法与除法指令
  • C:支持编码长度为 16 位的压缩指令,提高代码密度。
  • A:支持原子操作指令。
    按照 RISC-V 架构命名规则,以上指令子集的组合可表示为 RV32IMAC

2.1 指令集举例说明

寻址

  • mv,传送寄存器到寄存器
    mv rd,rs,rs源寄存器送到目标寄存器rd
    在这里插入图片描述

  • lw,内存访问,load word,将32位寄存器加载到目标寄存器,4字节读出
    lw,x15,0x0(x23) --> x15 = [x23+0],x15和x23是寄存器
    在这里插入图片描述

  • lwsp:出栈指令

    lwsp x1,0x8(x2),x1 = [x2+0x8],x2是sp指针,sp+8的值 赋值给x1

  • sw,内存访问,store word,将将32位寄存器写到目标寄存器地址,4字节写入,
    sw,x27,0x0(x23) --> [x23+0] = x27
    在这里插入图片描述

  • swsp:压栈指令
    swsp x1,0x8(x2),[x2+0x8]=x1,x2是sp指针,将x1压栈到sp+8的地址

  • lui,直接传输 将立即数左移12位到目标寄存器
    lui x27,0x20000 —> x27 = 0x20000<<12;
    在这里插入图片描述

  • lbu,load byte unsigned,加载一个无符号数据到目标地址,lb是加载有符号数,会进行扩展
    lbu x27,0x0(x25) —> x27 = [x25 + 0]
    在这里插入图片描述
    在这里插入图片描述

  • sb,store byte,存储一个byte字节。
    sb x27, 0x0(x25)
    在这里插入图片描述

  • sd ,store dword,存储8字节
    在这里插入图片描述

  • ld,双字加载
    在这里插入图片描述

加减乘除法左移 右移指令

  • slli:左移指令
    在这里插入图片描述

  • srli:右移指令
    在这里插入图片描述

  • or:或指令
    在这里插入图片描述

  • addi:加法指令, i代表immediate ,立即数
    addi,x8,x8,0xC9
    在这里插入图片描述

跳转指令

  • j,直接跳转指令,后面直接跟地址
    j 0x080005ZF6
    在这里插入图片描述

  • jalr,带连接的跳转指令,一般和auipc一起用,
    auipc x1,0x1 将x1=x1 +1 <<12,即加上0x1000,4k地址
    jalr x1,-0x5CA(x1),先计算跳转地址,pc = x1- 0x5CA,然后将返回地址保存到x1,x1 =当前pc+4
    在这里插入图片描述

其他指令

  • ret 指令
    在这里插入图片描述

  • mret,异常返回指令
    在这里插入图片描述

  • ebreak
    在这里插入图片描述

  • ecall
    在这里插入图片描述
    来看一段汇编,理解一些基础指令
    在这里插入图片描述
    函数调用,传参数使用 x10 -x17,总共8个参数。

  • 左边第250行代码,函数led_blink函数,参数是test_counter_g。

  • mv x10,x27,将27的数据给了x10,说明x27就是test_counter_g的值,那就看x27的值

  • lw x27,0x0(x22),说明x27的值是通过x22地址读出来的,那就看x22的地址,

  • lui x22,0x20000,addi x22,x22,0x70, x22 = 0x20000+0x70 = 0x20000070 地址,符合地址要求
    在这里插入图片描述

  • 接下来,auipc x1, 0x1 那么 x1 = 080015FC

  • jalr x1,-0x3DA,那么x1 = 0x080045FC - 0x3DA = 0x08001222,就是led_blink 函数的地址

在这里插入图片描述

  • 接着再看上面的代码, lw x15,0x0(x23) , lw x27,0x0(x22) ,加载了x22和x23地址的数据到x15和x27,x22是test_counter_g的地址, x23 的地址是什么呢? 通过上面可以计算其地址
  • lui x23,0x20000,addi x23,x24,0x6C, x23 = 0x20000+0x6c = 0x2000006C 地址,是 current_test_count_g的地址
    在这里插入图片描述
  • 这样就比较好理解,加载了这两个变量的值,就是用来判断是否相等的。
  • beq x15,x27,0x8000632 如果不相等,直接跳走
  • 否则, c.mv x10,x24 ,把x24的值给了x10,说明又有函数调用
  • lui x24,0x40001 , addi x24,x24,-0x800 x24的地址为,x24 = 0x40001000 - 0x800 = 0x40000800,其是一个外设地址,是TIMER3的base地址。
    在这里插入图片描述
  • auipc x1,0x0 , jalr x1,0x4F6(x1) ,x1 = 0x08000612+0x4F6 = 0x08000B08,是timer_counter_read函数的地址,
    在这里插入图片描述
  • 接着是一个打印,刚刚x10 作为函数的返回值,这次作为打印的第三个参数,所以就是x12 寄存器的值,mv x12,x10
  • mv x11,x27 x27是 test_counter_g的值,是第二个参数
  • addi x10,x26,0x350 ,x10 = x26+x350,x26= 08000000,所以x10 = 08000350,字符串的地址
    在这里插入图片描述
  • 最后是一个跳转函数,auipc x1,0x1 jalr x1,-0x580(x1) ,跳转地址= 08001622 - 0x580 = 0x080010A2,则是test_printf的函数。
    在这里插入图片描述

3、芯片特权架构

Bumblebee 内核支持两个特权模式(Privilege Modes):

  • 机器模式(Machine Mode)是必须的模式,该 Privilege Mode 的编码是 0x3。
  • 用户模式(User Mode)是可配置的模式,该 Privilege Mode 的编码是 0x0。

RISCV的CSR 寄存器可以反应内核的状态,不是单个寄存器,是一系列寄存器。

3.1 机器模式(Machine Mode)

Bumblebee 内核有关 Machine Mode 的关键要点如下:

  • 处理器内核被复位后,默认处于 Machine Mode。
  • 在 Machine Mode 下,程序能够访问所有的 CSR 寄存器。
  • 跳转到用户模式。执行mret指令

3.2 用户模式(User Mode)

Bumblebee 内核有关 User Mode 的关键要点如下:

  • 在 User Mode 下只能够访问 User Mode 限定的 CSR 寄存器,
  • 从用户模式到机器模式,通过异常中断

3.3 机器子模式(Machine Sub-Mode)

Bumblebee 内核的 Machine Mode 可能处于四种不同的状态下,将之称之为机器子模式
(Machine Sub-Mode):

  • 正常机器模式(该 Machine Sub-Mode 的编码是 0x0):处理器内核被复位之后,处于此子模式之下。处理器复位后如果不产生异常、 NMI、中断,则一直正常运行于此模式之下。
  • 异常处理模式(该 Machine Sub-Mode 的编码是 0x2):响应异常后处理器内核处于此状态。
  • NMI 处理模式(该 Machine Sub-Mode 的编码是 0x3):响应 NMI 后处理器内核处于此状态。
  • 中断处理模式(该 Machine Sub-Mode 的编码是 0x1):响应中断后处理器内核处于此状态。

处理器内核当前处于的 Machine Sub-Mode 反映在 CSR 寄存器 msubm 的 TYP 域中,因此软件可以通过读取此 CSR 寄存器查看当前处于的 Machine Sub-Mode。
注意: 在 RISC-V 架构中,进入异常、 NMI 或者中断也被统称为 Trap
在这里插入图片描述

3.4 不支持PMP

  • PMP :physical Memory Protection,物理内存保护,即ARM 芯片里面的MPU

4、芯片中断机制

芯片中断主要有外部中断和内部中断,中断跳转模式主要有向量模式与非向量模式。
在这里插入图片描述
具体详情,可以参考笔者这篇文章RISCV学习(4)GD32VF103 MCU芯片学习。

5、芯片异常机制

RISCV的芯片异常机制没有自动保存寄存器,需要用户自身保存。

异常处理的流程如下:均是硬件行为,一个时钟周期内完成。

  • 停止执行当前程序流,转而从 CSR 寄存器 mtvec 定义的 PC 地址开始执行。
  • 更新相关 CSR 寄存器,分别是以下几个寄存器:
    • mcause(Machine Cause Register)
    • mepc(Machine Exception Program Counter)
    • mtval(Machine Trap Value Register )
    • mstatus(Machine Status Register)
  • 更新处理器内核的 Privilege Mode 以及 Machine Sub-Mode。
    在这里插入图片描述
    mtvec :硬件异常处理函数的统一入口,最低64位对齐。
    在这里插入图片描述
    如下图所示:mtvec 为 x080013C3,
  • mtvec ADDR:0异常地址:0x080013C0,而该地址则为trap_entry的地址。
  • mtvec MODE:0x11,则为ECLIC 中断模式
    在这里插入图片描述

在这里插入图片描述
笔者测试的异常代码如下:

if(test_counter_g == 3){current_test_count_g = 0;test_printf("%d\r\n",(test_counter_g/current_test_count_g));}

mepc:保存进入异常之前的PC值,作为异常返回的地址,当然也可以作为分析出错的地址,2字节对齐。
在这里插入图片描述
如下图所述,mepc值为0x080005fa,指令为ebreak,确实会产生异常,可能编译器认为笔者是想进入异常,则编译成了该指令。
在这里插入图片描述在这里插入图片描述
mcause:异常原因寄存器,其值为0x38000003
在这里插入图片描述

  • INTERRUPT:其值为0,表示异常。
  • MPP:其值为3,表示特权模式,0为用户模式
  • MPIE:其值为1,表示允许中断,
  • EXCCODE:0x3,表示断点指令,可以进入异常。
    在这里插入图片描述
    mtval:表示异常的访问地址或者指令编码,笔者这里为0,表示该数据没有意义。

再比如一个例子:机器模式下面直接调用ecall,会触发进入异常。

test_entry:ecallret

在这里插入图片描述
在这里插入图片描述
笔者测试,即使非对齐访问和写入,不会触发异常,依然程序正常进行,待后续研究。

再来一个例子,非法指令

led_blink(test_counter_g);if(current_test_count_g != test_counter_g){test_printf("test_counter_g=%d timer_counter=%d\r\n",test_counter_g,timer_counter_read(TIMER3));test_printf("mcause=0x%x, int num=%d, time=%d\r\n", int_num_g, (int_num_g&0x3FF), rdtime());current_test_count_g = test_counter_g;}

异常编码为2,代表非法指令,pc指针为0800061e,然后mtval记录的指令地址为0xC01026F2,就是这个非法指令的值。
在这里插入图片描述
在这里插入图片描述

6、芯片timer

6.1 系统TIMER

系统timer属于外设,外设的地址由厂商自己定义,没有定义成CSR寄存器。64位的寄存器。

#define TIMER_MSIP 0xFFC
#define TIMER_MSIP_size   0x4
#define TIMER_MTIMECMP 0x8
#define TIMER_MTIMECMP_size 0x8
#define TIMER_MTIME 0x0
#define TIMER_MTIME_size 0x8#define TIMER_CTRL_ADDR           0xd1000000
unsigned int mtime_lo(void)
{return *(volatile unsigned int *)(TIMER_CTRL_ADDR + TIMER_MTIME);
}unsigned int mtime_hi(void)
{return *(volatile unsigned int *)(TIMER_CTRL_ADDR + TIMER_MTIME + 4);
}

寄存器地址如下:
在这里插入图片描述
测试效果如下:主循环打印

test_printf("mtime low=%d, diff=%d\r\n",mtime_lo(), (mtime_lo()-mtime_low_g));
mtime_low_g = mtime_lo();

在这里插入图片描述
timer里面可以软件中断:msip软件中断
msip软件中断 中断号为3,仍然需要设置中断模式以及向量等方式。

#if (INTERRUPT_MODE==INTERRUPT_VECTOR_MODE)__attribute__((interrupt)) void eclic_msip_handler()
#else
void eclic_msip_handler()
#endif
{msip_int_num_g =  read_csr(mcause);msip_int_clear();
}void set_software_int()
{#if (INTERRUPT_MODE == INTERRUPT_VECTOR_MODE) eclic_set_vmode(CLIC_INT_SFT);
#elseeclic_set_nonvmode(CLIC_INT_SFT);
#endifeclic_set_posedge_trig(CLIC_INT_SFT);eclic_irq_enable(CLIC_INT_SFT, 1, 0);
}void msip_int_set()
{*(volatile unsigned int *)(TIMER_CTRL_ADDR + TIMER_MSIP) = 1;
}int msip_int_get()
{return *(volatile unsigned int *)(TIMER_CTRL_ADDR + TIMER_MSIP) ;
}void msip_int_clear()
{*(volatile unsigned int *)(TIMER_CTRL_ADDR + TIMER_MSIP) = 0;
}msip_int_set();
test_printf("set msip int,reg=%d, int num=%d\r\n",msip_int_get(),  (msip_int_num_g&0x3FF));

在这里插入图片描述

6.2 指令周期计数器和指令计数器

mcycle 为:指令周期计数器
instret:指令计数器

这两者均是CSR寄存器。

cycle_start_g = read_csr(mcycle) ;
current_test_count_g = test_counter_g;
test_printf("start=%d end=%d, cycle=%d\r\n", cycle_start_g, read_csr(mcycle), (read_csr(mcycle))-cycle_start_g);cycle_start_g = read_csr(instret) ;
current_test_count_g = test_counter_g;
test_printf("start=%d end=%d, cycle=%d\r\n", cycle_start_g, read_csr(instret), (read_csr(instret))-cycle_start_g);

在这里插入图片描述
指令完成计数器:总共完成了5条指令,
在这里插入图片描述
时钟周期:总共花费5个时钟周期,

在这里插入图片描述

7 附录参考

中断向量号

/* define interrupt number */
typedef enum IRQn
{CLIC_INT_RESERVED        	 = 0,      			/*!< RISC-V reserved		*/CLIC_INT_SFT         		 = 3,				/*!< Software interrupt		*/CLIC_INT_TMR         		 = 7,				/*!< CPU Timer interrupt	*/CLIC_INT_BWEI        		 = 17,				/*!< Bus Error interrupt	*/CLIC_INT_PMOVI       		 = 18,				/*!< Performance Monitor	*//* interruput numbers */WWDGT_IRQn                   = 19,      /*!< window watchDog timer interrupt                          */LVD_IRQn                     = 20,      /*!< LVD through EXTI line detect interrupt                   */TAMPER_IRQn                  = 21,      /*!< tamper through EXTI line detect                          */RTC_IRQn                     = 22,      /*!< RTC alarm interrupt                                      */FMC_IRQn                     = 23,      /*!< FMC interrupt                                            */RCU_CTC_IRQn                 = 24,      /*!< RCU and CTC interrupt                                    */EXTI0_IRQn                   = 25,      /*!< EXTI line 0 interrupts                                   */EXTI1_IRQn                   = 26,      /*!< EXTI line 1 interrupts                                   */EXTI2_IRQn                   = 27,      /*!< EXTI line 2 interrupts                                   */EXTI3_IRQn                   = 28,      /*!< EXTI line 3 interrupts                                   */EXTI4_IRQn                   = 29,     /*!< EXTI line 4 interrupts                                   */DMA0_Channel0_IRQn           = 30,     /*!< DMA0 channel0 interrupt                                  */DMA0_Channel1_IRQn           = 31,     /*!< DMA0 channel1 interrupt                                  */DMA0_Channel2_IRQn           = 32,     /*!< DMA0 channel2 interrupt                                  */DMA0_Channel3_IRQn           = 33,     /*!< DMA0 channel3 interrupt                                  */DMA0_Channel4_IRQn           = 34,     /*!< DMA0 channel4 interrupt                                  */DMA0_Channel5_IRQn           = 35,     /*!< DMA0 channel5 interrupt                                  */DMA0_Channel6_IRQn           = 36,     /*!< DMA0 channel6 interrupt                                  */ADC0_1_IRQn                  = 37,     /*!< ADC0 and ADC1 interrupt                                  */CAN0_TX_IRQn                 = 38,     /*!< CAN0 TX interrupts                                       */CAN0_RX0_IRQn                = 39,     /*!< CAN0 RX0 interrupts                                      */CAN0_RX1_IRQn                = 40,     /*!< CAN0 RX1 interrupts                                      */CAN0_EWMC_IRQn               = 41,     /*!< CAN0 EWMC interrupts                                     */EXTI5_9_IRQn                 = 42,     /*!< EXTI[9:5] interrupts                                     */TIMER0_BRK_IRQn              = 43,     /*!< TIMER0 break interrupts                                  */TIMER0_UP_IRQn               = 44,     /*!< TIMER0 update interrupts                                 */TIMER0_TRG_CMT_IRQn          = 45,     /*!< TIMER0 trigger and commutation interrupts                */TIMER0_Channel_IRQn          = 46,     /*!< TIMER0 channel capture compare interrupts                */TIMER1_IRQn                  = 47,     /*!< TIMER1 interrupt                                         */TIMER2_IRQn                  = 48,     /*!< TIMER2 interrupt                                         */TIMER3_IRQn                  = 49,     /*!< TIMER3 interrupts                                        */I2C0_EV_IRQn                 = 50,     /*!< I2C0 event interrupt                                     */I2C0_ER_IRQn                 = 51,     /*!< I2C0 error interrupt                                     */I2C1_EV_IRQn                 = 52,     /*!< I2C1 event interrupt                                     */I2C1_ER_IRQn                 = 53,     /*!< I2C1 error interrupt                                     */SPI0_IRQn                    = 54,     /*!< SPI0 interrupt                                           */SPI1_IRQn                    = 55,     /*!< SPI1 interrupt                                           */USART0_IRQn                  = 56,     /*!< USART0 interrupt                                         */USART1_IRQn                  = 57,     /*!< USART1 interrupt                                         */USART2_IRQn                  = 58,     /*!< USART2 interrupt                                         */EXTI10_15_IRQn               = 59,     /*!< EXTI[15:10] interrupts                                   */RTC_ALARM_IRQn               = 60,     /*!< RTC alarm interrupt EXTI                                 */USBFS_WKUP_IRQn              = 61,     /*!< USBFS wakeup interrupt                                   */EXMC_IRQn                    = 67,     /*!< EXMC global interrupt                                    */TIMER4_IRQn                  = 69,     /*!< TIMER4 global interrupt                                  */SPI2_IRQn                    = 70,     /*!< SPI2 global interrupt                                    */UART3_IRQn                   = 71,     /*!< UART3 global interrupt                                   */UART4_IRQn                   = 72,     /*!< UART4 global interrupt                                   */TIMER5_IRQn                  = 73,     /*!< TIMER5 global interrupt                                  */TIMER6_IRQn                  = 74,     /*!< TIMER6 global interrupt                                  */DMA1_Channel0_IRQn           = 75,     /*!< DMA1 channel0 global interrupt                           */DMA1_Channel1_IRQn           = 76,     /*!< DMA1 channel1 global interrupt                           */DMA1_Channel2_IRQn           = 77,     /*!< DMA1 channel2 global interrupt                           */DMA1_Channel3_IRQn           = 78,     /*!< DMA1 channel3 global interrupt                           */DMA1_Channel4_IRQn           = 79,     /*!< DMA1 channel3 global interrupt                           */CAN1_TX_IRQn                 = 82,     /*!< CAN1 TX interrupt                                        */CAN1_RX0_IRQn                = 83,     /*!< CAN1 RX0 interrupt                                       */CAN1_RX1_IRQn                = 84,     /*!< CAN1 RX1 interrupt                                       */CAN1_EWMC_IRQn               = 85,     /*!< CAN1 EWMC interrupt                                      */USBFS_IRQn                   = 86,     /*!< USBFS global interrupt                                   */ECLIC_NUM_INTERRUPTS
} IRQn_Type;

相关文章:

RISCV学习(5)GD32VF103 MCU架构了解

RISCV学习&#xff08;5&#xff09;GD32VF103 MCU架构了解 1、芯片内核功能简介 GD32VF103 MCU架构&#xff0c;采用Bumblebee内核&#xff0c;芯来科技&#xff08;Nuclei System Technology&#xff09;与台湾晶心科技&#xff08;Andes Technology&#xff09;联合开发&am…...

IDEA2022.3开启热部署

1、开启IDEA的自动编译 1.1 具体步骤&#xff1a;打开顶部工具栏 File -> Settings -> Build,Execution,Deployment -> Compiler 然后勾选 Build project automatically 。 1.2 打开顶部工具栏 File -> Settings -> Advanced Settings -> Compiler -> 然…...

《算法吞噬幻想乡:GPT-4o引发的艺术平权运动与版权核爆》

一、引言&#xff1a;现象级AI艺术事件的社会回响 GPT - 4o吉卜力风格刷屏现象 在当今数字化浪潮中&#xff0c;GPT - 4o吉卜力风格的作品在网络上掀起了一阵刷屏热潮。吉卜力工作室以其独特的水彩质感、奇幻氛围和孤独美学&#xff0c;在全球范围内拥有大量粉丝。而GPT - 4o强…...

yolov5 源码 +jupyter notebook 笔记 kaggle

YOLOv5 | Kaggle 直接用的githuab的源码&#xff0c;git clone 后output才有文件 直接gitclone他的源码用Vscode看 好久没见过16g了 怎么这么便宜 https://gadgetversus.com/graphics-card/nvidia-tesla-p100-pcie-16gb-vs-nvidia-geforce-rtx-4060/#google_vignette 好的&am…...

聊天室系统:多任务版TCP服务端程序开发详细代码解释

1. 需求 目前我们开发的TCP服务端程序只能服务于一个客户端&#xff0c;如何开发一个多任务版的TCP服务端程序能够服务于多个客户端呢? 完成多任务&#xff0c;可以使用线程&#xff0c;比进程更加节省内存资源。 2. 具体实现步骤 编写一个TCP服务端程序&#xff0c;循环等…...

Python(15)迭代器和生成器

在 Python 编程领域中&#xff0c;迭代器和生成器是两个强大且独特的概念&#xff0c;它们为处理数据序列提供了高效且灵活的方式。这篇博客将结合菜鸟教程内容&#xff0c;通过丰富的代码示例&#xff0c;深入学习 Python3 中的迭代器与生成器知识&#xff0c;方便日后复习回顾…...

无刷空心杯电机及机器人灵巧手的技术解析与发展趋势

一、无刷空心杯电机结构与技术解析 1. 核心结构设计 无刷空心杯电机的核心设计突破在于无铁芯转子与电子换向系统的结合。其结构由以下关键部分构成: 定子组件:采用印刷电路板(PCB)或柔性电路板(FPC)作为绕组载体,通过三维绕线技术形成空心杯状绕组,彻底消除齿槽效应…...

如何修复卡在恢复模式下的 iPhone:简短指南

Apple 建议使用恢复模式作为最后的手段&#xff0c;以便在 iPhone 启动循环或显示 Apple 标志时恢复 iPhone。这是解决持续问题的简单方法&#xff0c;但您很少使用。但是&#xff0c;当您的 iPhone 卡住恢复模式本身时&#xff0c;您会怎么做&#xff1f;虽然 iPhone 卡在这种…...

蒋新松:中国机器人之父

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 蒋新松&#xff1a;中国机器人之父 一、生平简介 1. 早年经历与求学道路 蒋新松出生…...

[Windows] MousePlus 5.5.9

[Windows] MousePlus 链接&#xff1a;https://pan.xunlei.com/s/VOOwKJ281kDaZV5_MpP1COd_A1?pwdn69c# MousePlus是一款轻便小巧的鼠标右键增强工具&#xff0c;使用鼠标右键拖动即可唤醒鼠标轮盘&#xff0c;这个功能界面和quicker的轮盘软件界面一样&#xff0c;操作逻辑…...

BT131-ASEMI无人机专用功率器件BT131

编辑&#xff1a;ll BT131-ASEMI无人机专用功率器件BT131 型号&#xff1a;BT131 品牌&#xff1a;ASEMI 封装&#xff1a;TO-92 批号&#xff1a;最新 引脚数量&#xff1a;3 特性&#xff1a;双向可控硅 工作温度&#xff1a;-40℃~150℃ 在智能化浪潮中&#xff0c…...

ETL架构、数据建模及性能优化实践

ETL&#xff08;Extract, Transform, Load&#xff09;和数据建模是构建高性能数据仓库的核心环节。下面从架构设计、详细设计、数据建模方法和最佳实践等方面系统阐述如何优化性能。 一、ETL架构设计优化 1. 分层架构设计 核心分层&#xff1a; 数据源层&#xff1a;对接O…...

30分钟上架鸿蒙原生应用,即时通信IM UI组件库全面适配HarmonyOS 原

自去年 10 月 8 日鸿蒙5开启公测以来&#xff0c;鸿蒙操作系统不断迭代&#xff0c;生态趋向稳健。当前&#xff0c;支持HarmonyOS操作系统的设备数量已超过 10 亿&#xff0c;上架HarmonyOS 5 应用市场的鸿蒙原生应用和元服务已超过2万个。这无疑为广大开发者提供了丰富的应用…...

【虚幻5蓝图Editor Utility Widget:创建高效模型材质自动匹配和资产管理工具,从3DMax到Unreal和Unity引擎_系列第二篇】

虚幻5蓝图Editor Utility Widget 一、基础框架搭建背景&#xff1a;1. 创建Editor Utility Widget2.根控件选择窗口3.界面功能定位与阶段4.查看继承树5.目标效果 二、模块化设计流程1.材质替换核心流程&#xff1a;2.完整代码如下 三、可视化界面UI布局1. 添加标题栏2. 构建滚动…...

机器学习第三篇 模型评估(交叉验证)

Sklearn:可以做数据预处理、分类、回归、聚类&#xff0c;不能做神经网络。原始的工具包文档&#xff1a;scikit-learn: machine learning in Python — scikit-learn 1.6.1 documentation数据集:使用的是MNIST手写数字识别技术&#xff0c;大小为70000&#xff0c;数据类型为7…...

php数据库连接

前言 最近在学习php&#xff0c;刚好学习到了php连接数据库记录一下 总结 //1、与mysql建立连接$conn mysql_connect("127.0.0.1","root","root");//设置编码mysql_set_charset(utf8);//2、选择要操作的数据库mysql_select_db("xuesheng…...

Android Studio学习记录1

Android Studio打包APK 本文为个人学习记录&#xff0c;仅供参考&#xff0c;如有错误请指出。本文主要记录在Android Studio中开发时遇到的问题和回答。 随着学习的深入&#xff0c;项目完成并通过测试之后免不了需要进入打包环节。这篇文章主要记录一下尝试打包APK的过程。我…...

【JAVA ee初阶】多线程(3)

一、出现线程安全的原因 1.【根本原因】线程的调度执行时随机的&#xff08;抢占式执行&#xff09;->罪魁祸首 2.多个线程同时修改同一个变量 如果是一个线程修改一个变量 或者 多个线程读取同一个变量 或者 多个线程修改不同变量 这些都没事。 3.修改操作不是原子的&a…...

【Java ee初阶】多线程(4)

一、java是怎么做到可重入的 java中&#xff0c;通过synchronized进行加锁&#xff0c;指定一个&#xff08;&#xff09;包含了一个锁对象。&#xff08;锁对象本身是一个啥样的对象&#xff0c;这并不重要&#xff0c;重点关注锁对象是不是同一个对象&#xff09; 后面搭配…...

Day15(贪心算法)——LeetCode121.买卖股票的最佳时机55.跳跃游戏

1 LeetCode121.买卖股票的最佳时机(LeetCode121) 1.1 题目描述 题目描述如下:   示例如下&#xff1a; 1.2 问题分析及解决 要求最大利润&#xff0c;即当天与之前天的价格之差最大值。因此我们可以遍历数组&#xff0c;记录下当前遇到的最小值&#xff0c;然后用当天的价…...

2025汽车制造企业数字化转型路径参考

以应用场景作为切入点&#xff0c;引导相关企业推进数字化深度转型和规模化改造&#xff0c;是目前实践探索出来的一条可行路径。 汽车制造行业是相对集聚的制造业领域&#xff0c;通过搭建“转型场景图谱——转型通用工具——转型路径指引”分析框架&#xff0c;聚焦需求侧共…...

雷池WAF的身份认证 - GitHub

雷池支持通过 GitHub 认证的方式&#xff0c;让用户使用 GitHub 身份安全登录应用或网站。使用此功能需要 GitHub 账号 。 第一步&#xff1a;在 GitHub 创建一个 OAuth 应用 可参阅 GitHub 官方文档&#xff0c;创建一个 GitHub OAuth 应用&#xff0c;并获取应用的 ClientI…...

【Linux】第十二章 安装和更新软件包

目录 1. 什么是RPM&#xff1f; 2. dnf是什么&#xff0c;它和rpm有什么联系和区别&#xff1f; 3. RHEL 中如何做才能启用对第三方存储库的支持&#xff1f; 4. 怎么理解RHEL9中的应用流(Application Streams)和模块(Modules)&#xff1f; 5. RHEL9 有两个必要的软件存储…...

【权限模型】RBAC模型详解

大家好&#xff0c;我是jstart千语。今天给大家介绍一下鉴权模型RBAC&#xff0c;传统的鉴权模式就是基于用户和权限之间的多对多关系。而RBAC就更加的精准&#xff0c;更好管理。 RBAC介绍 RBAC&#xff08;Role-Based Access Control&#xff09;是一种通过角色&#xff08;…...

tree命令

tree [选项] [目录...] 指定要显示的目录。如果没有指定目录&#xff0c;tree 会显示当前目录及其子目录结构。 常用选项 -a 显示所有文件和目录&#xff0c;包括隐藏文件&#xff08;以 . 开头的文件&#xff09;。 -d 只显示目录&#xff0c;不显示文件。 -L LEVEL …...

【Vue.js】组件数据通信:基于Props 实现父组件→子组件传递数据(最基础案例)

概览 前言父子通信流程关键技术点关键规则 实战1. 在父组件中注册子组件2. 子组件接收父组件传入的数据补充与总结 前言 在 Vue 3 中&#xff0c;父组件向子组件传递数据是通过props实现的。父组件在子组件的标签上绑定数据&#xff0c;子组件通过定义props接收这些数据。这种…...

信创时代技术栈选择与前景分析:国产替代背景下的战略路径与实践指南

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…...

Python内置方法干货总结

如果你还在为提升Python代码能力发愁&#xff0c;那么掌握内置方法就是你的捷径&#xff01;很多初学者和进阶者忽略了这一“宝藏”&#xff0c;其实&#xff0c;Python的内置方法不仅能让你代码更简洁&#xff0c;还能大幅提升开发效率。今天&#xff0c;咱们就来一次系统梳理…...

小草GrassRouter多卡聚合路由器聚合卫星、MESH网络应用解决方案

一、多网融合解决方案 卫星网络融合‌ 支持接入卫星通信模块&#xff0c;在无地面网络覆盖的极端场景&#xff08;如偏远山区、海洋救援&#xff09;下&#xff0c;形成“5G卫星”双链路冗余传输&#xff0c;卫星链路可作为核心通信备份&#xff0c;确保关键指令和视频数据实…...

Spring反射机制

Spring反射机制 反射机制是加载类时&#xff0c;在运行时动态地获取类的信息&#xff0c;并且可以操作类或对象的属性、方法、构造函数等成员的能力。在 Java 里&#xff0c;反射机制的实现主要依赖于 java.lang.reflect 包下的多个类&#xff0c;以及 java.lang 包中的 Class…...

PCB硬件电路设计_pcb布线设计

1.MCU最小系统电路 这些电路都会非常接近MCU&#xff0c;他们的可靠性决定了MCU能否正常工作。 外围电路&#xff0c;为了布线整齐美观&#xff0c;尽量避免打过多的通孔。在布局的时候走线的顺序和元器件顺序尽可能的保持一直避免走线交叉。 2.晶振电路布线 一般情况下我们…...

Qt开发:XML文件的写入与读取

文章目录 一、使用 QDomDocument操作节点1.1 将信息写入XML文件中1.2.从XML文件中读取信息 二、使用 QXmlStreamWriter操作节点2.1 将信息写入XML文件中2.2 从XML文件中读取信息 三、总结 一、使用 QDomDocument操作节点 1.1 将信息写入XML文件中 #include <QDomDocument&…...

PCI/PXI 总线的可编程电阻卡

701X 系列是阿尔泰科技基于 PCI/PXI 总线的可编程电阻卡&#xff0c;多种电阻范围可选&#xff0c;稳定性好&#xff1b;准确 度低至 0.2%&#xff1b;分辨率设置精细&#xff0c;可低至 0.125Ω&#xff0c;适用于传感器仿真应用。 701X 系列高精度程控电阻模块具有高设置分辨…...

火语言RPA--腾讯云存储

【组件功能】&#xff1a;存储本地文件至腾讯云 选择本地文件&#xff0c;通过腾讯云存储配置上传至腾讯云对象存储的指定地域指定存储桶指定路径。 配置预览 配置说明 SecretId 支持T或# 前往官网获取或创建。参考链接&#xff1a;https://console.cloud.tencent.com/cam/…...

使用POI和EasyExcel使用导入

1.使用POI导入 1.1导入依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency> 1.2创建工具类 package com.ruoyi.common.utils.poi;import org.ap…...

AWS PrivateLink vs Lattice:深度解析两大网络服务的异同

导语: 在AWS的网络服务生态中,PrivateLink和Lattice都是备受关注的解决方案。本文将深入探讨这两项服务的核心特性、应用场景以及它们之间的关键区别,帮助您在复杂的网络架构设计中做出明智的选择。 一、AWS PrivateLink 概述 定义 AWS PrivateLink 是一种网络服务,允许您…...

Linux系统编程---exec簇:进程的加载与替换

1、exec簇基础 在Linux中&#xff0c;用于加载并执行指定程序的API有exec簇和system函数。 exec簇的进程替换不会创建一个新的进程&#xff0c;只是加载新的程序代码和数据&#xff0c;替换当前进程执行的程序代码。 system函数的进程替换是创建一个新的子进程&#xff0c;然后…...

C++ 之 【模拟实现 list(节点、迭代器、常见接口)】(将三个模板放在同一个命名空间就实现 list 啦)

1.前提准备 (1) list 的底层结构一般是带头双向循环链表 (1)为避免命名冲突&#xff0c;需要创建一个命名空间来存放模拟实现的 list (2)下面模拟实现list时&#xff0c;声明和定义不分离(具体原因后续讲解) 2.完整实现 2.1 链表节点 template<class T>//节点写成类模板…...

数字图像处理 -- 眼底图像血管分割方法

算法框架 基于深度学习的 U-Net 架构&#xff0c;结合注意力机制&#xff08;Attention Gate&#xff09;与多尺度特征提取&#xff0c;以提高细小血管的检测能力。整体流程如下&#xff1a; 输入图像预处理&#xff1a;提取绿色通道 & CLAHE 增强数据增强&#xff1a;旋…...

基于ffmpeg的音视频编码

1 音频编码 本质上是由pcm文件转到一个协议文件 比如说aac协议 1.1 音频基本知识回归 比特率 比特率是指单位时间内传输或处理的比特&#xff08;bit&#xff09;数量&#xff0c;通常用 bps&#xff08;bits per second&#xff0c;比特每秒&#xff09;来表示。它是衡量数…...

Android wifi开发调试总结

Android wifi开发调试简单总结 文章目录 Android wifi开发调试简单总结一、前言二、wifi demo开发1、开关和连接2、wifi开启主要流程3 、wifi主要广播4、相关日志5、demo示例 三、其他1、Wifi开发小结2、其他wifi知识小结&#xff08;1&#xff09;Android无线Wifi开发&#xf…...

LLVIP、KAIST、M3FD数据集

LLVIP、KAIST、M3FD数据集 &#xff08;可见光红外&#xff0c;双模态数据集&#xff0c;已配准已对齐已清洗&#xff0c;已处理为txt格式&#xff0c;YOLO可直接训练&#xff09; 电子产品&#xff0c;一经出售&#xff0c;概不退换 算法设计、毕业设计、期刊专利&#xff01;…...

datasets 数据处理封装后,统一处理流程以避免Dataset Map顺序依赖问题

文章目录 处理流程说明小结 在实际项目中&#xff0c;我们常常需要对数据集进行预处理。为了规范操作&#xff0c;我封装了一个基础数据集处理类&#xff1a; class DatasetAbstract:"""所有数据集都应包含以下几个字段&#xff1a;* question&#xff1a;用户…...

【学习笔记】机器学习(Machine Learning) | 第四章(3)| 多变量线性回归

机器学习&#xff08;Machine Learning&#xff09; 简要声明 基于吴恩达教授(Andrew Ng)课程视频 BiliBili课程资源 文章目录 机器学习&#xff08;Machine Learning&#xff09;简要声明 三、特征工程与多项式回归&#xff08;一&#xff09;特征工程&#xff1a;从数据中发…...

将本地Springboot项目部署到Linux服务器

1、打包后端项目 在IDEA的终端上执行命令 mvn clean package "-Dmaven.test.skiptrue" 在target目录下查看jar包是否存在 2、idea运行jar包&#xff08;可选&#xff09; 在IDEA的终端上执行命令 # 进入jar包所在目录 E:\LzpWorkspaces\lzp-records> cd .\tar…...

无人设备遥控器之实时数据保护技术篇

无人设备遥控器的实时数据保护技术是保障设备安全运行、避免信息泄露或恶意干扰的核心手段&#xff0c;其核心目标是在复杂电磁环境和网络攻击威胁下&#xff0c;确保指令传输的完整性、保密性和抗干扰性。 一、技术实现路径 链路层加密与认证 动态密钥协商&#xff1a;采用…...

【优秀三方库研读】【性能优化点滴】odygrd/quill 解决伪共享

一、伪共享&#xff08;False Sharing&#xff09;问题本质 当不同CPU核心频繁修改**同一缓存行&#xff08;Cache Line&#xff09;**中的不同变量时&#xff0c;会导致严重的性能下降。现代CPU的缓存系统以缓存行&#xff08;通常64字节&#xff09;为单位操作内存&#xff…...

JavaScript性能优化实战(6):网络请求与资源加载优化

引言 在现代Web应用开发中,网络性能已成为影响用户体验的关键因素。据统计,用户等待页面加载的耐心通常不超过3秒,超过这个时间,约40%的用户会选择离开。此外,Google的研究表明,页面加载时间每增加0.5秒,流量就会下降约20%。因此,优化网络请求和资源加载不仅关乎用户体…...

re题(49)BUUCTF-crackMe

BUUCTF在线评测 int wmain() {FILE *v0; // eaxFILE *v1; // eaxchar v3; // [esp3h] [ebp-405h]char v4[256]; // [esp4h] [ebp-404h] BYREFchar Format[256]; // [esp104h] [ebp-304h] BYREFchar v6[256]; // [esp204h] [ebp-204h] BYREFchar v7[256]; // [esp304h] [ebp-10…...

Python中的单例模式:深入探索元类与装饰器实现

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 单例模式(Singleton Pattern)是设计模式中的一种重要模式,确保一个类在整个应用中只有一个实例,并且提供全局访问点。Python语言作为一…...