RT_Thread組件開(kāi)發(fā)

一筷黔、文件系統(tǒng)

  • RT-Thread 文件系統(tǒng)結(jié)構(gòu)圖
    • 最頂層是一套面向嵌入式系統(tǒng)面殖,專門優(yōu)化過(guò)的設(shè)備虛擬文件系統(tǒng) POSIX 文件接口
    • 中間層是各種文件系統(tǒng)的實(shí)現(xiàn)
      • 比如 ELM FatFS、RomFS、devfs刷晋、RamFS记焊、Yaffs2袱讹、Uffs2面睛、JFFS2 、NFS 等
    • 最底層是各類存儲(chǔ)設(shè)備驅(qū)動(dòng)
      • 初始化存儲(chǔ)設(shè)備并向上層提供存儲(chǔ)設(shè)備的驅(qū)動(dòng)接口冲甘。存儲(chǔ)設(shè)備的類型可能是 SPI Flash绩卤,SD卡 等
image

1.文件系統(tǒng)的移植

1)開(kāi)啟/配置 DFS 框架

  • 進(jìn)入menuconfig : RT-Thread Components → Device virtual file system

    • [x] Using device virtual file system : 使用設(shè)備虛擬文件系統(tǒng),即 RT-Thread 文件系統(tǒng)江醇。
    • [x] Using working directory : 打開(kāi)這個(gè)選項(xiàng)濒憋,在 finsh/msh 中就可以使用基于當(dāng)前工作目錄的相對(duì)路徑。
    • [ ] The maximal number of mounted file system : 最大掛載文件系統(tǒng)的數(shù)量嫁审。
    • [ ] The maximal number of file system type : 最大支持文件系統(tǒng)類型的數(shù)量。
    • [ ] The maximal number of opened files : 打開(kāi)文件的最大數(shù)量赖晶。
    • [x] Enable elm-chan fatfs : 使用 elm-chan FatFs律适,用于掛載在spi flash等存儲(chǔ)設(shè)備上。
      • elm-chan's FatFs, Generic FAT Filesystem Module : elm-chan 文件系統(tǒng)的配置項(xiàng)遏插。
    • [x] Using devfs for device objects : 開(kāi)啟 devfs 文件系統(tǒng)捂贿。
    • [ ] Enable BSD socket operated by file system API : 使 BSD socket 可以使用文件系統(tǒng)的 API 來(lái)管理,比如讀寫操作和 select/poll 的 POSIX API 調(diào)用胳嘲。
    • [x] Enable ReadOnly file system on flash : 在 Flash 上使用只讀文件系統(tǒng)RomFS厂僧。
    • [ ] Enable RAM file system : 使用 RAM 文件系統(tǒng)。
    • [ ] Enable UFFS file system: Ultra-low-cost Flash File System :使用 UFFS了牛。
    • [ ] Enable JFFS2 file system : 使用 JFFS2 文件系統(tǒng)颜屠。
    • [ ] Using NFS v3 client file system :使用 NFS 文件系統(tǒng)。

    配置和指定文件系統(tǒng)

2)存儲(chǔ)設(shè)備驅(qū)動(dòng)初始化

  • 根據(jù)所使用的儲(chǔ)存設(shè)備鹰祸,如 SPI Flash甫窟,SD卡,初始化其驅(qū)動(dòng)

  • 如:RT-Thread Components → Device Drivers 界面中選中 Using SPI Bus/Device device drivers 以及 Using Serial Flash Universal Driver 選項(xiàng)蛙婴,

  • 檢查儲(chǔ)存設(shè)備驅(qū)動(dòng)

    編譯程序并下載到開(kāi)發(fā)板上

    list_device #查看是否識(shí)別到有spi 驅(qū)動(dòng)
    sf probe xxx #檢測(cè)spi設(shè)備接口下是否有 spi flash
    sf bench yes #對(duì)存儲(chǔ)設(shè)備進(jìn)行測(cè)試
    

