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

嵌入式IDE(2):KEIL中SCF分散加載鏈接文件詳解和實例分析

這篇具有很好參考價值的文章主要介紹了嵌入式IDE(2):KEIL中SCF分散加載鏈接文件詳解和實例分析。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

在上一篇文章IAR中ICF鏈接文件詳解和實例分析中,我通過I.MX RT1170的SDK中的內(nèi)存映射關(guān)系,分析了IAR中的ICF鏈接文件的語法。對于MCU編程所使用的IDE來說,IAR和Keil用得比較多,所以這一篇文章就來分析一下Keil的分散文件.scf(scatter file)。

1 內(nèi)存映射

和上一篇文章一樣,同樣使用I.MX RT1170的SDK中的鏈接文件進行分析,通過實際的分散文件來學(xué)習(xí)里面的語法。和上一節(jié)也是同一個例程,除了芯片自帶的RAM外,還有NOR Flash和SDRAM。首先來看一下整個工程的內(nèi)存映射表格:

類型 名稱 起始地址 大小
Flash NOR Flash 0x30000000 0x1000000
RAM SDRAM 0x80000000 0x3000000
RAM NCACHE_REGION 0x83000000 0x1000000
RAM SRAM_DTC_cm7 0x20000000 0x40000
RAM SRAM_ITC_cm7 0x0 0x40000
RAM SRAM_OC1 0x20240000 0x80000
RAM SRAM_OC2 0x202c0000 0x80000
RAM SRAM_OC_ECC1 0x20340000 0x10000
RAM SRAM_OC_ECC2 0x20350000 0x10000

對于我們的工程來說,有以下幾個內(nèi)存:

  1. 兩個256KB的緊耦合內(nèi)存DTCMITCM
  2. 兩個帶ECC的片內(nèi)RAM:OC1OC2。
  3. 在映射的起始地址為0x30000000的FlexSPI1接口上接了一個16MB的NOR Flash
  4. 在映射的起始地址為0x80000000的FlexSPI2接口上接了一個64MB的SDRAM。其中,前48MB用于可緩存的區(qū)域,后16MB(NCACHE_REGION)用于不可緩存區(qū)域,通常直接與硬件進行交互的buffer需要設(shè)置為不可緩存。

2 SCF語法分析

2.1 工程的SCF文件

針對上面的內(nèi)存映射,官方的SDK中提供的SCF文件如下:

#if (defined(__ram_vector_table__))
  #define __ram_vector_table_size__    0x00000400
#else
  #define __ram_vector_table_size__    0x00000000
#endif

#define m_flash_config_start           0x30000400
#define m_flash_config_size            0x00000C00

#define m_ivt_start                    0x30001000
#define m_ivt_size                     0x00000020

#define m_boot_data_start              0x30001020
#define m_boot_data_size               0x00000010

#define m_dcd_data_start               0x30001030
#define m_dcd_data_size                0x000006E8

#define m_xmcd_data_start              0x30001040
#define m_xmcd_data_size               0x00000204

#define m_interrupts_start             0x30002000
#define m_interrupts_size              0x00000400

#define m_text_start                   0x30002400
#if (defined(__use_flash64MB__))
#define m_text_size                    0x03FFDC00
#else
#define m_text_size                    0x00FFDC00
#endif

#define m_qacode_start                 0x00000000
#define m_qacode_size                  0x00040000

#define m_interrupts_ram_start         0x80000000
#define m_interrupts_ram_size          __ram_vector_table_size__

#define  m_data_start                  (m_interrupts_ram_start + m_interrupts_ram_size)
#define  m_data_size                   (0x03000000 - m_interrupts_ram_size)

#define m_data2_start                  0x20000000
#define m_data2_size                   0x00040000

#define m_data3_start                  0x202C0000
#define m_data3_size                   0x00080000

#define m_ncache_start                 0x83000000
#define m_ncache_size                  0x01000000

/* Sizes */
#if (defined(__stack_size__))
  #define Stack_Size                   __stack_size__
#else
  #define Stack_Size                   0x0400
#endif

#if (defined(__heap_size__))
  #define Heap_Size                    __heap_size__
#else
  #define Heap_Size                    0x0400
#endif

