pymavlink 源碼剖析(二)之生成代碼


相關:

  1. pymavlink 源碼剖析(一)之XML文件的數據解析
  2. MAVLink 協議解析之原理篇;
  3. MAVLink 協議解析之XML定義篇;

1 引言

本文是 pymavlink 源碼剖析 文章的第二篇。上一篇 pymavlink 源碼剖析(一)之XML文件的數據解析 主要是分析 pymavlinkMAVLINK XML 格式的定義文件是如何解析的,這一篇則分析 pymavlink 是如何在解析獲得的結果的基礎上生成目標代碼的。本篇主要關注於 C 的目標代碼生成的實現。
如果對 MAVLink 協議還不太熟悉請參考文章目錄下方 “相關” 裏面給出的鏈接。

2 C 代碼生成

pymavlink 生成 C 的原理是模板填充 — 給出代碼模板然後把從 XML 中解析處的相關參數填充到其中。對應於C 代碼生成的函數主要在 mavgen_c.py 這個文件裏面。 在 mavgen_c.py 文件中定義瞭如下五個函數:

  • generate: 代碼生成入口函數
  • generate_main_h: 生成主頭文件,所謂主頭文件即以 XML 文件名的去掉後綴來命名的文件;
  • generate_mavlink_h: 生成 mavlink.h 文件;
  • generate_message_h: 生成各個message 的頭文件;
  • generate_one: 由 generate 調用,分別對每一個 XML 生成頭文件;
  • generate_version_h: 生成 version.h 文件,其中包括了 MAVLink 的版本號,代碼生成時間等;
  • generate_testsuite_h 生成 testsuite.h 文件,testsuite.h 爲測試生成的頭文件的代碼。

這裏首先從generate 函數看起

代碼段 1

703 def generate(basename, xml_list):
704     '''generate complete MAVLink C implemenation'''
705
706     for idx in range(len(xml_list)):
707         xml = xml_list[idx]
708         xml.xml_idx = idx
709         generate_one(basename, xml)
710     copy_fixed_headers(basename, xml_list[0])

從這段代碼可以看出其只是對傳入進來的 xml_list 列表調用 generate_one 進行解析,然後調用了 copy_fixed_headers 函數進行收尾。 對於generate_one 函數相對略複雜單獨放在 第3節 說明,這裏先分析copy_fixed_headers 函數。

代碼段 2

519 def copy_fixed_headers(directory, xml):
520     '''copy the fixed protocol headers to the target directory'''
521     import shutil, filecmp
522     hlist = {
523         "0.9": [ 'protocol.h', 'mavlink_helpers.h', 'mavlink_types.h', 'checksum.h' ],
524         "1.0": [ 'protocol.h', 'mavlink_helpers.h', 'mavlink_types.h', 'checksum.h', 'mavlink_conversions.h' ],
525         "2.0": [ 'protocol.h', 'mavlink_helpers.h', 'mavlink_types.h', 'checksum.h', 'mavlink_conversions.h',
526                  'mavlink_get_info.h', 'mavlink_sha256.h' ]
527         }
528     basepath = os.path.dirname(os.path.realpath(__file__))
529     srcpath = os.path.join(basepath, 'C/include_v%s' % xml.wire_protocol_version)
530     print("Copying fixed headers for protocol %s to %s" % (xml.wire_protocol_version, directory))
531     for h in hlist[xml.wire_protocol_version]:
532         src = os.path.realpath(os.path.join(srcpath, h))
533         dest = os.path.realpath(os.path.join(directory, h))
534         if src == dest or (os.path.exists(dest) and filecmp.cmp(src, dest)):
535             continue
536         shutil.copy(src, dest)

可以看出,copy_fixed_headers 函數的主要功能就是依據當前的 MAVLink 版本把一些相對不要模板生成的頭文件挨個複製到輸出文件夾下。

3 generate_one 函數分析


TODO

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章