3)創(chuàng)建存儲(chǔ)設(shè)備

  • 由于只有塊設(shè)備類型的設(shè)備才能和文件系統(tǒng)對(duì)接粗井,所以需要根據(jù) SPI Device 找到 SPI Flash 設(shè)備,并創(chuàng)建與其對(duì)應(yīng)的 Block Device街图。

  • 在drv_spi_flash.c文件中添加如下函數(shù)浇衬,注冊(cè)塊設(shè)備

    static int rt_hw_spi_flash_with_sfud_init(void)
    {
        //使用spi50 設(shè)備接口注冊(cè)W25Q256塊設(shè)備
        if (RT_NULL == rt_sfud_flash_probe("W25Q256", "spi50"))
        {
            return RT_ERROR;
        };
    
      return RT_EOK;
    }
    INIT_COMPONENT_EXPORT(rt_hw_spi_flash_with_sfud_init);
    
  • 重新編譯下載程序,使用list_device命令可以找到W25Q256設(shè)備

    image

2.文件系統(tǒng)使用

1)文件系統(tǒng)的初始化

  • 初始化 DFS 框架
    • 初始化文件系統(tǒng)必須的數(shù)據(jù)表餐济,以及互斥鎖
    • 由dfs_init函數(shù)完成
  • 初始化具體文件系統(tǒng)
    • 將所選擇的elm FatFS 等文件系統(tǒng)的操作函數(shù)注冊(cè)到 DFS 框架中
    • 由elm_init等函數(shù)完成
  • 初始化存儲(chǔ)設(shè)備

2)在存儲(chǔ)設(shè)備創(chuàng)建文件系統(tǒng)

存儲(chǔ)設(shè)備上需要先創(chuàng)建相應(yīng)的文件系統(tǒng)耘擂,才能掛載文件系統(tǒng)

當(dāng)重啟開(kāi)發(fā)板直接掛載文件系統(tǒng),就會(huì)看到 spi flash mount to /spi failed! 的提示絮姆,因?yàn)榇藭r(shí)在 SPI Flash 中還沒(méi)有創(chuàng)建相應(yīng)類型的文件系統(tǒng)梳星。

  • 在存儲(chǔ)設(shè)備上創(chuàng)建相應(yīng)的文件系統(tǒng)

    • 使用mkfs命令:mkfs [-t type] device

      mkfs -t elm W25Q256
      #文件系統(tǒng)創(chuàng)建完成后需要重啟設(shè)備
      

3)掛載文件系統(tǒng)

文件系統(tǒng)的掛載指的是將文件系統(tǒng)和具體的存儲(chǔ)設(shè)備關(guān)聯(lián)起來(lái)赞赖,并掛載到某個(gè)掛載點(diǎn),這個(gè)掛載點(diǎn)即為這個(gè)文件系統(tǒng)的根目錄冤灾。

  • 在rt_application_init函數(shù)初始化的線程中調(diào)用api函數(shù)掛載文件系統(tǒng)(如application.c的rt_init_thread_entry函數(shù))

    //掛載romfs到根目錄/
    if (dfs_mount(RT_NULL, "/", "rom", 0, &(romfs_root)) == 0)
    {
        rt_kprintf("ROM file system initializated!\n");
    }
    
    //將elm FatFS文件系統(tǒng)與W25Q256設(shè)備關(guān)聯(lián)前域,并掛載到/spi目錄下
    /* mount sd card fat partition 0 as root directory */
    if (dfs_mount("W25Q256", "/spi", "elm", 0, 0) == 0)
    {
        rt_kprintf("spi flash mount to /spi !\n");
    }
    else
    {
        rt_kprintf("spi flash mount to /spi failed!\n");
    }
    
    //將elm FatFS文件系統(tǒng)與sd0設(shè)備關(guān)聯(lián),并掛載到/sdcard目錄下
    /* mount sd card fat partition 0 as root directory */
    if (dfs_mount("sd0", "/sdcard", "elm", 0, 0) == 0)
    {
        rt_kprintf("sd card mount to /sdcard!\n");        
    }
    else
    {
        rt_kprintf("sd card mount to /sdcard failed!\n");
    }
    

3.文件與目錄操作 shell 命令

  • 文件系統(tǒng)的操作命令在 RT-Thread online packages → miscellaneous packages → samples: kernel and components sample -> filesystem sample options中選擇.
    • 默認(rèn)命令有l(wèi)s韵吨、cd匿垄、cp、rm归粉、mv椿疗、ifconfig、echo糠悼、cat届榄、pwd、mkdir等
    • 文件系統(tǒng)提供的 Sample 還有 openfile倔喂、readwrite铝条、stat、rename席噩、opendir班缰、readdir 、 tell_seek_dir等命令
    • 添加新的sample會(huì)在工程中添加新的文件夾

