歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Python版DNW

Python版DNW

日期:2017/3/1 10:40:42   编辑:Linux編程

准備全線遷到Linux下做實驗,虛擬機裡編譯太慢了。DNW是個問題。其實DNW到底是個什麼東西我並不清楚,廠家提供的bootloader就是用DNW通過USB線接受PC傳來數據。記得兩年前就見過網友Linux版的DNW。那時沒開始接觸內核,覺得寫這個東西的人真NB。現在把那個代碼找出來看看,原來蠻簡單的。一個內核態的驅動,一個用戶態的程序。通過看用戶態的程序,知道了DNW傳輸的格式,即4字節的下載地址+4字節的傳輸總長度+傳輸內容+2字節的checksum。checksum就是把前面三個部分以unsigned char的形式全部加起來。

後來找到了無需內核態驅動的DNW,借助libusb純在用戶態做。這個蠻不錯,昨晚准備編一個試一下,結果裝了libusb一還干了別的事,到頭到也沒試。今天又找到了一個xdnw,它用QT給DNW做了個UI,還是利用libusb純在用戶態下實現。為了試一下它還特意去裝了QT4,看了下界面,很簡陋。沒有具體使用,不過應該問題不大。

想了半天,還是決定看能不能用Python實現一個。首先要找到能操縱USB的Python模塊。有個叫PyUSB的東西一搜就搜到了。大致掃了一眼它的文檔,覺得蠻簡單的,於是開始著手實現。Python的一些東西還是很不熟悉,搞了幾個小時,總算是搞出來了。不到40行代碼,有效代碼可能還沒有30行,但確實折騰了兩三個小時。偷了不少懶,錯誤處理都沒做,而且直接假定第一個configuration的第一個interface的第一個setting的第二個endpoint是用來輸出的。跟USB相關的代碼只有四行。測試了一下,有時候是正常,有時候傳輸到的內存地址有誤,比如要傳到0x32000000結果終端上顯示傳到0x30000000。

有湊合用吧,以後再慢慢完善。用Python寫的好處在於便是擴展。比如想加個界面,或者作為模塊融入到更大的代碼中,都是很容易的。

  1. #!/usr/bin/python
  2. import usb.core
  3. import StringIO
  4. import struct
  5. import sys
  6. if len(sys.argv) == 2 :
  7. addr = 0x32000000
  8. elif len(sys.argv) == 3:
  9. addr = int(sys.argv[2], 16)
  10. else:
  11. print 'Usage: dnw filename [address]'
  12. quit()
  13. def checksum(data):
  14. s = 0
  15. for i in data:
  16. s += struct.unpack('B', i)[0];
  17. return s&0xffff
  18. content = open(sys.argv[1]).read()
  19. address = struct.pack('L', addr)
  20. length = struct.pack('L', len(content) + 10)
  21. check = struct.pack('H', checksum(address + length + content))
  22. inp = StringIO.StringIO(address + length + content + check)
  23. dev = usb.core.find(idVendor=0x5345, idProduct=0x1234)
  24. dev.set_configuration()
  25. ep = dev[0][(0,0)][1]
  26. data = inp.read(512)
  27. while data:
  28. ep.write(data)
  29. data = inp.read(512)
Copyright © Linux教程網 All Rights Reserved