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;

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

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

相关文章

【Java学习笔记】递归

递归&#xff08;recursion&#xff09; 思想&#xff1a;把一个复杂的问题拆分成一个简单问题和子问题&#xff0c;子问题又是更小规模的复杂问题&#xff0c;循环往复 本质&#xff1a;栈的使用 递归的注意事项 &#xff08;1&#xff09;需要有递归出口&#xff0c;否者就…

渗透测试中的那些“水洞”:分析与防御

1. Nginx 版本泄露 风险分析&#xff1a; Nginx 默认会在响应头中返回 Server: nginx/x.x.x&#xff0c;攻击者可利用该信息匹配已知漏洞进行攻击。 防御措施&#xff1a; 修改 nginx.conf 配置文件&#xff0c;隐藏版本信息&#xff1a;server_tokens off;使用 WAF 进行信息…

基于C#开发的适合Windows开源文件管理器

使用DDD从零构建一个完整的系统 推荐一个功能强大且直观的开源文件管理器&#xff0c;适用于Windows平台。 01 项目简介 该项目是一个基于C#开发、开源的文件管理器&#xff0c;适用于Windows&#xff0c;界面UI美观、方便轻松浏览文件。此外&#xff0c;支持创建和提取压缩…

实习入职的总结

我是4月14号入职的&#xff0c;到现在差不多已经三个礼拜了&#xff0c;今天想总结一下这段时间的工作情况&#xff0c;并给学弟学妹们提供一些指引。 目前&#xff0c;我所在的公司是一家初创企业&#xff0c;专注于IPC安防领域。作为一名大专生&#xff0c;我深知自己的学历在…

Ubuntu 系统上部署 Kubernetes 的完整指南

Ubuntu 系统上部署 Kubernetes 的完整指南 一、环境准备&#xff08;Ubuntu 22.04/24.04&#xff09;1. 系统初始化2. 安装容器运行时&#xff08;containerd&#xff09;3. 安装 Kubernetes 组件&#xff08;kubeadm, kubelet, kubectl&#xff09; 二、部署 Kubernetes 集群1…

partition_pdf 和chunk_by_title 的区别

from unstructured.partition.pdf import partition_pdf from unstructured.chunking.title import chunk_by_titlepartition_pdf 和 chunk_by_title 初看有点像&#xff0c;都在"分块"&#xff0c;但是它们的本质完全不一样。 先看它们核心区别 partition_pdfchun…

基于深度学习的医疗诊断辅助系统设计

标题:基于深度学习的医疗诊断辅助系统设计 内容:1.摘要 随着医疗数据的爆炸式增长和深度学习技术的飞速发展&#xff0c;开发基于深度学习的医疗诊断辅助系统具有重要的现实意义。本研究的目的在于设计一个高效、准确的医疗诊断辅助系统&#xff0c;以辅助医生进行更精准的诊断…

Matlab/Simulink - BLDC直流无刷电机仿真基础教程(四) - PWM调制模拟

Matlab/Simulink - BLDC直流无刷电机仿真基础教程&#xff08;四&#xff09; - PWM调制模拟 前言一、PWM调制技术基本原理二、仿真模型中加入PWM调制三、逆变电路MOS管添加体二极管四、模拟添加机械负载五、仿真模型与控制框图文章相关模型文件下载链接参考链接 前言 本系列文…

Curl 全面使用指南

Curl&#xff08;Client URL&#xff09;是一个跨平台命令行工具&#xff0c;支持多种协议&#xff08;HTTP/HTTPS/FTP/SFTP等&#xff09;&#xff0c;用于数据传输、API调试、文件上传/下载等场景。以下从 核心功能、用户疑问解答、高级技巧 三方面系统总结&#xff0c;并整合…

PyTorch中“原地”赋值的思考