#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
LR_m_text m_flash_config_start m_text_start+m_text_size-m_flash_config_start {   ; load region size_region
  RW_m_config_text m_flash_config_start FIXED m_flash_config_size { ; load address = execution address
    * (.boot_hdr.conf, +FIRST)
  }

  RW_m_ivt_text m_ivt_start FIXED m_ivt_size { ; load address = execution address
    * (.boot_hdr.ivt, +FIRST)
  }

  RW_m_boot_data_text m_boot_data_start FIXED m_boot_data_size { ; load address = execution address
    * (.boot_hdr.boot_data, +FIRST)
  }

#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1)
  RW_m_dcd_data_text m_dcd_data_start FIXED m_dcd_data_size { ; load address = execution address
    * (.boot_hdr.dcd_data, +FIRST)
  }
#elif defined(XIP_BOOT_HEADER_XMCD_ENABLE) && (XIP_BOOT_HEADER_XMCD_ENABLE == 1)
  RW_m_xmcd_data_text m_xmcd_data_start FIXED m_xmcd_data_size { ; load address = execution address
    * (.boot_hdr.xmcd_data, +FIRST)
  }
#endif
#else
LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start {   ; load region size_region
#endif
  VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address
    * (.isr_vector,+FIRST)
  }
  ER_m_text m_text_start FIXED m_text_size { ; load address = execution address
    * (InRoot$$Sections)
    .ANY (+RO)
  }
#if (defined(__ram_vector_table__))
  VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size {
  }
#else
  VECTOR_RAM m_interrupts_start EMPTY 0 {
  }
#endif
  RW_m_data2 m_data2_start m_data2_size {
    * (RamFunction)
    * (DataQuickAccess)
  }
#if (defined(__heap_noncacheable__))
  RW_m_data m_data_start m_data_size-Stack_Size { ; RW data
#else
  RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
#endif
    .ANY (+RW +ZI)
    *(*m_usb_dma_init_data)
    *(*m_usb_dma_noninit_data)
  }
#if (!defined(__heap_noncacheable__))
  ARM_LIB_HEAP +0 EMPTY Heap_Size {    ; Heap region growing up
  }
#endif
  ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
  }
  RW_m_ram_text m_qacode_start m_qacode_size { ;
    * (CodeQuickAccess)
  }
#if (defined(__heap_noncacheable__))
  RW_m_ncache m_ncache_start m_ncache_size - Heap_Size { ; ncache data
#else
  RW_m_ncache m_ncache_start m_ncache_size { ; ncache data
#endif
    * (NonCacheable.init)
    * (*NonCacheable)
  }
#if (defined(__heap_noncacheable__))
  ARM_LIB_HEAP +0 EMPTY Heap_Size {    ; Heap region growing up
  }
  RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache)-Heap_Size { ; Empty region added for MPU configuration
#else
  RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache) { ; Empty region added for MPU configuration
#endif
  }
}

2.2 define

先來分析第一段分散文件,KEIL的分散文件的語法define#if defined語句與C語言一致,所以下面這一段還是很好理解的:

#if (defined(__ram_vector_table__))
  #define __ram_vector_table_size__    0x00000400
#else
  #define __ram_vector_table_size__    0x00000000
#endif

#define m_flash_config_start           0x30000400
#define m_flash_config_size            0x00000C00

#define m_ivt_start                    0x30001000
#define m_ivt_size                     0x00000020

#define m_boot_data_start              0x30001020
#define m_boot_data_size               0x00000010

#define m_dcd_data_start               0x30001030
#define m_dcd_data_size                0x000006E8

#define m_xmcd_data_start              0x30001040
#define m_xmcd_data_size               0x00000204

#define m_interrupts_start             0x30002000
#define m_interrupts_size              0x00000400

#define m_text_start                   0x30002400
#if (defined(__use_flash64MB__))
#define m_text_size                    0x03FFDC00
#else
#define m_text_size                    0x00FFDC00
#endif

#define m_qacode_start                 0x00000000
#define m_qacode_size                  0x00040000

#define m_interrupts_ram_start         0x80000000
#define m_interrupts_ram_size          __ram_vector_table_size__

#define  m_data_start                  (m_interrupts_ram_start + m_interrupts_ram_size)
#define  m_data_size                   (0x03000000 - m_interrupts_ram_size)

#define m_data2_start                  0x20000000
#define m_data2_size                   0x00040000

#define m_data3_start                  0x202C0000
#define m_data3_size                   0x00080000

#define m_ncache_start                 0x83000000
#define m_ncache_size                  0x01000000

/* Sizes */
#if (defined(__stack_size__))
  #define Stack_Size                   __stack_size__
