VxWorks 6.9 內核編程指導之讀書筆記 -- C++開發


  • 5.1 介紹
  • 針對C++的VxWorks配置
  • C++頭文件
  • 使用C++啟動任務
  • C和C++之前調用代碼
  • C++編譯器說明
  • 在信號處理和ISR中使用C++
  • 下載C++編寫的內核模塊
  • C++編譯器的不同
  • 命名空間
  • C++異常處理
  • C++示例

介紹

注意:風河C++編譯器與GNU C++二進制文件不兼容。

針對C++的VxWorks配置

默認情況下,VxWorks只包含了最小的C++支持。可以通過包含所有或部分組件來支持C++的全部或部分功能,

INCLUDE_CTORS_DTORS

默認包含了該組件。確保編譯器產生初始化函數,包括C++靜態對象的初始化,在內核啟動時調用。

INCLUDE_CPLUS

包含C++應用程序的基本支持。通常與INCLUDE_CPLUS_LANG一起使用。

INCLUDE_CPLUS_LANG

包含C++語言特性的支持,如new,delete和異常處理

INCLUDE_CPLUS_IOSTREAM

包含所有類庫功能。

INCLUDE_CPLUS_DEMANGLER

該組件在使用INCLUDE_CPLUS和INCLUDE_SYM_TBL組件時被自動增加。

C++頭文件

每個編譯器都有自己的頭文件和類庫,不必用戶指定所在的文件夾,編譯器將在特定目錄查找。

使用C++啟動任務

任何使用C++啟動的任務都必須使用VX_FP_TASK選項。默認,從主機工具發起的任務自動帶有該選項(如Wind Shell)。

注意:沒有使用該選項,將在運行時導致很難調試的、不可預期的浮點寄存器的損壞。C++的異常處理器將使用浮點寄存器。該選項確保產生異常時,浮點寄存器將被保存和恢復。

C和C++代碼之間的調用

如果在C中調用C++的代碼,則必須使用extern “C”來導出原型。使用下面的方式可以使代碼能被C和C++都調用。

#ifdef _cplusplus

extern "C" void myEntryPoint();

#else

void myEntryPoint();

#endif

C++編譯器的說明

Small data area (SDA)重新分配,只被PowerPC和MIPS支持,C++代碼並不工作。別使用風河Diab編譯器的-Xsmall-const=8 -Xsmall-data=8選項,或GUN編譯器的-G8 -msdata=eabi選項

在信號處理器和ISR中使用C++

在信號處理器和ISR中使用C++代碼必須特別小心。更多信息看信號處理和編寫ISR章節。

下載C++編寫的內核模塊

要下載到VxWorks內核的C++代碼應該被鏈接成單一的可下載對象模塊。它必須被munched,任何COMDAT和linkonce的section必須被填充。

使用單一的C++模塊

VxWorks的加載器只支持自包含的C++模塊。自包含C++模塊就是不使用其它模塊中的類的模塊,它的類也不被其它模塊使用。特別,模塊要么包含標准類庫的一份拷貝,要不根本不使用C++標准類庫。

為了產生自包含模塊,所有可下載的C++對象必須被鏈接成單一的可下載對象模塊。

卸載不是自包含的C++模塊,可能導致其它模塊中創建的對象或數據結構的引用的損壞。如果iostream的標准庫的部分從一個稍后被卸載的模塊中初始化,這是可能發生的。這種情況下,iostream的任何的進一步使用都將導致內核異常(訪問非法地址)。

Munching一個應用程序模塊

在C++模塊被下載到VxWorks內核之前,由於歷史原因,它必須經歷一個額外的步驟,稱為munching。Munching執行以下任務

  1. 對靜態對象的初始化支持
  2. 確保對所有的靜態對象按順序調用正確的構造和析構函數。
  3. 對應風河的編譯器,自動填充COMDAT段;對應GNU編譯器,自動填充linkonce段。

Munching必須在下載之前,編譯之后執行。

Munching的例子

對於每一個工具鏈,下面的例子編譯了一個C++應用程序源碼hello.cpp,在.o上運行munch,編譯產生ctdt.c文件,並連接應用程序和ctdt.o產生可可下載的模塊,hello.out。

使用風河工具鏈 
1. Compile the source code:
$ dcc -tPPC604FH:vxworks61  -Xlocal-data-area-static-only -XO \ 
-IinstallDir/vxworks-6.x/target/h -DCPU=PPC32 -DTOOL_FAMILY=diab -DTOOL=diab \ 
-D_WRS_KERNEL  -c hello.cpp
2. Munch the object file:
$ ddump -Ng hello.o | tclsh \
installDir/vxworks-6.x/host/resource/hutils/tcl/munch.tcl -c ppc > ctdt.c
3. Compile the munch output:
$ dcc -tPPC604FH:vxworks61  -Xlocal-data-area-static-only -XO \ 
-IinstallDir/vxworks-6.x/target/h -DCPU=PPC32 -DTOOL_FAMILY=diab -DTOOL=diab \ 
-D_WRS_KERNEL  -c ctdt.c
4. Link the original object file with the munched object file to create a 
downloadable module: 
$ dld -tPPC604FH:vxworks61 -X -r4 -o hello.out hello.o ctdt.o