二悼枢、FinSH shell

  • finsh運(yùn)行于開(kāi)發(fā)板埠忘,它可以使用串口/以太網(wǎng)/USB等與PC機(jī)進(jìn)行通信,提供一套供用戶在命令行的操作接口馒索。

  • finsh是一個(gè)C語(yǔ)言風(fēng)格的Shell莹妒,在finsh shell中使用命令(即C語(yǔ)言中的函數(shù)),必須攜帶()符號(hào)绰上,finsh命令的輸出為此函數(shù)的返回值动羽。

  • finsh支持兩種模式:

    • C語(yǔ)言解釋器模式,為行文方便稱之為c-style渔期;

      #列舉支持的命令
      finsh >list()
      --Function List:
      pinMode          -- set hardware pin mode
      pinWrite         -- write value to hardware pin
      pinRead          -- read status from hardware pin
      hello            -- say hello world
      version          -- show RT-Thread version information
      list_thread      -- list thread
      list_sem         -- list semaphore in system
      list_event       -- list event in system
      list_mutex       -- list mutex in system
      list_mailbox     -- list mail box in system
      list_msgqueue    -- list message queue in system
      list_memheap     -- list memory heap in system
      list_mempool     -- list memory pool in system
      list_timer       -- list timer in system
      list_device      -- list device in system
      list             -- list all symbol in system
      msh              -- use module shell
      --Variable List:
      dummy            -- dummy variable for finsh
      
      #測(cè)試命令格式
      finsh >hello()
      finsh >version()
      
    • 傳統(tǒng)命令行模式运吓,此模式又稱為msh(module shell)。

      #列舉支持的命令
      msh >help
      RT-Thread shell commands:
      reboot           - Reboot System
      version          - show RT-Thread version information
      list_thread      - list thread
      list_sem         - list semaphore in system
      list_event       - list event in system
      list_mutex       - list mutex in system
      list_mailbox     - list mail box in system
      list_msgqueue    - list message queue in system
      list_memheap     - list memory heap in system
      list_mempool     - list memory pool in system
      list_timer       - list timer in system
      list_device      - list device in system
      exit             - return to RT-Thread shell mode.
      help             - RT-Thread shell help.
      ps               - List threads in the system.
      time             - Execute command with time.
      free             - Show the memory usage in the system.
      
      #測(cè)試命令格式
      msh >help
      msh >version
      
  • 所以的finsh命令或msh命令都是在cmd.c文件中導(dǎo)出的

    • finsh命令通過(guò)宏定義FINSH_FUNCTION_EXPORT導(dǎo)出
    • msh命令通過(guò)宏定義MSH_CMD_EXPORT導(dǎo)出

三疯趟、動(dòng)態(tài)模塊

1.簡(jiǎn)介

  • dlmodule 則是 RT-Thread 下拘哨,在內(nèi)核空間對(duì)外提供的動(dòng)態(tài)模塊加載機(jī)制的軟件組件。
    • dlmodule 組件更多的是一個(gè) ELF 格式加載器信峻,把單獨(dú)編譯的一個(gè) elf 文件的代碼段倦青,數(shù)據(jù)段加載到內(nèi)存中,并對(duì)其中的符號(hào)進(jìn)行解析盹舞,綁定到內(nèi)核導(dǎo)出的 API 地址上产镐。
      • 動(dòng)態(tài)模塊被系統(tǒng)加載到內(nèi)存的

[圖片上傳失敗...(image-dd0ae4-1563508716000)]

  • 動(dòng)態(tài)模塊 elf 文件需要放置于 RT-Thread 下的文件系統(tǒng)上

  • RT-Thread 的動(dòng)態(tài)模塊支持兩種格式:

    • .mo 動(dòng)態(tài)模塊隘庄;它可以被加載,并且系統(tǒng)中會(huì)自動(dòng)創(chuàng)建一個(gè)主線程執(zhí)行這個(gè)動(dòng)態(tài)模塊中的 main 函數(shù)癣亚;同時(shí)這個(gè) main(int argc, char**argv) 函數(shù)也可以接受命令行上的參數(shù)丑掺。
    • .so 動(dòng)態(tài)庫(kù);它可以被加載述雾,并駐留在內(nèi)存中街州,并提供一些函數(shù)集由其他程序(內(nèi)核里的代碼或動(dòng)態(tài)模塊)來(lái)使用。