#else
  #define Stack_Size                   0x0400
#endif

#if (defined(__heap_size__))
  #define Heap_Size                    __heap_size__
#else
  #define Heap_Size                    0x0400
#endif

先說明一下,I.MX系列單片機上電會進入L1 BootLoader,它用來引導(dǎo)程序如何啟動,比如說是否加密、加密密鑰、是XIP還是non-XIP(就要拷貝到RAM)、是否要初始化時鐘。在NOR Flash啟動的情況下,程序鏡像的前0x2000字節(jié)就是用來給L1 BootLoader提供一些啟動信息的,這里不必過分關(guān)注這些字段的意義,若想詳細(xì)理解可以參考我的這篇文章I.MX RT1170啟動詳解:Boot配置、Bootable image頭的組成。
(1)__ram_vector_table__沒有在別的地方定義,所以__ram_vector_table_size__為0。這也很好理解,因為這里有NOR Flash,向量表就不放到RAM中了,而是放在NOR Flash的最前面。
(2)m_flash_config_startm_flash_config_size:用來給L1 BootLoader提供NOR Flash的配置信息,因為上電后L1 BootLoader用最慢的最保險的配置來初始化NOR Flash,如果用戶希望自行配置一些參數(shù),比如時鐘變快一些,就可以在這個字段填充配置信息,起始地址為0x30000400(NOR Flash的基地址為0x30000000),長度為0xC00
(3)m_ivt_startm_ivt_size:IVT(Image Vector Table)字段,用來保存程序入口地址等參數(shù)
(4)m_boot_data_startm_boot_data_size:用來保存鏡像的絕對起始地址和大小
(5)m_dcd_data_startm_dcd_data_sizeDCD字段,一般用來初始化SDRAM,特別是希望程序在SDRAM運行的時候需要配置此字段
(6)m_xmcd_data_startm_xmcd_data_size:可以看到這里的起始地址和大小與上面的DCD字段重合了,實際上二者的功能類似,只不過DCD的配置是一個個寄存器配置的指令,比較復(fù)雜,而XMCD簡化了這些配置操作,這兩個字段是二選一的。
(7)m_interrupts_startm_interrupts_size:前面說了,L1 BootLoader的頭信息的大小為0x2000,所以從0x2000開始就是程序的開始,最前面放置向量表,長度為0x400。
(8)m_text_startm_text_size:代碼段緊接著向量表后面,起始地址為0x30002400,這里__use_flash64MB__為假,我們假設(shè)用的是16MB(0x1000000)的NOR Flash,剩下的大小就是0x1000000-0x2400=0x00FFDC00。
(9)m_qacode_startm_qacode_size:即前面內(nèi)存映射中芯片內(nèi)部的SRAM_ITC_cm7
(10)m_interrupts_ram_startm_interrupts_ram_size:如果向量表沒有放在NOR Flash,就放在SDRAM的起始,這里由于放在NOR Flash,這兩個字段沒有用到
(11)m_data_startm_data_size:data數(shù)據(jù)段,這里將data段放在了SDRAM。這里SDRAM的大小為64M,這個字段占了前48M。
(12)m_data2_start、m_data2_sizem_data3_startm_data3_size:同樣是data數(shù)據(jù)段,分別為SRAM_ITC_cm7SRAM_OC2,即片內(nèi)的RAM都可以作為data段放置變量

  • SRAM_OC1沒有用到,我們可以自行聲明。因為L1 BootLoader運行時用到了這塊SRAM,所以使用時需要考慮使用這塊SRAM的時間。

(13)m_ncache_startm_ncache_size:即SDRAM最后的16M用來做non-cacheable區(qū)域,比如GUI繪制的Buffer、攝像頭的Buffer和DMA的數(shù)據(jù),這種直接與硬件交互的內(nèi)存,需要定義在不可緩存的區(qū)域。這與MPU配置有關(guān),可以參考我的MPU系列的文章MPU內(nèi)存保護單元詳解及例子和L1 Cache之I-Cache和D-cache詳解。
(14)Stack_SizeHeap_Size:分別為棧和堆的大小,由于程序中使用了FreeRTOS,所以只要保證這里的棧和堆的大小能夠成功初始化FreeRTOS即可,初始化FreeRTOS過程應(yīng)該沒有內(nèi)存分配,所以Heap Size可以設(shè)置為0。

2.3 加載區(qū)域和執(zhí)行區(qū)域

