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.pswp.cn/news/903743.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903743.shtml
英文地址,請注明出處:http://en.pswp.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 系統上安裝…