2.編譯固件

  • 進(jìn)入bsp庫(kù)玻孟,執(zhí)行:menuconfig 唆缴,選擇

    RT-Thread Components  --->
           POSIX layer and C standard library  --->
               [*] Enable dynamic module with dlopen/dlsym/dlclose feature
               
    RT-Thread Components  --->
            Device virtual file system  --->
                   [*] Using device virtual file system
    
  • 在編譯文件rtconfig.py中添加動(dòng)態(tài)模塊編譯時(shí)需要的配置參數(shù)

    #CXXFLAGS = CFLAGS + ' -Woverloaded-virtual -fno-exceptions -fno-rtti'
    M_CFLAGS = CFLAGS + '-mlong-calls -fPIC'
    M_CXXFLAGS = CXXFLAGS + '-mlong-calls -fPIC'
    M_LFLAGS = DEVICE + CXXFLAGS + '-Wl,--gc-sections,-z,max-page-size=0x4' +\
                                    '-shared -fPIC -nostartfiles -nostdlib -static-libgcc' 
                                    
    M_POST_ACTION = STRIP + '-R .hash $TARGET\n' + SIZE + '$TARGET \n'
    M_BIN_PATH = r'E:\qemu-dev310\fatdisk\root'
    
  • 在鏈接腳本xxx.ld中添加對(duì)應(yīng)的信息

    /* section information for modules */
    . = ALIGN(4);
    __rtmsymtab_start = .;
    KEEP(*(RTMSymTab))
    __rtmsymtab_end = .;
    
  • 執(zhí)行編譯

    scons #使用動(dòng)態(tài)模塊只能使用gcc編譯
    
    #生成編譯動(dòng)態(tài)模塊時(shí)需要包括的內(nèi)核頭文件搜索路徑及全局宏定義
    scons --target=ua -s
    

3.編譯動(dòng)態(tài)模塊

在 github 上有一份獨(dú)立倉(cāng)庫(kù): rtthread-apps ,這份倉(cāng)庫(kù)中放置了一些和動(dòng)態(tài)模塊黍翎。

目錄名 說(shuō)明
cxx 演示了如何在動(dòng)態(tài)模塊中使用 C++ 進(jìn)行編程
hello 最簡(jiǎn)單的 hello world 示例
lib 動(dòng)態(tài)庫(kù)的示例
md5 為一個(gè)文件產(chǎn)生 md5 碼
tools 動(dòng)態(tài)模塊編譯時(shí)需要使用到的 Python/SConscript 腳本
ymodem 通過(guò)串口以 YModem 協(xié)議下載一個(gè)文件到文件系統(tǒng)上
  • 執(zhí)行編譯
#指向到 RT-Thread 代碼的根目錄
set RTT_ROOT=E:\@Git_Depository\rt-thread
#指向到 BSP 的工程目錄
set BSP_ROOT=E:\@Git_Depository\rt-thread\bsp\stm32f429-apollo #注意工程路徑

#編譯hello/動(dòng)態(tài)模塊
scons --app=hello

#編譯lib/動(dòng)態(tài)庫(kù)
scons --lib=lib

? 編譯成功會(huì)生成xxx.mo文件面徽,將文件放置到rt-thread的文件系統(tǒng)上,就可以執(zhí)行匣掸。

4.動(dòng)態(tài)模塊開(kāi)發(fā)

在msh命令中輸入list_symbol命令趟紊。可以看到內(nèi)核符號(hào)表(kernel symbol table)所映射的函數(shù)旺聚,這些函數(shù)就是模塊模塊開(kāi)發(fā)當(dāng)前能使用的函數(shù)

