国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART)

這篇具有很好參考價值的文章主要介紹了開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

文章傳送門

一、什么是串口

二、本項目串口的FPGA實現(xiàn)

三、串口驅(qū)動程序的編寫

四、上板測試


文章傳送門

開發(fā)一個RISC-V上的操作系統(tǒng)(一)—— 環(huán)境搭建_riscv開發(fā)環(huán)境_Patarw_Li的博客-CSDN博客

開發(fā)一個RISC-V上的操作系統(tǒng)(二)—— 系統(tǒng)引導(dǎo)程序(Bootloader)_Patarw_Li的博客-CSDN博客

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART)_Patarw_Li的博客-CSDN博客

一、什么是串口

串口(UART)又名異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter),是一種通用的數(shù)據(jù)通信協(xié)議,也是異步串行通信口(串口)的總稱,它在發(fā)送數(shù)據(jù)時將并行數(shù)據(jù)轉(zhuǎn)換成串行數(shù)據(jù)來傳輸,在接收數(shù)據(jù)時將串行數(shù)據(jù)轉(zhuǎn)換成并行數(shù)據(jù)。SPI和I2C為同步通信接口,雙方時鐘頻率相同,而UART屬于異步通信接口,沒有統(tǒng)一時鐘,靠起始位和終止位來接收數(shù)據(jù)。

串口包括RS232、RS499、RS423等接口標準規(guī)范,我們這里使用的是RS232:
開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

上圖為串口的通信方式,可以同時收發(fā)(全雙工通信)。其中rx負責(zé)接收,tx負責(zé)發(fā)送,每次發(fā)送10bit數(shù)據(jù)(起始位+8bit數(shù)據(jù)+停止位),從最低位開始發(fā)送。?

二、本項目串口的FPGA實現(xiàn)

在寫串口的驅(qū)動程序之前,我們首先要知道如何與開發(fā)板上的串口進行交互,所以我們要先看看我們riscv cpu項目是怎么實現(xiàn)串口模塊的。

項目倉庫:

cpu_prj: 一個基于RISC-V指令集的CPU實現(xiàn)

串口模塊的實現(xiàn)在?FPGA/rtl/perips/目錄下的uart.v文件中,它作為一個外設(shè)掛載在rib總線上

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

在總線模塊 FPGA/rtl/core/rib.v中可以看到, uart.v外設(shè)的地址范圍為0x2000_0000 ~ 0x2fff_ffff,用于訪問uart模塊中的寄存器(實際uart模塊只有三個寄存器,不需要這么大空間,但是影響不大):

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

下面是uart.v的代碼。其中uart_rx和uart_tx引腳為串口接收和發(fā)送引腳;最下面五個信號則用于讀寫串口寄存器。