接下來開始涉及到一些分散文件的語法,參考文檔:<DUI0377G_02_mdk_armlink_user_guide.pdf>(可以在KEIL安裝目錄下找到)。
相比IAR,KEIL的分散文件的語法簡單地多,和Linux的ld文件差不多,分散文件就由一個或多個加載區(qū)域(Load Region)構(gòu)成,如下圖所示:
嵌入式IDE(2):KEIL中SCF分散加載鏈接文件詳解和實例分析,嵌入式,ide
加載區(qū)域的語法如下:

load_region_name (base_address | ("+" offset)) [attribute_list] [max_size]
"{"
execution_region_description+
"}"
  • load_region_name(名稱): 用于由鏈接器識別不同加載區(qū)域的獨特標(biāo)簽,每個加載區(qū)域必須具有唯一的名稱
  • base_address(基地址):加載區(qū)域內(nèi)的代碼和數(shù)據(jù)在內(nèi)存中放置的起始內(nèi)存地址
  • attribute_list(屬性): 定義加載區(qū)域的特性和行為,包括只讀、讀寫、僅執(zhí)行或其他內(nèi)存保護屬性
  • max_size(最大大小): 可選,用于限制加載區(qū)域的大小,防止內(nèi)存溢出
  • execution_region_description(執(zhí)行區(qū)域): 加載區(qū)域可以包含一個或多個執(zhí)行區(qū)域。執(zhí)行區(qū)域表示連續(xù)的代碼和數(shù)據(jù)塊,作為一個單獨的單元加載到內(nèi)存中

如果要把所有語法都總結(jié)到文章中就太耗時了,所以還是繼續(xù)分析分散文件,出現(xiàn)了什么語法或關(guān)鍵字,我們再來去找它的意思。由于后面的分散文件中的宏定義太多而影響閱讀,這里假設(shè)XIP_BOOT_HEADER_ENABLE=1XIP_BOOT_HEADER_DCD_ENABLE=1、XIP_BOOT_HEADER_XMCD_ENABLE=0__heap_noncacheable__(表示將堆放置在non-cacheable區(qū)域,保證堆內(nèi)存不會收到緩存的影響)。

剩下的分散文件實際上就是定義了一個加載區(qū)域LR_m_text,它的起始地址為m_flash_config_start(0x30000400),最大的大小為m_text_start+m_text_size-m_flash_config_start(16M-0x400=0xFFFC00),即從0x30000400處開始鏈接,大小為0xFFFC00,這個大小僅限制加載區(qū)域的大小(下面屬性為FIXED的執(zhí)行區(qū)域)。0~0x400與NXP RT系列單片機的加密啟動有關(guān),這些字段編譯器無法進行填充,所以這里就沒有考慮。

LR_m_text m_flash_config_start m_text_start+m_text_size-m_flash_config_start {   ; load region size_region
	......
}
  • 在分散文件中,;后面為注釋

在加載區(qū)域LR_m_text下有非常多個執(zhí)行區(qū)域,下面來一個個分析一下:

1、RW_m_config_text:起始地址0x30000400,大小0xC00

RW_m_config_text m_flash_config_start FIXED m_flash_config_size { ; load address = execution address
	* (.boot_hdr.conf, +FIRST)
}
  • FIXED:執(zhí)行區(qū)域的屬性,表示讓執(zhí)行區(qū)域的執(zhí)行地址與加載地址盡量保持相等。這意味著,分配給這個執(zhí)行區(qū)域的代碼和數(shù)據(jù)在加載到內(nèi)存時會盡量放置在指定的執(zhí)行地址上。如果因為內(nèi)存沖突或空間不足等原因無法滿足,則鏈接器會報錯。
  • +FIRST:表示把該section放在該執(zhí)行區(qū)域的最開始的地方

所以這里就是從0x30000400開始處開始放置boot_hdr.conf段,因為放置的位置必須固定才能被L1 BootLoader正確識別,所以執(zhí)行區(qū)域需要用FIXED屬性。

2、RW_m_ivt_text:起始地址0x30001000,大小0x00000020

RW_m_ivt_text m_ivt_start FIXED m_ivt_size { ; load address = execution address
	* (.boot_hdr.ivt, +FIRST)
}

同上,放置L1 BootLoader的引導(dǎo)頭。

3、RW_m_boot_data_text:起始地址0x30001020,大小0x00000010