msh /spi>list_module
module   ref      address 
-------- -------- ------------
msh /spi>list_sy    
list_symbols
msh /spi>list_symbols\
list_symbols\: command not found.
msh /spi>list_symbols 
rt_tick_get => 0x0800c4e1
rt_tick_from_millisecond => 0x0800c53d
rt_device_register => 0x0800c6b1
rt_device_unregister => 0x0800c715
rt_device_find => 0x0800c781
rt_device_create => 0x0800c811
rt_device_destroy => 0x0800c85d
rt_device_open => 0x0800c941
rt_device_close => 0x0800ca5d
rt_device_read => 0x0800caf9
rt_device_write => 0x0800cb81
rt_device_control => 0x0800cc09
rt_device_set_rx_indicate => 0x0800cc71
rt_device_set_tx_complete => 0x0800ccc5
rt_sem_init => 0x0800d06d
rt_sem_detach => 0x0800d0d5
rt_sem_create => 0x0800d149
rt_sem_delete => 0x0800d1d9
rt_sem_take => 0x0800d285
rt_sem_trytake => 0x0800d3e5
rt_sem_release => 0x0800d401
rt_sem_control => 0x0800d4a1
rt_mutex_init => 0x0800d525
rt_mutex_detach => 0x0800d58d
rt_mutex_create => 0x0800d609
rt_mutex_delete => 0x0800d695
rt_mutex_take => 0x0800d741
rt_mutex_release => 0x0800d91d
rt_mutex_control => 0x0800dabd
rt_event_init => 0x0800db0d
rt_event_detach => 0x0800db61
rt_event_create => 0x0800dbdd
rt_event_delete => 0x0800dc51
rt_event_send => 0x0800dcfd
rt_event_recv => 0x0800de45
rt_event_control => 0x0800e041
rt_mb_init => 0x0800e0c1
rt_mb_detach => 0x0800e139
rt_mb_create => 0x0800e1bd
rt_mb_delete => 0x0800e279
rt_mb_send_wait => 0x0800e339
rt_mb_send => 0x0800e541
rt_mb_recv => 0x0800e561
rt_mb_control => 0x0800e795
rt_mq_init => 0x0800e829
rt_mq_detach => 0x0800e8e9
rt_mq_create => 0x0800e965
rt_mq_delete => 0x0800ea65
rt_mq_send => 0x0800eb1d
rt_mq_urgent => 0x0800ec71
rt_mq_recv => 0x0800edb5
rt_mq_control => 0x0800f001
rt_interrupt_enter => 0x0800f0b5
rt_interrupt_leave => 0x0800f0f5
rt_interrupt_get_nest => 0x0800f135
rt_hw_interrupt_disable => 0x080001ad
rt_hw_interrupt_enable => 0x080001b5
rt_get_errno => 0x0800f14d
rt_set_errno => 0x0800f185
_rt_errno => 0x0800f1c5
rt_memset => 0x0800f1f9
rt_memcpy => 0x0800f2b1
rt_memmove => 0x0800f385
rt_memcmp => 0x0800f409
rt_strstr => 0x0800f461
rt_strcasecmp => 0x0800f4c1
rt_strncpy => 0x0800f525
rt_strncmp => 0x0800f589
rt_strcmp => 0x0800f5d5
rt_strnlen => 0x0800f619
rt_strlen => 0x0800f659
rt_strdup => 0x0800f689
rt_show_version => 0x0800f6c5
rt_vsnprintf => 0x0800f98d
rt_snprintf => 0x0800fed5
rt_vsprintf => 0x0800ff05
rt_sprintf => 0x0800ff29
rt_console_get_device => 0x0800ff55
rt_console_set_device => 0x0800ff6d
rt_hw_console_output => 0x0800ffb9
rt_kprintf => 0x0800ffcd
rt_malloc_align => 0x0801004d
rt_free_align => 0x080100bd
rt_assert_handler => 0x0801014d
rt_malloc => 0x080103c5
rt_realloc => 0x08010659
rt_calloc => 0x080107f1
rt_free => 0x0801082d
rt_memheap_init => 0x080109f9
rt_memheap_detach => 0x08010b3d
rt_memheap_alloc => 0x08010bb1
rt_memheap_realloc => 0x08010da9
rt_memheap_free => 0x080110b9
rt_mp_init => 0x080112ed
rt_mp_detach => 0x080113bd
rt_mp_create => 0x08011469
rt_mp_delete => 0x08011575
rt_mp_alloc => 0x08011661
rt_mp_free => 0x080117bd
rt_object_get_information => 0x080118c1
rt_enter_critical => 0x08012099
rt_exit_critical => 0x080120c5
rt_critical_level => 0x08012119
rt_thread_init => 0x08012365
rt_thread_self => 0x080123d1
rt_thread_startup => 0x080123e9
rt_thread_detach => 0x08012489
rt_thread_create => 0x0801254d
rt_thread_delete => 0x080125b1
rt_thread_yield => 0x08012659
rt_thread_delay => 0x0801275d
rt_thread_mdelay => 0x08012775
rt_thread_control => 0x08012795
rt_thread_suspend => 0x08012869
rt_thread_resume => 0x08012911
rt_thread_timeout => 0x080129a9
rt_thread_find => 0x08012a2d
rt_timer_init => 0x08012c11
rt_timer_detach => 0x08012c59
rt_timer_create => 0x08012cd5
rt_timer_delete => 0x08012d15
rt_timer_start => 0x08012d95
rt_timer_stop => 0x08012f91
rt_timer_control => 0x08013025
dfs_subdir => 0x08013b11
dfs_normalize_path => 0x08013b61
open => 0x0801517d
close => 0x080151e9
read => 0x0801523d
write => 0x08015299
lseek => 0x080152f5
rename => 0x080153a9
unlink => 0x080153d9
stat => 0x08015405
fstat => 0x08015435
fsync => 0x080154ad
fcntl => 0x080154e9
ioctl => 0x08015555
statfs => 0x08015589
mkdir => 0x080155b9
rmdir => 0x08015631
opendir => 0x0801565d
readdir => 0x080156f5
telldir => 0x080157b1
seekdir => 0x080157fd
rewinddir => 0x08015851
closedir => 0x080158a5
chdir => 0x08015905
getcwd => 0x080159b1
system => 0x0801dce5
strcpy => 0x08046d3d
strncpy => 0x08046ec1
strlen => 0x080007c1
strcat => 0x08046c2d
strstr => 0x08047205
strchr => 0x08046c6d
strcmp => 0x080004e9
strtol => 0x08047581
strtoul => 0x08047739
strncmp => 0x08046e21
memcpy => 0x08000391
memcmp => 0x08045dc1
memmove => 0x08045e25
memset => 0x08045eed
memchr => 0x080002f1
putchar => 0x08046565
puts => 0x08046635
printf => 0x0804653d
sprintf => 0x08046b55
snprintf => 0x08046ab9
fwrite => 0x08045a51
localtime => 0x08045a71
time => 0x08023a15
longjmp => 0x080004d1
setjmp => 0x080004c5
exit => 0x0802398d
abort => 0x080239e1
rand => 0x08046645
__assert_func => 0x08045149
dlclose => 0x08023a89
dlerror => 0x08024951
dlmodule_find => 0x08025315
dlopen => 0x080253f5
dlsym => 0x080254bd
lwip_accept => 0x0802960d
lwip_bind => 0x080298a5
lwip_shutdown => 0x0802abb1
lwip_getpeername => 0x0802adc9
lwip_getsockname => 0x0802aded
lwip_getsockopt => 0x0802ae11
lwip_setsockopt => 0x0802b369
lwip_close => 0x080299a1
lwip_connect => 0x08029a55
lwip_listen => 0x08029b71
lwip_recv => 0x08029fe9
lwip_read => 0x08029fbd
lwip_recvfrom => 0x08029c3d
lwip_send => 0x0802a015
lwip_sendto => 0x0802a0e1
lwip_socket => 0x0802a251
lwip_write => 0x0802a309
lwip_select => 0x0802a5c9
lwip_ioctl => 0x0802b791
lwip_fcntl => 0x0802b911
lwip_htons => 0x0802bd4d
lwip_htonl => 0x0802bd69
lwip_gethostbyname => 0x08028e39
lwip_gethostbyname_r => 0x08028ed1
lwip_freeaddrinfo => 0x08028fd1
lwip_getaddrinfo => 0x08028ffd
dhcp_start => 0x08036c49
dhcp_renew => 0x080371d9
dhcp_stop => 0x08037629
netifapi_netif_set_addr => 0x08029329
netif_set_link_callback => 0x0802d879
netif_set_status_callback => 0x0802d791
netif_find => 0x0802d4a9
netif_set_addr => 0x0802d451
netif_set_ipaddr => 0x0802d519
netif_set_gw => 0x0802d5bd
netif_set_netmask => 0x0802d5f5
gethostbyname => 0x0803cf21
gethostbyname_r => 0x0803cf39
freeaddrinfo => 0x0803cf65
getaddrinfo => 0x0803cf7d
accept => 0x0803d315
bind => 0x0803d3c9
shutdown => 0x0803d3f1
getpeername => 0x0803d475
getsockname => 0x0803d49d
getsockopt => 0x0803d4c5
setsockopt => 0x0803d4f5
connect => 0x0803d525
listen => 0x0803d54d
recv => 0x0803d571
recvfrom => 0x0803d5a5
send => 0x0803d5d9
sendto => 0x0803d60d
socket => 0x0803d641
closesocket => 0x0803d6d9
ioctlsocket => 0x0803d759
rt_completion_init => 0x08042df9
rt_completion_wait => 0x08042e3d
rt_completion_done => 0x08042f39
rt_data_queue_init => 0x08043025
rt_data_queue_push => 0x080430a9
rt_data_queue_pop => 0x08043239
rt_data_queue_peak => 0x0804341d
rt_data_queue_reset => 0x080434b9
rt_rbb_init => 0x08043691
rt_rbb_create => 0x08043731
rt_rbb_destroy => 0x080437ad
rt_rbb_blk_alloc => 0x08043859
rt_rbb_blk_put => 0x08043a59
rt_rbb_blk_get => 0x08043a9d
rt_rbb_blk_size => 0x08043b25
rt_rbb_blk_buf => 0x08043b59
rt_rbb_blk_free => 0x08043b89
rt_rbb_blk_queue_get => 0x08043c09
rt_rbb_blk_queue_len => 0x08043d21
rt_rbb_blk_queue_buf => 0x08043d85
rt_rbb_blk_queue_free => 0x08043db5
rt_rbb_next_blk_queue_len => 0x08043e25
rt_rbb_get_buf_size => 0x08043edd
rt_ringbuffer_init => 0x08043f5d
rt_ringbuffer_put => 0x08044001
rt_ringbuffer_put_force => 0x0804416d
rt_ringbuffer_get => 0x0804433d
rt_ringbuffer_putchar => 0x08044499
rt_ringbuffer_putchar_force => 0x08044551
rt_ringbuffer_getchar => 0x0804464d
rt_ringbuffer_data_len => 0x08044701
rt_ringbuffer_reset => 0x08044785
rt_ringbuffer_create => 0x080447d9
rt_ringbuffer_destroy => 0x0804484d