在开发一个PyTorch模块时&#xff0c;遇到了一个诡异的现象&#xff0c;将他描述出来就是下面这样&#xff1a; f[..., :p_index - 1] f[..., 1:p_index] 这个操作将f张量的部分数值进行左移&#xff0c;我在模型训练的时候还能正常跑&#xff0c;但是当我将模型部署到项目中…

什么是:云边端一体化架构

什么是云边端一体化架构 文章目录 什么是云边端一体化架构云、边、端云计算边缘计算终端设备 云边端一体化协同云边端一体化架构协同的流程云边端一体化架构协同的应用云边端一体化架构协同的价值云边端一体化架构协同未来发展趋势 云、边、端 云&#xff08;Cloud&#xff09…

gephi绘图

参考&#xff1a; 如何在Gephi中正确的显示中文&#xff1f; Gephi绘制网络图初步探索 gephi 节点标签 调节_图分析与可视化-从Gephi开始

马克·雷伯特:用算法让机器人飞奔的人

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 马克雷伯特:用算法让机器人飞奔的人 一、天才的起点 在机器人领域,有一个名字如雷贯耳——马克雷伯特(Marc Raibert)。作为波士顿动力公司(Boston…

三维装配可视化界面开发笔记

三维装配可视化界面开发笔记 项目概述 这是一个基于Vue.js和Three.js的三维装配可视化系统&#xff0c;用于展示机械零部件的装配和拆解过程。系统支持模型加载、拆解/装配路径生成、动画展示和工艺流程图生成等功能。 技术栈 前端框架: Vue 3 (使用组合式API)构建工具: Vi…

深⼊理解指针(8)

1.对上一篇的补充内容 typedef int* ptr_t #define PTR_T int* 这两种写法都是可以的 ptr_t p1, p2; //p1, p2 都是指针变量 PTR_T p3, p4; //p3 是指针变量, p4是整型变量 为什么p3 是指针变量, p4是整型变量呢&#xff1f; 因为PTR_T 真的被改为了 int* 在编译器中…

neo4j暴露公网ip接口——给大模型联通知识图谱

特别鸣谢 我的领导&#xff0c;我的脑子&#xff0c;我的学习能力&#xff0c;感动了 1. 搭建知识图谱数据库&#xff08;见上一章博客&#xff09; 这里不加赘述了&#xff0c;请参考上一篇博客搭建 2. FastApi包装接口 这里注意&#xff1a;NEO4J_URI不得写http:,只能写…

AI编程新选择!VSCode + RooCode,超越Cursor​

在当今快节奏的开发环境中&#xff0c;AI编程助手已经成为提升开发效率的关键工具。然而&#xff0c;面对众多选择&#xff0c;开发者往往陷入纠结&#xff1a;如何在众多AI编程工具中找到最适合自己的方案&#xff1f;尤其是当VSCode搭配RooCode时&#xff0c;相比Cursor&…

电子病历高质量语料库构建方法与架构项目(环境聆听与自动化文档生成篇)

电子病历高质量语料库的构建是一个复杂而系统的工程,涉及数据收集、清洗、标注、验证等多个环节。在项目实施过程中,"环境聆听"和"自动化文档生成"是两个关键支撑要素,前者确保项目能够适应不断变化的技术和业务环境,后者则保障项目过程的可追溯性和知…

Python协程入门指北

一、什么是协程&#xff1f; 协程&#xff08;Coroutine&#xff09;就像可以暂停执行的函数&#xff0c;能够在执行过程中主动让出控制权&#xff0c;等准备好后再继续执行。 生活小例子 想象你在咖啡店排队&#xff1a; 普通函数&#xff1a;必须一直排到取餐&#xff08…

mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz的下载安装和使用

资源获取链接&#xff1a; mysql-5.7.24-linux-glibc2.12-x86-64.tar.gz和使用说明资源-CSDN文库 详细作用 数据库服务器的核心文件&#xff1a; 这是一个压缩包&#xff0c;解压后包含 MySQL 数据库服务器的可执行文件、库文件、配置文件模板等。 它用于在 Linux 系统上安装…