RW_m_boot_data_text m_boot_data_start FIXED m_boot_data_size { ; load address = execution address
	* (.boot_hdr.boot_data, +FIRST)
}

同上,放置L1 BootLoader的引導(dǎo)頭。

4、RW_m_dcd_data_text:起始地址0x30001030,大小0x000006E8

RW_m_dcd_data_text m_dcd_data_start FIXED m_dcd_data_size { ; load address = execution address
	* (.boot_hdr.dcd_data, +FIRST)
}

同上,放置L1 BootLoader的引導(dǎo)頭。

5、VECTOR_ROM:起始地址0x30002000,大小0x00000400

VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address
	* (.isr_vector,+FIRST)
}

放置中斷向量表。在啟動文件startup_MIMXRT1176_cm7.S文件中定義了該段:.section .isr_vector, "a",這里的a表示將該段標(biāo)記為可分配(allocatable)的,意味著它在鏈接時可以被分配到內(nèi)存中的某個位置。

6、ER_m_text:起始地址0x30002400,大小0x00FFDC00

ER_m_text m_text_start FIXED m_text_size { ; load address = execution address
	* (InRoot$$Sections)
	.ANY (+RO)
}
  • InRoot$$Sections是在分散文件中使用的特殊標(biāo)記,用來將壓縮數(shù)據(jù)段放置該執(zhí)行區(qū)域中,以確保這些數(shù)據(jù)段在運行時能夠被自動解壓縮并提供給程序使用。該特性是ARM為了減少存儲空間占用設(shè)計的,上電后ARM庫會根據(jù)此段來進行解壓。
    • 參考文章:Example of placing code in a root region
  • .ANY:可以理解為*,表示所有段,但.ANY可以用在多個執(zhí)行區(qū)域中,而*一般只用在一個執(zhí)行區(qū)域中,所以.ANY會更靈活一些。具體參考手冊7.4章節(jié)<Placement of unassigned sections with the .ANY module selector>
  • (+RO):只讀數(shù)據(jù)段

這里表示將所有的只讀數(shù)據(jù)段放置在這個執(zhí)行區(qū)域。

7、VECTOR_RAM :這里將中斷向量表放置在NOR Flash了,這個執(zhí)行區(qū)域沒有用到

VECTOR_RAM m_interrupts_start EMPTY 0 {
}
  • EMPTY表示保留一個空區(qū)域,但這里區(qū)域的大小設(shè)為0,所以這段執(zhí)行區(qū)域沒有任何作用

8、RW_m_data2:起始地址0x20000000,大小0x00040000

RW_m_data2 m_data2_start m_data2_size {
	* (RamFunction)
	* (DataQuickAccess)
}

這里定義了兩個Section:RamFunctionDataQuickAccess,在程序中都可以用__attribute__((section("")))來定義函數(shù)或變量到內(nèi)部的SRAM_DTCM中,可以加快函數(shù)的執(zhí)行速度和數(shù)據(jù)的訪問速度。

9、RW_m_data:起始地址0x80000000,大小0x03000000-0x400

RW_m_data m_data_start m_data_size-Stack_Size { ; RW data
	.ANY (+RW +ZI)
	*(*m_usb_dma_init_data)
	*(*m_usb_dma_noninit_data)
}

這個執(zhí)行區(qū)域就是SDRAM的前48M,將所有的讀寫數(shù)據(jù)段和bss段放置在此,同時聲明兩個usb段,用于SDK中對于USB相關(guān)功能的實現(xiàn)。實際上USB段放在non-cacheable區(qū)域肯定是可以運行的,但是同時也意味著沒有用到緩存,速度就會降低很多。所以就可以將USB相關(guān)變量聲明到cacheable的區(qū)域,然后在代碼中必要的地方手動緩存更新相關(guān)函數(shù),如SCB_CleanInvalidateDCacheSCB_CleanDCache。

10、ARM_LIB_STACK:起始地址0x83000000,大小0x400

ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
}
  • ARM_LIB_STACK:棧的執(zhí)行區(qū)域的固定名稱

這里的Stack_Size的前面有一個-,表示棧是向下生長的。

11、RW_m_ram_text:起始地址0x00000000,大小0x00040000

RW_m_ram_text m_qacode_start m_qacode_size { ;
	* (CodeQuickAccess)
}

與上面的7類似,聲明一個CodeQuickAccess段,用于將函數(shù)鏈接到內(nèi)部的SRAM_ITCM中,因為內(nèi)部的SRAM的速度比NOR Flash或SDRAM的訪問速度都快得多。

12、RW_m_ncache:起始地址0x83000000,大小0x01000000-0x400

RW_m_ncache m_ncache_start m_ncache_size - Heap_Size { ; ncache data
	* (NonCacheable.init)
	* (*NonCacheable)
}

定義non-cacheable區(qū)域的兩個段NonCacheable.initNonCacheable,同時預(yù)留堆的空間,因為這里我們假設(shè)堆空間也為non-cacheable。

13、ARM_LIB_HEAP:大小0x400

ARM_LIB_HEAP +0 EMPTY Heap_Size {    ; Heap region growing up
}
  • +0:表示為上一個執(zhí)行區(qū)域的結(jié)束地址,根據(jù)用戶放置到RW_m_ncache執(zhí)行區(qū)域的變量的多少和大小來決定這個地址
  • ARM_LIB_HEAP:堆的執(zhí)行區(qū)域的固定名稱

定義堆空間的內(nèi)存。

14、RW_m_ncache_unused

RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache)-Heap_Size { ; Empty region added for MPU configuration
}

同樣放置在上一個執(zhí)行區(qū)域的結(jié)束地址處,用來給MPU進行配置,大小m_ncache_size-ImageLength(RW_m_ncache)-Heap_Size即除去變量和堆外的剩下的non-cacheable區(qū)域。文章來源地址http://www.zghlxwxcb.cn/news/detail-702241.html

  • ImageLength可以取某個執(zhí)行區(qū)域占的大小