上述函數(shù)主要來(lái)自于rt-thread/src/xx.c文件织阳、rt-thread/components/使用的組件xxx/src/xx.c文件

1)導(dǎo)出函數(shù)到內(nèi)核符號(hào)表

通過(guò)宏定義RTM_EXPORT(symbol) 眶蕉,可以將函數(shù)導(dǎo)出到符號(hào)表砰粹。

RTM_EXPORT(rt_timer_control);

2)動(dòng)態(tài)模塊操作片級(jí)資源

  • 操作gpio

    • rt-thread\components\drivers\misc\pin.c默認(rèn)沒(méi)有把rt_pin_mode、rt_pin_write造挽、rt_pin_read等函數(shù)添加到符號(hào)表碱璃,需要人為添加
      • STM32F429-apollo是基于STM32F4xx_PIN_NUMBERS == 176的芯片,參考rt-thread\bsp\stm32f429-apollo\drivers\drv_gpio.c的pins[]數(shù)組饭入,PB.0和PB.1分別對(duì)應(yīng)index 56和57嵌器。
    #include <stdio.h>
    #include <board.h>
    #include <rtthread.h>
    #include <rtdevice.h>
    #include <rthw.h>
    
    int main(int argc, char *argv[])
    {
        rt_pin_mode(56, PIN_MODE_OUTPUT);
    
        printf("Hello, world1\n");
        while (1)
        {
            rt_pin_write(56, PIN_HIGH);
            rt_thread_mdelay(2000);
            rt_pin_write(56, PIN_LOW);
            rt_thread_mdelay(2000);
        }
        return 0;
    }
    
    