// 串口模塊,默認波特率為9600
module uart(

    input   wire                        clk                 ,
    input   wire                        rst_n               ,
    
    input   wire                        uart_rx             , // uart接收引腳
    output  reg                         uart_tx             , // uart發(fā)送引腳
    
    input   wire                        wr_en_i             , // uart寄存器寫使能信號
    input   wire[`INST_ADDR_BUS]        wr_addr_i           , // uart寄存器寫地址
    input   wire[`INST_DATA_BUS]        wr_data_i           , // uart寫數(shù)據(jù)
    input   wire[`INST_ADDR_BUS]        rd_addr_i           , // uart寄存器讀地址
    output  reg [`INST_DATA_BUS]        rd_data_o             // uart讀數(shù)據(jù)

    );
    
    // 寄存器地址定義
    parameter   UART_CTRL = 4'd0,
                UART_TX_DATA_BUF= 4'd4,
                UART_RX_DATA_BUF= 4'd8;
    // addr: 0x0
    // 低兩位(1:0)為TI和RI
    // TI:發(fā)送完成位,該位在數(shù)據(jù)發(fā)送完成時被設(shè)置為高電平
    // RI:接收完成位,該位在數(shù)據(jù)接收完成時被設(shè)置為高電平
    reg[31:0]   uart_ctrl;
    
    // addr: 0x4
    // 發(fā)送數(shù)據(jù)寄存器
    reg[31:0]   uart_tx_data_buf;
    
    // addr: 0x8
    // 接收數(shù)據(jù)寄存器
    reg[31:0]   uart_rx_data_buf;
    
    parameter   BAUD_CNT_MAX = `CLK_FREQ / `UART_BPS;
    parameter   IDLE = 4'd0,
                BEGIN= 4'd1,
                RX_BYTE = 4'd2,
                TX_BYTE = 4'd3,
                END  = 4'd4;
    
    wire                        uart_rx_temp;
    reg                         uart_rx_delay; // rx延遲后的輸入
    reg[3:0]                    uart_rx_state; // rx狀態(tài)機
    reg[12:0]                   rx_baud_cnt;   // rx計數(shù)器
    reg[3:0]                    rx_bit_cnt;    // rx比特計數(shù)
    
    reg[3:0]                    uart_tx_state; // rx狀態(tài)機
    reg[12:0]                   tx_baud_cnt;   // rx計數(shù)器
    reg[3:0]                    tx_bit_cnt;    // rx比特計數(shù)
    reg                         tx_data_rd;    // 發(fā)送數(shù)據(jù)就緒信號
    
    
    // 讀寫寄存器,write before read
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            uart_ctrl <= `ZERO_WORD;
            uart_tx_data_buf <= `ZERO_WORD;
        end
        else begin
            if(wr_en_i == 1'b1) begin
                case(wr_addr_i[3:0])
                    UART_CTRL: begin
                        uart_ctrl = wr_data_i;
                    end
                    UART_TX_DATA_BUF: begin
                        uart_tx_data_buf = wr_data_i;
                    end
                    default: begin
                    end
                endcase
            end
            if(uart_tx_state == END && tx_baud_cnt == 1) begin
                uart_ctrl[1] = 1'b1; // TI置1,代表發(fā)送完畢,需要軟件置0
            end
            if(uart_rx_state == END && rx_baud_cnt == 1) begin
                uart_ctrl[0] = 1'b1; // RI置1,代表接收完畢,需要軟件置0
            end
            case(rd_addr_i[3:0])
                UART_CTRL: begin
                    rd_data_o = uart_ctrl;
                end
                UART_TX_DATA_BUF: begin
                    rd_data_o = uart_tx_data_buf;
                end
                UART_RX_DATA_BUF: begin
                    rd_data_o = uart_rx_data_buf;
                end
                default: begin
                    rd_data_o = `ZERO_WORD;
                end
            endcase
        end
    end
    
    /* TX發(fā)送模塊 */
    
    // tx數(shù)據(jù)就緒信號 tx_data_rd
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            tx_data_rd <= 1'b0;  
        end
        else if(wr_en_i == 1'b1 && wr_addr_i[3:0] == UART_TX_DATA_BUF) begin
            tx_data_rd <= 1'b1;
        end
        else if(uart_tx_state == END && tx_baud_cnt == 1) begin
            tx_data_rd <= 1'b0;
        end
        else begin
            tx_data_rd <= tx_data_rd;
        end
    end
    
    // tx_baud_cnt計數(shù)
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n) begin 
            tx_baud_cnt <= 13'd0;
        end
        else if(uart_tx_state == IDLE || tx_baud_cnt == BAUD_CNT_MAX - 1) begin
            tx_baud_cnt <= 13'd0;
        end
        else begin
            tx_baud_cnt <= tx_baud_cnt + 1'b1;
        end
    end
    
    // TX發(fā)送模塊
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            uart_tx_state <= IDLE;
            tx_bit_cnt <= 4'd0;
            uart_tx <= 1'b1;
        end
        else begin
            case(uart_tx_state)
                IDLE: begin
                    uart_tx <= 1'b1;
                    if(tx_data_rd == 1'b1) begin
                        uart_tx_state <= BEGIN; 
                    end
                    else begin
                        uart_tx_state <= uart_tx_state;
                    end
                end
                BEGIN: begin
                    uart_tx <= 1'b0;
                    if(tx_baud_cnt == BAUD_CNT_MAX - 1) begin
                        uart_tx_state <= TX_BYTE; 
                    end
                    else begin
                        uart_tx_state <= uart_tx_state;
                    end
                end
                TX_BYTE: begin
                    if(tx_bit_cnt == 4'd7 && tx_baud_cnt == BAUD_CNT_MAX - 1) begin
                        tx_bit_cnt <= 4'd0;
                        uart_tx_state <= END; 
                    end
                    else if(tx_baud_cnt == BAUD_CNT_MAX - 1) begin
                        tx_bit_cnt <= tx_bit_cnt + 1'b1; 
                    end
                    else begin
                        uart_tx <= uart_tx_data_buf[tx_bit_cnt];
                    end
                end
                END: begin
                    uart_tx <= 1'b1;
                    if(tx_baud_cnt == BAUD_CNT_MAX - 1) begin
                        uart_tx_state <= IDLE; 
                    end
                    else begin
                        uart_tx_state <= uart_tx_state;
                    end
                end
                default: begin
                    uart_tx_state <= IDLE;
                    tx_bit_cnt <= 4'd0;
                    uart_tx <= 1'b1;
                end
            endcase
        end
    end
    
    
    /* RX接收模塊 */
    
    // 將輸入rx延遲4個時鐘周期,減少亞穩(wěn)態(tài)的影響
    delay_buffer #(
        .DEPTH(4),
        .DATA_WIDTH(1)
    ) u_delay_buffer(
        .clk           (clk),   //  Master Clock
        .data_i        (uart_rx),   //  Data Input
        .data_o        (uart_rx_temp)    //  Data Output
    );
    
    always @ (posedge clk) begin
        uart_rx_delay <= uart_rx_temp;
    end
    
    // rx_baud_cnt計數(shù)
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n) begin 
            rx_baud_cnt <= 13'd0;
        end
        else if(uart_rx_state == IDLE || rx_baud_cnt == BAUD_CNT_MAX - 1) begin
            rx_baud_cnt <= 13'd0;
        end
        else begin
            rx_baud_cnt <= rx_baud_cnt + 1'b1;
        end
    end
    
    // RX接收模塊
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            uart_rx_state <= IDLE;
            rx_bit_cnt <= 4'd0;
            uart_rx_data_buf <= `ZERO_WORD;
        end
        else begin
            case(uart_rx_state)
                IDLE: begin
                    if(uart_rx_temp == 1'b0 && uart_rx_delay == 1'b1) begin
                        uart_rx_state <= BEGIN; 
                    end
                    else begin
                        uart_rx_state <= uart_rx_state;
                    end
                end
                BEGIN: begin
                    if(rx_baud_cnt == BAUD_CNT_MAX - 1) begin
                        uart_rx_state <= RX_BYTE; 
                    end
                    else begin
                        uart_rx_state <= uart_rx_state;
                    end
                end
                RX_BYTE: begin
                    if(rx_bit_cnt == 4'd7 && rx_baud_cnt == BAUD_CNT_MAX - 1) begin
                        rx_bit_cnt <= 4'd0;
                        uart_rx_state <= END; 
                    end
                    else if(rx_baud_cnt == BAUD_CNT_MAX / 2 - 1) begin
                        uart_rx_data_buf[rx_bit_cnt] <= uart_rx_delay;
                    end
                    else if(rx_baud_cnt == BAUD_CNT_MAX - 1) begin
                        rx_bit_cnt <= rx_bit_cnt + 1'b1; 
                    end
                    else begin
                        uart_rx_state <= uart_rx_state;
                    end
                end
                END: begin
                    if(rx_baud_cnt == 1) begin
                        uart_rx_state <= IDLE; 
                    end
                    else begin
                        uart_rx_state <= uart_rx_state;
                    end
                end
                default: begin
                    uart_rx_state <= IDLE;
                    rx_bit_cnt <= 4'd0;
                    uart_rx_data_buf <= `ZERO_WORD;
                end
            endcase
        end
    end
    
endmodule

在串口模塊uart.v中定義了三個寄存器,分別為 串口控制寄存器 uart_ctrl、 串口發(fā)送數(shù)據(jù)緩存寄存器 uart_tx_data_buf、?串口接收數(shù)據(jù)緩存寄存器 uart_rx_data_buf,它們的作用分別是:

  • ?uart_ctrl串口控制寄存器,只有最低兩位有效,分別為TI和RI。TI,發(fā)送完成標志位,該位在數(shù)據(jù)發(fā)送完成時被設(shè)置為1RI,接收完成標志位,該位在數(shù)據(jù)接收完成時被設(shè)置為高電平。在數(shù)據(jù)發(fā)送/接收完成后由uart模塊將TI/RI置1,這樣驅(qū)動程序就可以通過讀取該寄存器的TI/RI位來確定數(shù)據(jù)是否發(fā)送/接收完成,這兩位需要軟件復(fù)位
  • uart_tx_data_buf串口發(fā)送數(shù)據(jù)緩存寄存器,只要uart_tx_data_buf寄存器有數(shù)據(jù)寫入,就開始發(fā)送數(shù)據(jù),發(fā)送完畢將TI置1。
  • uart_rx_data_buf串口接收數(shù)據(jù)緩存寄存器,用于接收用戶通過rx端口發(fā)送的數(shù)據(jù),接收完就將RI置1。

它們的地址偏移分別是0,4,8,實際的物理地址為0x20000000,0x20000004,0x20000008:

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

在了解上述內(nèi)容后,我們就可以開始編寫串口驅(qū)動程序了。

三、串口驅(qū)動程序的編寫

源碼放在我的gitee倉庫,歡迎star:

riscv_os: 一個RISC-V上的簡易操作系統(tǒng)

代碼在?01_UART?目錄下,目錄結(jié)構(gòu)為:

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

inc目錄存放頭文件,其中platform.h里定義了串口設(shè)備首地址UART:

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

uart.c即為我們的串口驅(qū)動程序,代碼內(nèi)容如下:?

#define UART_REG_ADDRESS(reg) ((uint8_t *) (UART + reg))

/*
 * UART registers map
 */
#define UART_CTRL 	 0
#define UART_TX_DATA_BUF 4
#define UART_RX_DATA_BUF 8

#define uart_read_reg(reg) (*(UART_REG_ADDRESS(reg)))
#define uart_write_reg(reg, data) (*(UART_REG_ADDRESS(reg)) = (data))

void uart_init()
{
	// init uart_ctrl reg to 0
	uart_write_reg(UART_CTRL, 0x00);
}

void uart_putc(char ch)
{    
	// fill send buf
	uart_write_reg(UART_TX_DATA_BUF, ch);
    // wait send over
    while((uart_read_reg(UART_CTRL) & (1 << 1)) != (1 << 1)){}
    // set TI to 0
	uart_write_reg(UART_CTRL, (uart_read_reg(UART_CTRL) & ~(1 << 1)));
}

void uart_puts(char *s)
{
	while(*s){
		uart_putc(*s++);
	}
}

char uart_getc()
{
	// wait RI to 1
	while((uart_read_reg(UART_CTRL) & (1 << 0)) != (1 << 0)){}
	// set RI to 0
	uart_write_reg(UART_CTRL, (uart_read_reg(UART_CTRL) & ~(1 << 0)));
	// read receive buf
	return uart_read_reg(UART_RX_DATA_BUF);
}

void uart_gets(char *s, uint8_t len){
	uint8_t i = 0;
	while(i < len - 1 && (*s = uart_getc()) != '\n'){
		++i;
		++s;
	}
	*(s + 1) = '\0';
}

其中第一行定義的宏UART_REG_ADDRESS(reg)用于取得對應(yīng)寄存器reg的地址,下面三個宏UART_CTRL,UART_TX_DATA_BUF,UART_RX_DATA_BUF 即為寄存器的偏移地址,例如uart_ctrl寄存器的地址為 (UART +?UART_CTRL ) = 0x20000000 + 0。

宏函數(shù)uart_read_reg(reg)用于讀取對應(yīng)reg的內(nèi)容,uart_write_reg(reg, data)則用于將data寫入對應(yīng)reg。

uart_init()函數(shù)很簡單,用于初始化uart_ctrl寄存器。

uart_putc(char ch)函數(shù)用于發(fā)送一個字符給上位機。首先會把要發(fā)的內(nèi)容寫入uart_tx_data_buf;寫入后串口模塊會自動發(fā)送數(shù)據(jù),發(fā)送完成后TI會置1,在此期間該函數(shù)會一直輪詢查看TI是否置1,若TI置1則代表發(fā)送完成。發(fā)送完成后需要將TI置0。

void uart_putc(char ch)
{    
	// fill send buf
	uart_write_reg(UART_TX_DATA_BUF, ch);
    // wait send over
    while((uart_read_reg(UART_CTRL) & (1 << 1)) != (1 << 1)){}
    // set TI to 0
	uart_write_reg(UART_CTRL, (uart_read_reg(UART_CTRL) & ~(1 << 1)));
}

uart_getc()函數(shù)用于接收上位機發(fā)過來的一個字符。因為只有RI為1才代表有一個字節(jié)數(shù)據(jù)需要接收,所以在RI為0的時候需要一直循環(huán)等待;待RI為1后,先把RI復(fù)位(置0),然后再讀取uart_rx_data_buf的內(nèi)容,得到上位機發(fā)過來的一個字符數(shù)據(jù)。

char uart_getc()
{
	// wait RI to 1
	while((uart_read_reg(UART_CTRL) & (1 << 0)) != (1 << 0)){}
	// set RI to 0
	uart_write_reg(UART_CTRL, (uart_read_reg(UART_CTRL) & ~(1 << 0)));
	// read receive buf
	return uart_read_reg(UART_RX_DATA_BUF);
}

uart_puts()和uart_gets()則用于連續(xù)獲取一組字符得到一個字符串,是通過連續(xù)調(diào)用上面兩個函數(shù)實現(xiàn)的。

至此,uart驅(qū)動程序的內(nèi)容已經(jīng)講解完畢,接下來調(diào)用試試看。

四、上板測試

首先我們看看主程序里面的內(nèi)容:

void start_kernel(void){
        /* User code begin */

        printf("Hello %d", 110);
        printf("World!\n");

        char msg[20] = "";
        while(1){
                uart_gets(msg, 20);
                uart_puts(msg);
        }

        /* User code end */

        while(1){}; // stop here!
}

可以看到這是一個串口回環(huán),會把我們上位機發(fā)送的msg又回傳到上位機。接下來我們燒錄到板子上看看,在燒錄前確保你的板子已經(jīng)把我的riscv cpu跑起來了,可以看我前面的文章。

首先執(zhí)行make得到os.bin文件,然后通過python燒錄程序把os.bin燒錄到處理器的memory中,燒錄完后我們需要用串口工具來調(diào)試,可以下載我上傳到cpu_prj倉庫里面的串口工具:

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

打開串口調(diào)試工具,設(shè)置好參數(shù)后點擊右下角的打開按鈕:

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

打開串口后,按下復(fù)位鍵即可看到串口輸出內(nèi)容?,輸出的是printf函數(shù)打印的內(nèi)容(pirntf函數(shù)也調(diào)用了uart_puts函數(shù),這里就不細講了,感興趣的話可以去看printf.c文件的內(nèi)容):

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

在下面的輸入框內(nèi)輸入內(nèi)容,最后加一個回車(內(nèi)容最后一定要加一個回車,uart_gets()函數(shù)是通過回車符號來判斷內(nèi)容的結(jié)束的),然后點擊發(fā)送即可看到上面顯示你發(fā)送的內(nèi)容:

開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART),RISC-V上的操作系統(tǒng)設(shè)計,risc-v,linux

至此,串口驅(qū)動程序?qū)嶒灲Y(jié)束,實現(xiàn)了串口,我們之后開發(fā)調(diào)試都會方便很多~

遇到問題歡迎加群 892873718 交流~文章來源地址http://www.zghlxwxcb.cn/news/detail-607090.html

到了這里,關(guān)于開發(fā)一個RISC-V上的操作系統(tǒng)(三)—— 串口驅(qū)動程序(UART)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 從零學(xué)習(xí)開發(fā)一個RISC-V操作系統(tǒng)(四)丨RISC-V匯編語言編程

    從零學(xué)習(xí)開發(fā)一個RISC-V操作系統(tǒng)(四)丨RISC-V匯編語言編程

    ?? 本系列是博主參考B站課程學(xué)習(xí)開發(fā)一個RISC-V的操作系統(tǒng)的學(xué)習(xí)筆記,計劃從RISC-V的底層匯編指令學(xué)起,結(jié)合C語言,在Ubuntu 20.04上開發(fā)一個簡易的操作系統(tǒng)。一個目的是通過實踐操作學(xué)習(xí)和了解什么是操作系統(tǒng),第二個目的是為之后學(xué)習(xí)RISC-V的集成電路設(shè)計打下一定基礎(chǔ)

    2024年01月25日
    瀏覽(42)
  • 從頭開發(fā)一個RISC-V的操作系統(tǒng)(一)計算機系統(tǒng)漫游

    從頭開發(fā)一個RISC-V的操作系統(tǒng)(一)計算機系統(tǒng)漫游

    目標:通過這一個系列課程的學(xué)習(xí),開發(fā)出一個簡易的在RISC-V指令集架構(gòu)上運行的操作系統(tǒng)。 這個系列的大部分文章和知識來自于:[完結(jié)] 循序漸進,學(xué)習(xí)開發(fā)一個RISC-V上的操作系統(tǒng) - 汪辰 - 2021春,以及相關(guān)的github地址。 在這個過程中,這個系列相當于是我的學(xué)習(xí)筆記,做

    2024年04月09日
    瀏覽(21)
  • 從頭開發(fā)一個RISC-V的操作系統(tǒng)(三)編譯與鏈接

    從頭開發(fā)一個RISC-V的操作系統(tǒng)(三)編譯與鏈接

    目標:通過這一個系列課程的學(xué)習(xí),開發(fā)出一個簡易的在RISC-V指令集架構(gòu)上運行的操作系統(tǒng)。 這個系列的大部分文章和知識來自于:[完結(jié)] 循序漸進,學(xué)習(xí)開發(fā)一個RISC-V上的操作系統(tǒng) - 汪辰 - 2021春,以及相關(guān)的github地址。 在這個過程中,這個系列相當于是我的學(xué)習(xí)筆記,做

    2024年04月09日
    瀏覽(19)
  • xv6(RISC-V)操作系統(tǒng)源碼分析第二節(jié)——操作系統(tǒng)組織

    xv6(RISC-V)操作系統(tǒng)源碼分析第二節(jié)——操作系統(tǒng)組織

    一個操作系統(tǒng)至少需要滿足以下三個要求: 多路復(fù)用 進程隔離 進程通信 硬件CPU的數(shù)量有限,且往往少于同時存在的進程數(shù)量。而操作系統(tǒng)需要支持進程的并發(fā)執(zhí)行,所以操作系統(tǒng)應(yīng)該能使多個進程分時共享計算機的資源。 一個進程的運行,應(yīng)當具有一定的獨立性,這個獨

    2024年02月03日
    瀏覽(22)
  • RISC-V公測平臺發(fā)布 · 數(shù)據(jù)庫在RISC-V服務(wù)器上的適配評估

    RISC-V公測平臺發(fā)布 · 數(shù)據(jù)庫在RISC-V服務(wù)器上的適配評估

    前言 上一期講到Y(jié)CSB在RISC-V服務(wù)器上對MySQL進行性能測試(RISC-V公測平臺發(fā)布 · 使用YCSB測試SG2042上的MySQL性能),在這一期文章中,我們繼續(xù)深入討論RISC-V+數(shù)據(jù)庫的應(yīng)用。本期就繼續(xù)利用HS-2平臺來測試數(shù)據(jù)庫軟件在RISC-V服務(wù)器上的兼容性。 參與此次實驗的數(shù)據(jù)庫如下: Red

    2024年02月12日
    瀏覽(26)
  • 在FPGA上運行輕量級Linux系統(tǒng)的RISC-V內(nèi)核 FPGA開發(fā)

    隨著嵌入式系統(tǒng)的發(fā)展,F(xiàn)PGA(現(xiàn)場可編程門陣列)在實現(xiàn)高性能和靈活性方面發(fā)揮著重要作用。RISC-V是一種基于開放指令集架構(gòu)(ISA)的處理器架構(gòu),它在嵌入式系統(tǒng)中越來越受歡迎。本文將介紹如何在FPGA上實現(xiàn)一個輕量級Linux系統(tǒng),其中包括RISC-V內(nèi)核的開發(fā)。 為了在FPGA上

    2024年02月04日
    瀏覽(26)
  • RISC-V IOPMP實際用例-Rapid-k模型在NVIDIA上的應(yīng)用

    RISC-V IOPMP實際用例-Rapid-k模型在NVIDIA上的應(yīng)用

    安全之安全(security2)博客目錄導(dǎo)讀 2023 RISC-V中國峰會 安全相關(guān)議題匯總 說明:本文參考RISC-V 2023中國峰會如下議題,版權(quán)歸原作者所有。

    2024年02月11日
    瀏覽(23)
  • RISC-V公測平臺發(fā)布 · 第一個WEB Server “Hello RISC-V world!”

    RISC-V公測平臺發(fā)布 · 第一個WEB Server “Hello RISC-V world!”

    RISC-V公測平臺Web Server地址:http://175.8.161.253:8081 Web Server是互聯(lián)網(wǎng)應(yīng)用的基礎(chǔ)設(shè)施,無論是用戶訪問網(wǎng)站,還是后端服務(wù)提供商和開發(fā)者構(gòu)建各種應(yīng)用程序,Web Server都在其中扮演著至關(guān)重要的角色。 顯而易見,對于RISC-V生態(tài)來說, Web Server也是不可缺少的一部分 。 接下來我們

    2024年02月14日
    瀏覽(31)
  • 簡單介紹STM32上的FreeRTOS實時操作系統(tǒng)

    FreeRTOS是一款廣泛使用的開源實時操作系統(tǒng)(RTOS),它為嵌入式系統(tǒng)提供了可靠的任務(wù)調(diào)度和并發(fā)管理。在嵌入式領(lǐng)域中,STM32微控制器廣受歡迎,并且與FreeRTOS的結(jié)合使用可以提供強大的功能和靈活性。在本篇博客中,我們將深入探究STM32上的FreeRTOS,并了解其核心概念、任

    2024年02月16日
    瀏覽(33)
  • 淺談 RISC-V 軟件開發(fā)生態(tài)之 IDE

    淺談 RISC-V 軟件開發(fā)生態(tài)之 IDE

    軟件開發(fā)者是芯片公司非常重要的資產(chǎn),CPU做出來是不夠的,要讓更多的軟件開發(fā)者用這顆芯片才是成功。國際大廠們都有一只較大的軟件團隊,在做面向開發(fā)者的軟件工具和SDK等。--張先軼博士:為什么RISC-V需要共建軟件生態(tài)? 目前RISC-V架構(gòu)在全球發(fā)展迅猛,RISC-V花了差不多

    2024年02月10日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包