日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

rtthread_scons简介

發布時間:2024/3/26 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rtthread_scons简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

env工具基本構成

  • 命令行環境Cmder: Cmder是一款免費的DOS系統仿真器,體積小巧,界面清爽,支持多標簽操作,兼容dos原有的指令。
  • 系統配置工具menuconfig: 即linux menuconfig的python實現版本,使用方法與linux menuconfig基本一致。遵循兼容LINUX的Kconfig語法,用戶可以方便的沿用以前的kconfig配置文件對代碼進行宏管理。
  • 開源軟件scons: scons是一個Python寫的自動化構建工具,從構建這個角度說,它跟GNU make是同一類的工具,是一種改進,并跨平臺的gnu make替代工具,其集成功能類似于autoconf/automake。scons是一個更簡便,更可靠,更高效的編譯軟件。
  • Python環境與.py文件: 主要目的是將scons, menuconfig, MinGW等有機的整合到Cmder中,以及添加scons的擴展選項,支持生成KEIL等可直接使用的項目文件。
  • 交叉編譯工具鏈MinGW: MinGW是Minimalist GNUfor Windows的縮寫。它是一個可自由使用和自由發布的Windows特定頭文件和使用GNU工具集導入庫的集合,允許你在GNU/Linux和Windows平臺生成本地的Windows程序而不需要第三方C運行時(C Runtime)庫。
  • 打開ENV工具進入具體工程目錄
    C:\Users\Admin\Desktop\data\rt-thread\bsp\stm32\stm32f407-atk-explorer

    scons //使用默認的 ARM_GCC 工具鏈編譯 bsp, scons 命令會根據 rtconfig.h文件編譯工程 scons -c //清除編譯目標。這個命令會清除執行 scons 時生成的臨時文件和目標文件 scons --target=iar //重新生成工程 scons --target=mdk5 scons --verbose //默認情況下,使用 scons 命令編譯的輸出不會顯示編譯參數

    menuconfig工作機制

  • menuconfig啟動后默認到當前目錄下尋找Kconfig文件,并解析。Kconfig中可以通過source指定加載子Kconfig文件,這樣根據Kconfig文件的內部調用結構,menuconfig依次解析所有被引用的Kconfig文件,生成內部的配置選項數據庫
  • 解析.config文件,根據上一次的配置結果初始化各個配置選項的初值。
  • 給用戶展示配置界面,并根據用戶的選擇更新內部數據庫。
  • Kconfig文件
    (目錄:C:\Users\Admin\Desktop\data\rt-thread\bsp\stm32\stm32f407-atk-explorer)

    mainmenu "RT-Thread Configuration" //定義主菜單標題config BSP_DIRstringoption env="BSP_ROOT"default "."config RTT_DIRstringoption env="RTT_ROOT"default "../../.."config PKGS_DIRstringoption env="PKGS_ROOT"default "packages"source "$RTT_DIR/Kconfig" source "$PKGS_DIR/Kconfig" source "../libraries/Kconfig" //加載其他目錄下的Kconfig source "board/Kconfig"
  • BSP_DIR變量定義了BSP根目錄,默認是. (因為Kconfig文件放置于BSP板級支持包目錄下),除非系統中定義了BSP_ROOT的環境變量;
  • RTT_DIR變量定義了RT-Thread 根目錄,因為板級包目錄默認放置在rt-thread/bsp目錄下,所以這個變量的默認值是…/…,除非系統中定義了RTT_ROOT的環境變量;
  • PKGS_DIR變量定義了RT-Thread包根目錄,一般它會從系統的環境變量PKGS_ROOT中獲得,而如果使用RT-Thread/env工具,env工具在啟動console終端時會默認地定義這個環境變量;
  • 這份Kconfig文件的后面部分則把相關的Kconfig文件都包含到這個Kconfig文件中來,最關鍵的是RT-Thread主干Kconfig文件 $RTT_DIR/Kconfig 和包Kconfig文件 $PKGS_DIR/Kconfig 。
  • 用戶退出交互界面并保存配置,menuconfig根據內部數據庫內容,生成新的.config文件。
    .config文件:

    # # Automatically generated file; DO NOT EDIT. # RT-Thread Configuration ## # RT-Thread Kernel # CONFIG_RT_NAME_MAX=8 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_SMP is not set CONFIG_RT_ALIGN_SIZE=4 # CONFIG_RT_THREAD_PRIORITY_8 is not set CONFIG_RT_THREAD_PRIORITY_32=y # CONFIG_RT_THREAD_PRIORITY_256 is not set CONFIG_RT_THREAD_PRIORITY_MAX=32 CONFIG_RT_TICK_PER_SECOND=1000 CONFIG_RT_USING_OVERFLOW_CHECK=y CONFIG_RT_USING_HOOK=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 CONFIG_IDLE_THREAD_STACK_SIZE=1024

    將.config文件翻譯成c語言能夠識別的rtconfig.h文件,位于當前工作目錄下。
    通過上面的步驟,menuconfig根據用戶的配置,最終生成了rtconfig.h文件,用戶便可以直接引用rtconfig.h文件來使用系統宏。從下面截取的示例可以看到rtconfig.h文件和.config文件是一 一對應的關系
    rtconfig.h文件:

    #ifndef RT_CONFIG_H__ #define RT_CONFIG_H__/* Automatically generated file; DO NOT EDIT. */ /* RT-Thread Configuration *//* RT-Thread Kernel */#define RT_NAME_MAX 8 #define RT_ALIGN_SIZE 4 #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 #define RT_TICK_PER_SECOND 1000 #define RT_USING_OVERFLOW_CHECK #define RT_USING_HOOK #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 #define IDLE_THREAD_STACK_SIZE 1024

    SCons基本命令

    scons
    編譯指令,根據scons腳本(SConstruct, SConscript)的配置,組織編譯代碼。scons命令必須在工程路徑下執行,因為scons默認會在當前路徑下尋找SConstruct文件作為第一個解析的腳本

    scons支持增量編譯,對已經編譯過的文件,且編譯后沒有進行過修改,那scons不會重新編譯這些文件,從而達到提高編譯效率的目的。

    scons --verbose
    直接使用scons編譯時,默認是不會輸出編譯選項等信息的。使用scons --verbose進行編譯時,將會打印編譯器選項等輔助信息。

    scons -c
    清除上一次編譯的臨時文件。執行該命令后,下一次編譯將能保證所有源文件都會被重新編譯。

    scons --help
    幫助命令,該命令會例舉出scons支持的所有操作選項,包括原生scons自帶的選項與OneOS擴展的操作選項。scons支持的操作選項很豐富,推薦讀者都去了解一下。

    scons --ide=xxx
    生成第三方IDE工程命令,其中“XXX”對應想要生成的工程類型。具體支持的工程類型可以通過scons --help查看。舉例生成keil5工程的命令如下:

    scons --ide=mdk5

    需要注意的是,要生產指定的IDE工程文件,一般需要提供一個空的工程文件作為模版,用戶應該在相應的模版文件中配置好硬件相關的編譯選項。具體可以參考示例開發板的工程目錄中的文件。

    SCons編譯構造概述

    Scons是構造工具,通過讀取SConstruct/Sconstruct/sconstruct和SConscript腳本來組織管理源碼,并調用指定的編譯鏈接器來對源文件進行編譯。

    scons目前支持的編譯器包括 ARM GCC、MDK、IAR、VisualStudio、Visual DSP。對流行的ARM Cortex M0、M3、M4 等架構,一般都同時支持ARM GCC、MDK、IAR 等編譯器。用戶可以通過 project 目錄下的osconfig.py 里的 CROSS_TOOL 選項查看相關的編譯器配置。

    使用SCons工具時,會使用到SConstruct/Sconstruct/sconstruct和SConscript 2種類型的文件。這2種類型的文件是Scons工具必備的,是編譯的配置腳本文件,相當于make中的makefile文件。

    Scons將在當前目錄下按SConstruct、Sconstruct、sconstruct次序來搜索配置文件,從讀取的第1個文件中讀取相關配置。

    在配置文件SConstruct中,可以使用SConscript()函數來讀取附屬的配置文件。按慣例,這些附屬配置文件被命名為“SConscript”。

    SCons的擴展性

    scons的配置文件都是基于python腳本語法的。因此可以在SConstruct文件中使用python語言很方便的調用自定義的python腳本與模塊。

    同時,scons自身也是python實現的,在自己的python腳本文件中通過添加語句:
    from SCons.Script import *

    可以很方便的直接使用scons內置類與操作。正因為scons與python腳本可以方便的互相調用,我們可以對scons方便的進行自定義與擴展。

    SCons常用函數

    腳本涉及到的函數分為兩部分:標準函數,自定義函數。

    Import()、Export()函數
    Import(vars)

    導入其它腳本定義的變量

    ‘vars’變量名,變量名是字符串,可以是一個變量或一個變量列表

    Export(vars)

    導出變量,供其它腳本使用

    ‘vars’變量名,變量名是字符串,可以是一個變量或一個變量列表

    SConscript()函數
    SConscript(scripts, [exports, variant_dir, duplicate])

    讀取一個或多個sconscript腳本,返回一個node列表,node是指一個編譯對象

    ‘scripts’:指定要加載的sconscript腳本名稱與路徑

    ‘exports’:可選參數,導出一個變量,此變量比一般Export()導出的變量有更高優先權

    ‘variant_dir’:可選參數,指定一個目錄,編譯動作都在該目錄中進行,不影響源碼路徑

    ‘duplicate’:可選參數,指定編譯目錄中是否拷貝源碼

    PresentDir()函數
    PresentDir()

    獲取當前腳本所在路徑

    Glob()函數
    Glob(pattern)

    返回滿足pattern指定條件的Node(編譯對象)

    ‘pattern’:指定匹配條件,支持unix shell的通配符替換。支持當前腳本所在路徑進行相對路徑索引

    IsDefined()函數
    IsDefined(depend)

    判斷依賴的宏或宏列表是否被定義,被定義返回True,如果存在未被定義的宏返回False

    ‘depend’:指定依賴的宏,或宏列表

    DeleteSrcFile()函數
    DeleteSrcFile(src, remove)

    將指定的文件從編譯列表中移除

    ‘src’:編譯node列表

    ‘remove’:指定被移除的文件

    AddCodeGroup()函數
    AddCodeGroup(name, src, depend, **parameters)

    將編譯對象添加到一個代碼組中進行編譯管理,返回編譯對象列表

    ‘name’:指定代碼組名稱,如果該名稱已經存在,則將添加到已經存在的組中。在keil工程中以該名稱呈現一個工作組

    ‘src’:指定要被添加的編譯對象列表

    ‘depend’:關鍵字參數,指定創建該組依賴的宏,如果條件宏不滿足,則直接返回空列表

    ‘parameters’:可變關鍵字參數,指定相應的編譯行為,支持的關鍵字如下:

    CPPPATH指定頭文件路徑,對應gcc的-I

    CCFLAGS對應gcc的–include選項

    CPPDEFINES定義編譯宏,對應gcc的-D

    LINKFLAGS定義鏈接選項

    LOCAL_CPPPATH

    定義僅對當前組有效的頭文件路徑選項

    SCons的編譯環境類

    scons中的一個基本類是構造環境Environment,scons對編譯源碼的管理,以及對編譯行為的控制都是通過配置構造環境(Env)來管理的。通過調用Environment()可以創建一個構造環境對象(Env)

    配置Env對象中的各個變量,我們可以方便的定義需要的編譯行為。簡單舉例:

    通過CPPPATH變量可以添加gcc編譯的-I選項

    通過CPPDEFINES變量可以添加gcc的-D選項

    通過CC變量可以指定C語言的交叉編譯器

    通過RESULT_SUFFIX變量可以指定生成目標文件的類型

    通過env[‘ENV’][‘PATH’]變量可以指定交叉編譯工具鏈的路徑

    python基礎知識

    os函數

    • os.system() #運行shell命令
    • os.name #返回當前使用平臺的代表字符,Windows用’nt’表示,Linux用’posix’表示
    • os.sep #返回當前操作系統特定的路徑分隔符,window和Linux通常不一樣
    • os.path.split(path) #將path的目錄和文件名分開為元組
    • os.path.join(path1,path2,…) #將path1,path2,…進行組合,若path2為絕對路徑,則會將path1刪除
    • os.path.dirname(path) #返回path中的目錄(文件夾部分),結果不包含’’
    • os.path.basename(path) #返回path中的文件名

    scons內置函數

    每一個 RT-Thread BSP 目錄下都會存在下面三個文件:rtconfig.py、SConstruct 和 SConscript,它們控制 BSP 的編譯。SConstruct文件是SCons默認解析的第一個腳本,因此scons命令必須在它所在的路徑下執行。一般建議將SConstruct腳本與rtconfig.py腳本置于用戶工程目錄中。下面以一個SConstruct為例進行簡單分析:

    SConstruct文件(SCons環境配置類腳本):

    import os //加載python庫os,os是python自帶的系統模塊,需要import使用os 源于英文Operating System(操作系統)的縮寫 import sys //加載python庫sys import rtconfig //加載編譯選項配置腳本rtconfig.pyif os.getenv('RTT_ROOT'):RTT_ROOT = os.getenv('RTT_ROOT') else:RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') //cwd(Current Working Directory),含義為當前工作目錄,os.getcwd() 指獲取當前工作目錄。定義從SConstruct所在目錄到rtthread源碼根目錄的相對路徑sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] try:from building import * except:print('Cannot found RT-Thread root directory, please check RTT_ROOT')print(RTT_ROOT)exit(-1)TARGET = 'rt-thread.' + rtconfig.TARGET_EXT //指定編譯生成二進制文件的名字//將rtconfig.py中配置的編譯選項信息傳遞到scons內置編譯對象env中 DefaultEnvironment(tools=[]) env = Environment(tools = ['mingw'],AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,AR = rtconfig.AR, ARFLAGS = '-rc',CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH)if rtconfig.PLATFORM == 'iar':env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])env.Replace(ARFLAGS = [''])env.Replace(LINKCOM = env["LINKCOM"] + ' --map rt-thread.map')Export('RTT_ROOT') //導出 RTT_ROOT 變量,供其他腳本使用 Export('rtconfig') //導出 rtconfig 變量,供其他腳本使用SDK_ROOT = os.path.abspath('./')if os.path.exists(SDK_ROOT + '/libraries'):libraries_path_prefix = SDK_ROOT + '/libraries' else:libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries'SDK_LIB = libraries_path_prefix Export('SDK_LIB')# prepare building environment objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) //調用(某腳本文件).py中的工具函數,其中會對scons選項,以及相應的編譯選項適配進行處理,通過sconscript()調用sconscript腳本文件stm32_library = 'STM32F4xx_HAL' rtconfig.BSP_LIBRARY_TYPE = stm32_library# include libraries objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SConscript')))# include drivers objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript')))# make a building DoBuilding(TARGET, objs)

    由上示例可以看出,SConstruct與rtconfig.py與用戶的具體應用環境和編譯配置緊密相關

    SConscript文件(SCons中間加載類腳本):
    (目錄:C:\Users\Admin\Desktop\data\rt-thread\bsp\stm32\stm32f407-atk-explorer)

    # for module compiling import os Import('RTT_ROOT') from building import *cwd = GetCurrentDir() //獲取當前目錄 objs = [] list = os.listdir(cwd) //獲取當前目錄下的子目錄列表//遍歷整個列表,判斷子目錄下是否存在SConscript腳本,如果存在則通過SConscript()方法加載該腳本 for d in list:path = os.path.join(cwd, d)if os.path.isfile(os.path.join(path, 'SConscript')):objs = objs + SConscript(os.path.join(d, 'SConscript'))Return('objs')

    SConscript文件(SCons代碼組織類腳本):
    此SConscript腳本位于子目錄
    (目錄:C:\Users\Admin\Desktop\data\rt-thread\bsp\stm32\stm32f407-atk-explorer\applications)

    DefineGroup()中的名字參數必須指定,如果該名字的組已經存在,則會進行追加合并。鍵值參數不是必選的,可以缺省。

    import rtconfig from building import *cwd = GetCurrentDir() CPPPATH = [cwd, str(Dir('#'))] #添加搜尋頭文件路徑 src = Split(""" main.c """) #定義要添加的源文件group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) #創建代碼管理組Return('group') #將定義的組返回給上一級調用腳本

    rtconfig.py文件:
    rtconfig.py文件,主要用于指定編譯器以及安裝路徑。除此之外,該文件中定義了大量的變量,這些變量包括編譯選項,匯編選項,鏈接選項。

    import os# toolchains options ARCH='arm' CPU='cortex-m4' CROSS_TOOL='gcc'# bsp lib config BSP_LIBRARY_TYPE = Noneif os.getenv('RTT_CC'):CROSS_TOOL = os.getenv('RTT_CC') if os.getenv('RTT_ROOT'):RTT_ROOT = os.getenv('RTT_ROOT')# cross_tool provides the cross compiler # EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR if CROSS_TOOL == 'gcc':PLATFORM = 'gcc'EXEC_PATH = r'C:\Users\XXYYZZ' elif CROSS_TOOL == 'keil':PLATFORM = 'armcc'EXEC_PATH = r'C:/Keil_v5' elif CROSS_TOOL == 'iar':PLATFORM = 'iar'EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0'if os.getenv('RTT_EXEC_PATH'):EXEC_PATH = os.getenv('RTT_EXEC_PATH')BUILD = 'debug'if PLATFORM == 'gcc':# toolchainsPREFIX = 'arm-none-eabi-'CC = PREFIX + 'gcc'AS = PREFIX + 'gcc'AR = PREFIX + 'ar'CXX = PREFIX + 'g++'LINK = PREFIX + 'gcc'TARGET_EXT = 'elf'SIZE = PREFIX + 'size'OBJDUMP = PREFIX + 'objdump'OBJCPY = PREFIX + 'objcopy'DEVICE = ' -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections'CFLAGS = DEVICE + ' -Dgcc'AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb 'LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rt-thread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds'CPATH = ''LPATH = ''if BUILD == 'debug':CFLAGS += ' -O0 -gdwarf-2 -g'AFLAGS += ' -gdwarf-2'else:CFLAGS += ' -O2'CXXFLAGS = CFLAGS POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'elif PLATFORM == 'armcc':# toolchainsCC = 'armcc'CXX = 'armcc'AS = 'armasm'AR = 'armar'LINK = 'armlink'TARGET_EXT = 'axf'DEVICE = ' --cpu Cortex-M4.fp 'CFLAGS = '-c ' + DEVICE + ' --apcs=interwork --c99'AFLAGS = DEVICE + ' --apcs=interwork 'LFLAGS = DEVICE + ' --scatter "board\linker_scripts\link.sct" --info sizes --info totals --info unused --info veneers --list rt-thread.map --strict'CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCC/include'LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCC/lib'CFLAGS += ' -D__MICROLIB 'AFLAGS += ' --pd "__MICROLIB SETA 1" 'LFLAGS += ' --library_type=microlib 'EXEC_PATH += '/ARM/ARMCC/bin/'if BUILD == 'debug':CFLAGS += ' -g -O0'AFLAGS += ' -g'else:CFLAGS += ' -O2'CXXFLAGS = CFLAGS CFLAGS += ' -std=c99'POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'elif PLATFORM == 'iar':# toolchainsCC = 'iccarm'CXX = 'iccarm'AS = 'iasmarm'AR = 'iarchive'LINK = 'ilinkarm'TARGET_EXT = 'out'DEVICE = '-Dewarm'CFLAGS = DEVICECFLAGS += ' --diag_suppress Pa050'CFLAGS += ' --no_cse'CFLAGS += ' --no_unroll'CFLAGS += ' --no_inline'CFLAGS += ' --no_code_motion'CFLAGS += ' --no_tbaa'CFLAGS += ' --no_clustering'CFLAGS += ' --no_scheduling'CFLAGS += ' --endian=little'CFLAGS += ' --cpu=Cortex-M4'CFLAGS += ' -e'CFLAGS += ' --fpu=VFPv4_sp'CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"'CFLAGS += ' --silent'AFLAGS = DEVICEAFLAGS += ' -s+'AFLAGS += ' -w+'AFLAGS += ' -r'AFLAGS += ' --cpu Cortex-M4'AFLAGS += ' --fpu VFPv4_sp'AFLAGS += ' -S'if BUILD == 'debug':CFLAGS += ' --debug'CFLAGS += ' -On'else:CFLAGS += ' -Oh'LFLAGS = ' --config "board/linker_scripts/link.icf"'LFLAGS += ' --entry __iar_program_start'CXXFLAGS = CFLAGSEXEC_PATH = EXEC_PATH + '/arm/bin/'POST_ACTION = 'ielftool --bin $TARGET rtthread.bin'def dist_handle(BSP_ROOT, dist_dir):import syscwd_path = os.getcwd()sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools'))from sdk_dist import dist_do_buildingdist_do_building(BSP_ROOT, dist_dir)

    總結

    以上是生活随笔為你收集整理的rtthread_scons简介的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。