5.對(duì)動(dòng)態(tài)模塊的操作

1)動(dòng)態(tài)模塊的結(jié)構(gòu)體

rt_dlmodule結(jié)構(gòu)體

struct rt_dlmodule
{
    struct rt_object parent;
    rt_list_t object_list;  /* objects inside this module */

    rt_uint8_t stat;        /* status of module */ //動(dòng)態(tài)模塊的狀態(tài) 

    /* main thread of this module */
    rt_uint16_t priority;
    rt_uint32_t stack_size;
    struct rt_thread *main_thread;
    /* the return code */
    int ret_code;

    /* VMA base address for the first LOAD segment */
    rt_uint32_t vstart_addr;

    /* module entry, RT_NULL for dynamic library */
    rt_dlmodule_entry_func_t  entry_addr;
    char *cmd_line;         /* command line */

    rt_addr_t   mem_space;  /* memory space */
    rt_uint32_t mem_size;   /* sizeof memory space */

    /* init and clean function */
    rt_dlmodule_init_func_t     init_func;
    rt_dlmodule_cleanup_func_t  cleanup_func;

    rt_uint16_t nref;       /* reference count */

    rt_uint16_t nsym;       /* number of symbols in the module */
    struct rt_module_symtab *symtab;    /* module symbol table */
};