到了這里,關(guān)于嵌入式IDE(2):KEIL中SCF分散加載鏈接文件詳解和實例分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【嵌入式資訊】Arm 通過引入 Keil MDK 版本 6 將嵌入式軟件開發(fā)提升到一個新的水平

    【嵌入式資訊】Arm 通過引入 Keil MDK 版本 6 將嵌入式軟件開發(fā)提升到一個新的水平

    ????????隨著物聯(lián)網(wǎng)設(shè)備變得越來越智能,開發(fā)人員面臨著日益增加的軟件復(fù)雜性,這需要新的開發(fā)流程來創(chuàng)建優(yōu)化的 ML 模型和高效的設(shè)備驅(qū)動程序。因此,我們?yōu)樯鷳B(tài)系統(tǒng)提供的軟件開發(fā)平臺和工具必須與我們的處理器路線圖一起發(fā)展。Keil 微控制器開發(fā)套件?(Keil M

    2024年02月15日
    瀏覽(38)
  • 【嵌入式系統(tǒng)開發(fā)】Keil 實現(xiàn)十次作業(yè)詳細(xì)代碼

    ? ? ? ??《嵌入式系統(tǒng)開發(fā)》系列專欄主要以LPC1100系列微控制器為硬件平臺,詳細(xì)介紹Cortex—-M0微控制器的原理與開發(fā)技術(shù),基于keil仿真軟件平臺設(shè)計最小應(yīng)用系統(tǒng)板和具有在板仿真器的口袋開發(fā)板以及相關(guān)例程。 ? ? ? ??本文已收錄于嵌入式系統(tǒng)開發(fā)系列專欄:嵌入式

    2024年02月08日
    瀏覽(20)
  • IDE也卷了,微軟殺入嵌入式IDE_microsoft azure rtos開源嗎(1)

    IDE也卷了,微軟殺入嵌入式IDE_microsoft azure rtos開源嗎(1)

    因為,這幾年物聯(lián)網(wǎng)的快速發(fā)展,迫使微軟布局嵌入式。 早在2019年,微軟重金收購 ThreadX 嵌入式實時操作系統(tǒng),然后,緊接著 在 2020 年,開源了Azure RTOS ThreadX 。 在去年底(2021年12月), 微軟發(fā)布了基于 VS 2022 的支持嵌入式RTOS、MCU軟件開發(fā)的IDE 。 在本月初(2022年3月),

    2024年04月16日
    瀏覽(22)
  • 【LVGL】學(xué)習(xí)筆記--(1)Keil中嵌入式系統(tǒng)移植LVGL

    【LVGL】學(xué)習(xí)筆記--(1)Keil中嵌入式系統(tǒng)移植LVGL

    最近emwin用的比較煩躁,同時被LVGL酷炫的界面吸引到了,所以準(zhǔn)備換用LVGL試試水。 LVGL(輕量級和通用圖形庫)是一個免費和開源的圖形庫,它提供了創(chuàng)建嵌入式GUI所需的一切,具有易于使用的圖形元素,美麗的視覺效果和低內(nèi)存占用。 豐富且強大的模塊化圖形組件:按鈕 (b

    2024年02月02日
    瀏覽(20)
  • 正點原子STM32嵌入式學(xué)習(xí)-keil5安裝教程

    正點原子STM32嵌入式學(xué)習(xí)-keil5安裝教程

    前言:本人沒有什么嵌入式的經(jīng)驗,但是看到硬件的同事做開發(fā)板比較好玩,比較感興趣。剛好有這樣一個機會,可以跟隨《原子教你玩STM32(庫函數(shù)版)》課程線下學(xué)習(xí),在此,將本次課程的學(xué)習(xí)做一個記錄。相信對我這樣一個小白來說,幫助還是會非常大的。 目錄 一.下

    2024年03月10日
    瀏覽(153)
  • AI嵌入式K210項目(19)-安裝CanMV IDE開發(fā)軟件

    AI嵌入式K210項目(19)-安裝CanMV IDE開發(fā)軟件

    前幾章我們介紹K210使用C語言裸機開發(fā)方法,大家對K210內(nèi)部的硬件和各種加速器有了初步的了解,但是開發(fā)人工智能相關(guān)程序,使用C語言的話復(fù)雜度比較高,因此接下來我們逐步學(xué)習(xí)基于K210芯片使用python開發(fā)人工智能相關(guān)程序,包含顏色識別,人臉識別,口罩識別等,也包

    2024年01月25日
    瀏覽(19)
  • RISC-V IDE MRS使用筆記(十):嵌入式編程開發(fā)技巧匯總

    RISC-V IDE MRS使用筆記(十):嵌入式編程開發(fā)技巧匯總

    MRS常見嵌入式開發(fā)技巧: Q1:如何修改程序編譯生成庫? A1:在工具欄中點擊活動工程的編譯配置按鈕,在Build Artifact的Tab頁面指定目標(biāo)類型,選中為Static Library 點擊Apply and Close應(yīng)用編譯配置。此時會提示建議將調(diào)試等級設(shè)置為None,優(yōu)化等級設(shè)為Os,這是為了減少生成庫的大小

    2024年02月11日
    瀏覽(18)
  • 【嵌入式開發(fā)工具】STM32+Keil實現(xiàn)軟件工程搭建與開發(fā)調(diào)試

    【嵌入式開發(fā)工具】STM32+Keil實現(xiàn)軟件工程搭建與開發(fā)調(diào)試

    本篇文章介紹了使用Keil來對STM32F103C8芯片進行初始工程搭建,以及開發(fā)與工程調(diào)試的完整過程,幫助讀者能夠在實戰(zhàn)中體會到Keil這個開發(fā)環(huán)境的使用方法,了解一個嵌入式工程從無到有的過程,并且具備快速搭建一個全新芯片對應(yīng)最小軟件工程的基本能力思路。文章首先介紹

    2024年02月05日
    瀏覽(96)
  • 【ARM 嵌入式 編譯系列 3.5 -- gcc 鏈接參數(shù)介紹】

    請閱讀 【嵌入式開發(fā)學(xué)習(xí)必備專欄 之 ARM GCC 編譯專欄】 上篇文章【ARM 嵌入式 編譯系列 3.4 – 查看所依賴庫文件的路徑 詳細(xì)介紹】一直在提 鏈接參數(shù) ,那么鏈接參數(shù)有哪些,它們又有什么作用呢? 如前一篇文章中的的鏈接參數(shù)到底是什么意思呢? -L : 指定了 鏈接庫的路徑

    2024年01月17日
    瀏覽(44)
  • CSS的三種鏈接方式(內(nèi)聯(lián)式、嵌入式、外部式)

    CSS的三種鏈接方式(內(nèi)聯(lián)式、嵌入式、外部式)

    其實就是用html中style屬性 嵌入式css樣式,就是可以把css樣式代碼寫在style type=“text/css”/style標(biāo)簽之間。 (樣式一多,內(nèi)聯(lián)式就很繁雜,不易于閱讀和維護,這沒法發(fā)揮CSS的優(yōu)勢了) 外部式css樣式(也可稱為外聯(lián)式)就是把css代碼寫一個單獨的外部文件中,這個css樣式文件以“

    2024年02月06日
    瀏覽(22)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包