歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Python版DNW

准備全線遷到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.   
  7. if len(sys.argv) == 2 :  
  8.         addr = 0x32000000  
  9. elif len(sys.argv) == 3:  
  10.         addr = int(sys.argv[2], 16)  
  11. else:  
  12.         print 'Usage: dnw filename [address]'  
  13.         quit()  
  14.   
  15. def checksum(data):  
  16.         s = 0  
  17.         for i in data:  
  18.                 s += struct.unpack('B', i)[0];  
  19.         return s&0xffff  
  20.   
  21. content = open(sys.argv[1]).read()  
  22. address = struct.pack('L', addr)  
  23. length = struct.pack('L', len(content) + 10)  
  24. check = struct.pack('H', checksum(address + length + content))  
  25.   
  26. inp = StringIO.StringIO(address + length + content + check)  
  27.   
  28. dev = usb.core.find(idVendor=0x5345, idProduct=0x1234)  
  29. dev.set_configuration()  
  30. ep = dev[0][(0,0)][1]  
  31.   
  32. data = inp.read(512)  
  33. while data:  
  34.         ep.write(data)  
  35.         data = inp.read(512)  
Copyright © Linux教程網 All Rights Reserved