2)動(dòng)態(tài)模塊API

動(dòng)態(tài)模塊API函數(shù)在rt-thread\components\libc\libdl\dlmodule.c文件中定義。

#include "dlmodule.h"

//加載動(dòng)態(tài)模塊
struct rt_dlmodule *dlmodule_load(const char* pgname);
//執(zhí)行動(dòng)態(tài)模塊
struct rt_dlmodule *dlmodule_exec(const char* pgname, const char* cmd, int cmd_size);
//退出動(dòng)態(tài)模塊
void dlmodule_exit(int ret_code);
//查找動(dòng)態(tài)模塊
struct rt_dlmodule *dlmodule_find(const char *name);
//返回動(dòng)態(tài)模塊:返回調(diào)用上下文環(huán)境下動(dòng)態(tài)模塊的指針
struct rt_dlmodule *dlmodule_self(void);
//查找符號(hào)
rt_uint32_t dlmodule_symbol_find(const char *sym_str);

  • 在keil工程中是不會(huì)添加dlmodule.c的谐丢,但是在gcc工程中已經(jīng)包含其路徑爽航。

停止動(dòng)態(tài)模塊

rt_err_t dlmodule(uint8_t argc, char **argv)
{
    rt_err_t res = 0;
    struct rt_dlmodule *module;
    
    if (argc != 2) {
        rt_kprintf("uasge:dlmodule name\n");
        return 0;
    }
    module = dlmodule_find(argv[1]);

    if ( module != RT_NULL) {
        //close dlmodule
        module->stat = RT_DLMODULE_STAT_CLOSING;
        rt_timer_stop(&(module->main_thread->thread_timer));
        res = rt_thread_delete(module->main_thread);
        
    } else {
        rt_kprintf("dlmodule find fail\n");
    }

    return res;
}

MSH_CMD_EXPORT(dlmodule, find dlmodule symbol);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市乾忱,隨后出現(xiàn)的幾起案子讥珍,更是在濱河造成了極大的恐慌,老刑警劉巖窄瘟,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衷佃,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蹄葱,警方通過(guò)查閱死者的電腦和手機(jī)氏义,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門锄列,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人惯悠,你說(shuō)我怎么就攤上這事邻邮。” “怎么了吮螺?”我有些...
    開(kāi)封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵饶囚,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我鸠补,道長(zhǎng)萝风,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任紫岩,我火速辦了婚禮规惰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泉蝌。我一直安慰自己歇万,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布勋陪。 她就那樣靜靜地躺著贪磺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诅愚。 梳的紋絲不亂的頭發(fā)上寒锚,一...
    開(kāi)封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音违孝,去河邊找鬼刹前。 笑死,一個(gè)胖子當(dāng)著我的面吹牛雌桑,可吹牛的內(nèi)容都是我干的喇喉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼校坑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拣技!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起耍目,我...
    開(kāi)封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤膏斤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后制妄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體掸绞,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衔掸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烫幕。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖敞映,靈堂內(nèi)的尸體忽然破棺而出较曼,到底是詐尸還是另有隱情,我是刑警寧澤振愿,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布捷犹,位于F島的核電站,受9級(jí)特大地震影響冕末,放射性物質(zhì)發(fā)生泄漏萍歉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一档桃、第九天 我趴在偏房一處隱蔽的房頂上張望枪孩。 院中可真熱鬧,春花似錦藻肄、人聲如沸蔑舞。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)攻询。三九已至,卻和暖如春州弟,著一層夾襖步出監(jiān)牢的瞬間钧栖,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工呆馁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桐经,地道東北人毁兆。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓浙滤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親气堕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子纺腊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容