W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計‧探索‧庚

辛一

辛二

辛三

《説文解字》:辛,秋時萬物成而孰;金剛,味辛,辛痛即泣出。从一,从 辠辠,辠也 。辛承庚,象人股。凡辛之屬皆从辛。

本義:遠古時代用来给奴隸或罪犯刺字的刺刀;在漢字中“辛”通常代表罪行、罪人或施刑。

─── 摘自《《派生》 Python 作坊【辛】岱宗封禪

 

若說我們已經對 GrovePi 這個開源軟硬體 IOT 系統做了詳細的

逆向工程

逆向工程(又稱反向工程),是一種技術過程,即對一專案標產品進行逆向分析及研究,從而演繹並得出該產品的處理流程、組織結構、功能 效能規格等設計要素,以製作出功能相近,但又不完全一樣的產品。逆向工程源於商業及軍事領域中的硬體分析。其主要目的是,在不能輕易獲得必要的生產資訊 下,直接從成品的分析,推匯出產品的設計原理。

逆向工程可能會被誤認為是對智慧財產權的嚴重侵害,但是在實際應用上,反而可能會保護智慧財產權所有者。例如在積體電路領域,如果懷疑某公司侵犯智慧財產權,可以用逆向工程技術來尋找證據。

動機

需要逆向工程的原因如下:

  • 介面設計。由於互操作性,逆向工程被用來找出系統之間的協作協定。
  • 軍事或商業機密。竊取敵人或競爭對手的最新研究或產品原型。
  • 改善文件。當原有的文件有不充分處,又當系統被更新而原設計人員不在時,逆向工程被用來取得所需資料,以補充說明或了解系統的最新狀態。
  • 軟體升級或更新。出於功能、合規、安全等需求更改,逆向工程被用來了解現有或遺留軟體系統,以評估更新或移植系統所需的工作。
  • 製造沒有許可/未授權的副本。
  • 學術/學習目的。
  • 去除複製保護和偽裝的登入權限。
  • 檔案遺失:採取逆向工程的情況往往是在某一個特殊裝置的檔案已經遺失了(或者根本就沒有),同時又找不到工程的負責人。完整的系統時常需要基於陳舊的系統上進行再設計,這就意味著想要整合原有的功能進行專案的唯一方法便是採用逆向工程的方法分析已有的碎片進行再設計。
  • 產品分析:用於調查產品的運作方式,部件構成,估計預算,識別潛在的侵權行為。

───

 

實在是有點奇怪!!若講反思之動機卻是來自懷疑

GrovePi Protocol and Adding Custom Sensors

文本的程式內容??經過了多個篇章的實證,懷疑終能解惑的矣。在此新年伊始之時,樹莓派更新之際,或應隨順 upgrade 系統,並整理修正資訊回饋於眾多 GrovePi 的學習者也。

且趕快加緊腳步

隨著斗轉星移,過去曾經麻煩的事情

Bit-banged I²C kernel driver

by kadamski » Tue Apr 16, 2013 10:10 am

I’ve made a handy kernel module for everybody wanting to use bit-banged host instead (or in addition to) hardware one. It’s like a wrapper for i2c-gpio kernel built-in module that let you dynamically create and remove i2c hosts on different gpio pins. It can be handy if you experience problems with hardware i2c clock stretching or you need more i2c hosts for some reason.

The code and some instructions can be found on my github. You need a custom kernel (with CONFIG_I2C_GPIO enabled) in order to use it. It got some limited testing so it should work but of course I don’t guarantee anything.

Anybody interested in testing this?

……

也已經簡單了。

# Overlay

Name:   i2c-gpio
Info:   Adds support for software i2c controller on gpio pins
Load:   dtoverlay=i2c-gpio,<param>=<val>
Params: i2c_gpio_sda             GPIO used for I2C data (default "23")

        i2c_gpio_scl             GPIO used for I2C clock (default "24")

        i2c_gpio_delay_us        Clock delay in microseconds
                                 (default "2" = ~100kHz)

※請參考『 Linux/drivers/i2c/busses/i2c-gpio.c

 

或許我們也應從善如流,一探春花春景的耶!!

【 dtoverlay=i2c-gpio 】

使用 i2c-gpio 預設值︰ GPIO23 是 SDA , GPIO24 為 SCL ,串接回硬體 I2C : GPIO0 SDA , GPIO1 SCL 。因此樹莓派上有兩個 I2C Master 。

Bit-Banging-I2C

pi@raspberrypi ~ ls /dev/i2c* -l crw-rw---- 1 root i2c 89, 1  1月 29 14:52 /dev/i2c-1 crw-rw---- 1 root i2c 89, 3  1月 29 14:52 /dev/i2c-3 pi@raspberrypi ~ 

都可定址 GrovePi 也。

pi@raspberrypi ~ i2cdetect -y 3      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f 00:          -- -- 05 -- -- -- -- -- -- -- -- -- --  10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  70: -- -- -- -- -- -- -- --                           pi@raspberrypi ~ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- 05 -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
pi@raspberrypi ~ </pre> <span style="color: #808080;"><strong>【 Bit-banged I²C 嚐鮮 】</strong></span>  ……  ── 摘自《<a href="http://www.freesandal.org/?m=20160206">W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計‧探索‧戊</a>》     <span style="color: #666699;">完成 I2C 探索之最後一里路的耶!!</span>  <span style="color: #666699;">令人驚訝的是,一個年過去了!版本也更新了︰</span> <pre class="lang:default decode:true "># rpi-update 後之版本 pi@raspberrypi ~ cat /proc/version 
Linux version 4.1.18-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #845 SMP Thu Feb 18 19:45:28 GMT 2016
pi@raspberrypi ~ </pre>    <span style="color: #666699;">結果竟然幾乎與過年前一樣大同小異︰</span> <pre class="lang:default decode:true "># 修改 grovepi.py ,選用 bus = smbus.SMBus(3) 。   pi@raspberrypi ~/example python
Python 2.7.9 (default, Mar  8 2015, 00:52:26)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import grovepi
>>> addr = 0x05
>>> grovepi.debugEnable()
>>> potentiometer = 0
>>> grovepi.pinMode(potentiometer,"INPUT")
1
>>> grovepi.analogRead(potentiometer)
0
[11, 2, 189, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
702
>>> ultrasonic_ranger = 2
>>> grovepi.ultrasonicRead(ultrasonic_ranger)
0
[11, 0, 3, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
3
>>> power=7
>>> grovepi.pinMode(power,"OUTPUT")
1
>>> grovepi.digitalWrite(power,1)
1
>>> grovepi.digitalWrite(power,0)
1
>>> grovepi.bus.write_i2c_block_data(5, 1, [3] + [0, 0, 0])
>>> grovepi.bus.read_i2c_block_data(5, 1)
[0, 2, 189, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.bus.write_i2c_block_data(5, 1, [3] + [0, 0, 0])
>>> grovepi.read_i2c_byte(addr)
0
>>> grovepi.bus.read_i2c_block_data(5, 1)
[0, 2, 189, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_byte(addr)
0
>>> grovepi.read_i2c_block(addr)
[0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 2, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>>

 

pi@raspberrypi ~ stty -F /dev/ttyUSB0 115200 pi@raspberrypi ~ cat /dev/ttyUSB0
CMD = 5, index =  4
 
CMD = 3, index =  4
 
DATA = 0, 2, 189
 
CMD = 3, index =  0
 
CMD = 7, index =  4
 
DATA = 0, 0, 3
 
CMD = 7, index =  0
 
CMD = 5, index =  4
 
CMD = 2, index =  4
 
CMD = 2, index =  4
 
CMD = 3, index =  4
 
CMD = 3, index =  0
 
DATA = 0, 2, 189
 
CMD = 3, index =  4
 
DATA = 0, 2, 189
 
CMD = 3, index =  0
 
DATA = 0, 2, 189
 
DATA = 0, 2, 189
 
CMD = 1, index =  1
 
DATA = 0, 2, 189
 
CMD = 1, index =  2
 
DATA = 0, 2, 189
 
CMD = 1, index =  3
 
DATA = 0, 2, 189
 
CMD = 1, index =  4
 
DATA = 0, 2, 189
 
CMD = 1, index =  0
#

 

難到應該改變的嗎??若從隨機或快或慢的讀取現象來看︰

>>> grovepi.ultrasonicRead(ultrasonic_ranger)
0
[11, 0, 198, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
198
>>> grovepi.read_i2c_block(addr)
[1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 198, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[11, 198, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_block(addr)
[1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> 
>>> grovepi.read_i2c_byte(addr)
1
>>> grovepi.read_i2c_block(addr)
[1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_byte(addr)
1
>>> grovepi.read_i2c_block(addr)
[1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> grovepi.read_i2c_byte(addr)
1
>>> grovepi.read_i2c_block(addr)
[1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> 

 

CMD = 7, index =  0

CMD = 1, index =  1

DATA = 0, 0, 182

CMD = 1, index =  2

CMD = 1, index =  3

CMD = 1, index =  4

CMD = 1, index =  0

CMD = 1, index =  1

CMD = 1, index =  2

DATA = 0, 0, 182

CMD = 1, index =  3

CMD = 1, index =  4

CMD = 1, index =  0

DATA = 0, 0, 182

DATA = 0, 0, 182

CMD = 1, index = 1

DATA = 0, 0, 182

DATA = 0, 0, 182

CMD = 1, index = 2

DATA = 0, 0, 182

DATA = 0, 0, 182

CMD = 1, index = 3

DATA = 0, 0, 182

 

,或許可以說明即使針對軟體 Bit-banged I²C 而言︰

Extraneous bus.read_byte commands? #169

In various functions in grovepi.py, there are what seem to me to be completely extraneous calls to read_byte, which can just be deleted. Or at least, deleting them doesn’t seem to break anything for me.

e.g. in analogRead it says bus.read_byte(address), then it does the actual read transaction with number = bus.read_i2c_block_data(address, 1). As far as I can tell the bus.read_byte is totally ignored, just does an extra i2c transaction for no reason and makes the code slightly slower.

Maybe I’m missing something and there is a reason for it, but as far as I can tell this is a bug?

When we were building the firmware initially, we found that read_block() didn’t work properly without calling the read_byte() first and this was the way we were able to make it work. It was a workaround then and we seem to have kept it till now.

── 摘自《W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計‧探索‧丙

 

依舊是不可少的也!!!