注意:-r4選項填充輸入文件中包含的任何COMDAT段。
使用GNU工具鏈
1. Compile the source code:
ccppc -mcpu=604 -mstrict-align  -O2 -fno-builtin \ 
-IinstallDir/vxworks-6.x/target/h \
-DCPU=PPC604 -DTOOL_FAMILY=gnu -DTOOL=gnu -c hello.cpp
2. Munch the object file:
nmppc hello.o | wtxtcl installDir/vxworks-6.x/host/src/hutils/munch.tcl \
-c ppc > ctdt.c
3. Compile the munch output:
ccppc -mcpu=604 -mstrict-align  -fdollars-in-identifiers -O2 \
-fno-builtin -IinstallDir/vxworks-6.x/target/h \
-DCPU=PPC604 -DTOOL_FAMILY=gnu -DTOOL=gnu  -c ctdt.c
4. Link the original object file with the munched object file to create a 
downloadable module: 
ccppc -r -nostdlib -Wl,-X \
-T installDir/vxworks-6.x/target/h/tool/gnu/ldscripts/link.OUT \
-o hello.out hello.o ctdt.o

注意:VxWorks內核對象加載器並不直接支持linkonce段。相反,在加載之前,linkonce段必須被合並和填充到標准的text和data段。-T選項用來填充任何包含的linkonce段。

使用通用的Makefile規則  

如果使用makefile,則可以編寫簡單的munch規則(定義適當的CPU和TOOL),可以在支持GUN和風河工具鏈。

CPU     = PPC604
TOOL    = gnu
TGT_DIR = $(WIND_BASE)/target
include $(TGT_DIR)/h/make/defs.bsp
default : hello.out
%.o : %.cpp
$(CXX) $(C++FLAGS) -c $<
%.out : %.o
$(NM) $*.o | $(MUNCH) > ctdt.c
$(CC) $(CFLAGS) $(OPTION_DOLLAR_SYMBOLS) -c ctdt.c
$(LD_PARTIAL) $(LD_PARTIAL_LAST_FLAGS) -o $@ $*.o ctdt.o

munching、下載和連接之后,靜態構造和析構將被調用。

調用靜態構造和析構

內核加載器提供了自動和手動選項去調用靜態構造和析構。

自動調用是默認策略。靜態構造僅在模塊被下載之后且模塊加載器返回給調用者之前被執行。靜態析構在模塊被卸載之前執行。

手動調用意味着用戶必須在模塊加載之后,顯式調用靜態構造,但是必須在運行應用程序之前。也需要用戶在任務完成之后且在模塊卸載之前,顯式調用析構。

靜態構造可以通過調研cplusCtors來調用。靜態析構通過cplusDtors來調用。這些函數帶有單獨的模塊名稱作為參數。然而,你也可以通過調用這些函數而不帶參數來調用所有的被加載到當前系統的對象的靜態構造和析構。

注意:當使用手動方法時,每個模塊的構造必須只能被調用一次。

可以在運行時,調用cplusXtorSet函數來改變調用策略。可以使用cplusStratShow來得到當前的調用策略。

C++編譯器的不同

風河公司的C++編譯器使用EDG風格(Edison Design Group),完全遵循ANSI C++標准。GUN編譯器支持大部分ANSI C++標准的語言特性。二者的二進制文件並不兼容。因此,編譯VxWorks映像的工具鏈和編譯可下載的內核應用程序必須使用相同的工具鏈。

模板實例化

運行時類型信息

命名空間

無特別之處

C++異常處理

C++異常處理是通過INCLUDE_CPLUS_LANG組件提供的。為了禁用C++異常處理,必須

  1. 在創建VIP項目之前,定義CXX_STL_VARIANT=abridged環境變量。這確保正確的庫被鏈接(異常禁用)。
  2. 為GNU添加-mc++-abr;為Diab添加-Xc++-abr選項。

C++演示

factory例子演示了C++的各種特性,包括STL,用戶定義模板,運行時類型信息RTII及異常處理。代碼位於/target/src/demo/cplusplus/factory。

使用該實例程序,內核必須包含下列組件

  • INCLUDE_CPLUS
  • INCLUDE_CPLUS_LANG
  • INCLUDE_CPLUS_IOSTREAM

另外對於GNU編譯器,還需包含以下組件

  • INCLUDE_CPLUS_STRING
  • INCLUDE_CPLUS_STRING_IO

編譯代碼作為可下載內核模塊,下載到目標板上,並且調用testFactory來啟動。舉個例子,在shell中使用如下命令

ld <factory.out

testFactory

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM