OrangePi PC をクロックダウン

OPI PC にファンをつけて、ついでに sccript.bin を作り直して1.5MHz から1.2MHz にクロックダウンして運用していますが、CPU 温度は30度から40 度を推移しているようです。

h3_temp-day-2

この状態でベンチマークがどのくらいいくかテストしてみました。

   ========================================================================
   BYTE UNIX Benchmarks (Version 5.1.3)
   System: OrangePi: GNU/Linux
   OS: GNU/Linux -- 3.4.39-01-lobo -- #1 SMP PREEMPT Sun Oct 25 14:46:41 CET 2015
   Machine: armv7l (armv7l)
   Language: en_US.utf8 (charmap="UTF-8", collate="UTF-8")
   07:17:03 up 44 min,  2 users,  load average: 1.56, 1.61, 1.56; runlevel 3
   ------------------------------------------------------------------------
   Benchmark Run: Sun Jan 03 2016 07:17:03 - 07:46:42
   0 CPUs in system; running 4 parallel copies of tests
   ::
   System Benchmarks Index Values               BASELINE       RESULT    INDEX
   Dhrystone 2 using register variables         116700.0   17298899.9   1482.3
   Double-Precision Whetstone                       55.0       2969.0    539.8
   Execl Throughput                                 43.0       1464.1    340.5
   File Copy 1024 bufsize 2000 maxblocks          3960.0     149424.6    377.3
   File Copy 256 bufsize 500 maxblocks            1655.0      45277.4    273.6
   File Copy 4096 bufsize 8000 maxblocks          5800.0     380747.9    656.5
   Pipe Throughput                               12440.0     911007.9    732.3
   Pipe-based Context Switching                   4000.0     124699.6    311.7
   Process Creation                                126.0       3414.8    271.0
   Shell Scripts (1 concurrent)                     42.4       1865.6    440.0
   Shell Scripts (8 concurrent)                      6.0        307.0    511.6
   System Call Overhead                          15000.0    2100567.0   1400.4
   ========
   System Benchmarks Index Score                                         516.5

おおよそ、RasPi2 より少し速い500ポイントちょいのスコアです。クロックダウンする前は、600ちょいだったので、すこし遅くなった感じですね。

 

実際にサーバとして仮運用していますので、レスポンスなど見たい方は以下にアクセスしてみてください。昨年からテストで運用しています。

Fedora22 OrangePi PC

/

・NGINX + php-fpm + MariaDB

そこそこ重めのアプリケーションのWordPress が動作しています。ネットワーク的には、サーバからの下りは帯域は絞られていると思いますので差し引いてみてください。今のところ、そこそこストレスなく動作しています。

 

当初、OpenStack として勉強用に使おうと思っていたのですが、何年ぶりかで自宅サーバを運用してみたら面白くてOpenStack の構成の検証に環境を壊したくないなぁという感じです。もう一台ほしいなぁと。

WEBを散歩しているとなにやら、Orange pi Oneという10ドルくらいのものも発売されるということで、すこし様子見をしています。

CNXSoft

Orange Pi One is a $10 Quad Core Board with Ethernet and HDMI

Orange_Pi_One

どうやら、WIFI 付きモデルと、10/100M Ethernet モデルが出るようです。なかなか面白そうです。比較表は、OSAKANA TARO さんのページにあります。

OSAKANA TARO のメモ帳

Orange Pi ONEの詳細が出た!

CPU は、今のと同じ 6ドルの H3 (4core)を使うようです。これで、9.99ドルで出せるとはほぼ原価並の価格ですね。メーカ(Shenzhen Xunlong Software)は、かなり大量にパーツを購入しているんでしょう。とにかくこれは出たら買いです。

 

OpenStack Ironic としてベアメタルな構成を考えているのですが、動作に必要な PXE Boot の実験がまだ終わっていません。まだ、OpenStack 自体もあまり良くわかっていないのですが、おそらくベアメタルをコントロールする際に、PXE Boot が必要になると思います。あとIPMI で電源とかなにか操作するようです。このあたりの検証もしないといけません。おそらく、なにか工夫する必要があると思っています。

 

5台くらいの構成で考えているのですが、安いほうがいいよねということで、Orange pi Oneが出てから考えたいなぁと思っています。5000円くらいで、最小構成を目指して OpenStack のベアメタルを勉強してみたいと思っています。

 

まとめ

・クロックを1.2Mhz にダウンさせるとベンチマークは500ちょい

・ヒートシンクと、ファンをつけた状態でアイドル時、温度は30度から40度を推移

・負荷をかけると50度ちょいくらい

・追加購入は、OrangePi PC の15ドルより安い9.99ドルの Orange Pi One というのが出るまで待ち

・U-Boot する仕組みを勉強してみる

Funの効果は、-15度!

ちょっと、orange pi pc で作業をしようと思い、ファンの電源をONにしました。

すると、やっぱりかなり効果があったようで、15度は下がっています。

h3_temp-day-1

※途中、空白なのはmunin の設定変えたけど再起動してなかった

今、CPUクロックが最高で1.5GHz くらいまであがる設定なので、速いですが温度もあがるようです。

cpuspeed-day

途中、コンパイルしていて1.5Ghz まで上がっていますが温度は、50度くらいのようです。これで少し安心して作業ができますね。さすがに、80度とかちょっと心配になるので。上限のクロックを下げるという方法もあるのですが、どうせならぶん回したいので。

 

クロックを下げるには、/sys 配下のscaling_max_freq と scaling_min_freq に起動したら設定を入れておく方法と、ブート領域のパラメータを持っているscrpt.bin で指定する方法があるようです。

以下のページが参考になります。

Sunxi Wiki
Orange Pi PC
http://linux-sunxi.org/Orange_Pi_PC#CPU_clock_speed_limit

当初、まったく意味不明だったのですがどうやら、sdCard のブート領域にあるscript.bin がuImage に渡すパラメータを持っているようです。今、動作させているのは loborisさんが作ったものですが、以下のようになっています。

 

このscript.bin をfex2bin というツールで展開すると見れます。

Sunxi-tools
http://linux-sunxi.org/Sunxi-tools#bin2fex

以下のようにして、実機でビルドしました。

# dnf install libusbx-devel
$ cd /usr/local/src/BUILD
$ git clone https://github.com/linux-sunxi/sunxi-tools
$ cd sunxi-tools/
$ LANG=C make

今後も使うと思うので、パスが切れているところに入れておきます。

sudo cp -pr ./bin2fex /usr/local/bin
sudo cp -pr ./fex2bin /usr/local/bin
sudo cp -pr ./sunxi-* /usr/local/bin

sudo chown root.root /usr/local/bin/bin2fex
sudo chown root.root /usr/local/bin/fex2bin
sudo chown root.root /usr/local/bin/sunxi-*

で、以下のように使うようです。

$ bin2fex script.bin lobo.fex

この中はパラメータがたくさん書かれたもので、最大と最小が以下のように指定されていました。

[dvfs_table]
pmuic_type = 2
pmu_gpio0 = port:PL06<1><1><2><1>
pmu_level0 = 11300
pmu_level1 = 576
extremity_freq = 1536000000
max_freq = 1536000000
min_freq = 480000000
LV_count = 8
LV1_freq = 1536000000
LV1_volt = 1500
LV2_freq = 1200000000
LV2_volt = 1300
LV3_freq = 0
LV3_volt = 1100
LV4_freq = 0
LV4_volt = 1100
LV5_freq = 0
LV5_volt = 1100
LV6_freq = 0
LV6_volt = 1100
LV7_freq = 0
LV7_volt = 1100
LV8_freq = 0
LV8_volt = 1100

このファイルは、.fex というのが通り名称のようです。sunxi の git リポジトリに昨年の12月22日にリリースされた.fex ファイルは以下にあります。

sunxi-boards/sys_config/h3/

https://github.com/linux-sunxi/sunxi-boards/tree/master/sys_config/h3

現在の、script.bin の内容と比較すると以下のようです。

[junkhack@OrangePi BUILD]$ mkdir tmp_boot
[junkhack@OrangePi BUILD]$ cp -pr /media/boot/* tmp_boot/
[junkhack@OrangePi BUILD]$ ll tmp_boot/
::
-rwxr-xr-x 1 501 root    35812 12月 19 14:29 script.bin
-rwxr-xr-x 1 501 root 10917600 12月 19 14:29 uImage
[junkhack@OrangePi BUILD]$ 
[junkhack@OrangePi BUILD]$ cp -p ./sunxi-boards/sys_config/h3/xunlong_orange_pi_pc.fex tmp_boot/
[junkhack@OrangePi BUILD]$ cd tmp_boot/

[junkhack@OrangePi tmp_boot]$ bin2fex script.bin lobo.fex

[junkhack@OrangePi tmp_boot]$ diff -up lobo.fex xunlong_orange_pi_pc.fex > lobo_opipc.patch

違いは以下のようです。

—- lobo_opipc.patch

--- lobo.fex    2016-01-03 04:30:34.000000000 +0900
+++ xunlong_orange_pi_pc.fex    2016-01-03 04:10:45.000000000 +0900
@@ -8,7 +8,8 @@ eraseflag = 1
 next_work = 2
 
 [target]
-boot_clock = 1536
+#boot_clock = 1008
+boot_clock = 1200
 storage_type = -1
 
 [key_detect_en]
@@ -146,7 +147,7 @@ twi_scl = port:PA11<2><default><default>
 twi_sda = port:PA12<2><default><default><default>
 
 [twi1]
-twi_used = 1
+twi_used = 0
 twi_scl = port:PA18<3><default><default><default>
 twi_sda = port:PA19<3><default><default><default>
 
@@ -165,14 +166,14 @@ uart_rx = port:PA05<2><1><default><defau
 [uart1]
 uart_used = 0
 uart_port = 1
-uart_type = 2
+uart_type = 4
 uart_tx = port:PG06<2><1><default><default>
 uart_rx = port:PG07<2><1><default><default>
 uart_rts = port:PG08<2><1><default><default>
 uart_cts = port:PG09<2><1><default><default>
 
 [uart2]
-uart_used = 1
+uart_used = 0
 uart_port = 2
 uart_type = 4
 uart_tx = port:PA00<2><1><default><default>
@@ -181,16 +182,16 @@ uart_rts = port:PA02<2><1><default><defa
 uart_cts = port:PA03<2><1><default><default>
 
 [uart3]
-uart_used = 1
+uart_used = 0
 uart_port = 3
-uart_type = 2
+uart_type = 4
 uart_tx = port:PA13<3><1><default><default>
 uart_rx = port:PA14<3><1><default><default>
 uart_rts = port:PA15<3><1><default><default>
 uart_cts = port:PA16<3><1><default><default>
 
 [spi0]
-spi_used = 1
+spi_used = 0
 spi_cs_bitmap = 1
 spi_mosi = port:PC00<3><default><default><default>
 spi_miso = port:PC01<3><default><default><default>
@@ -209,50 +210,66 @@ spi_miso = port:PA16<2><default><default
 spi_dev_num = 1
 
 [spi_board0]
-modalias = "spidev"
+modalias = "m25p32"
 max_speed_hz = 33000000
 bus_num = 0
 chip_select = 0
 mode = 0
-full_duplex = 1
-manual_cs = 0
 
 [gpio_para]
 gpio_used = 1
-gpio_num = 19
-gpio_pin_1 = port:PL10<1><default><default><0>
-gpio_pin_2 = port:PA15<1><default><default><1>
-gpio_pin_3 = port:PA06<1><default><default><0>
-gpio_pin_4 = port:PA13<1><default><default><0>
-gpio_pin_5 = port:PA14<1><default><default><0>
-gpio_pin_6 = port:PD14<1><default><default><0>
-gpio_pin_7 = port:PA03<1><default><default><0>
-gpio_pin_8 = port:PC04<1><default><default><0>
-gpio_pin_9 = port:PC07<1><default><default><0>
-gpio_pin_10 = port:PC03<1><default><default><0>
-gpio_pin_11 = port:PA21<1><default><default><0>
-gpio_pin_12 = port:PA07<1><default><default><0>
-gpio_pin_13 = port:PA08<1><default><default><0>
-gpio_pin_14 = port:PG08<1><default><default><0>
-gpio_pin_15 = port:PA09<1><default><default><0>
-gpio_pin_16 = port:PA10<1><default><default><0>
-gpio_pin_17 = port:PG09<1><default><default><0>
-gpio_pin_18 = port:PG06<1><default><default><0>
-gpio_pin_19 = port:PG07<1><default><default><0>
-
-[led_assign]
-normal_led = "gpio_pin_2"
-standby_led = "gpio_pin_1"
+gpio_num = 30
+; gpio_pin_1 = port:PL10<1><default><default><1>
+; gpio_pin_2 = port:PA15<1><default><default><0>
+gpio_pin_3 = port:PA12<1><default><default><0>
+gpio_pin_4 = port:PA11<1><default><default><0>
+gpio_pin_5 = port:PA06<1><default><default><0>
+gpio_pin_6 = port:PA13<1><default><default><0>
+gpio_pin_7 = port:PA14<1><default><default><0>
+gpio_pin_8 = port:PA01<1><default><default><0>
+gpio_pin_9 = port:PD14<1><default><default><0>
+gpio_pin_10 = port:PA00<1><default><default><0>
+gpio_pin_11 = port:PA03<1><default><default><0>
+gpio_pin_12 = port:PC04<1><default><default><0>
+gpio_pin_13 = port:PC07<1><default><default><0>
+gpio_pin_14 = port:PC00<1><default><default><0>
+gpio_pin_15 = port:PC01<1><default><default><0>
+gpio_pin_16 = port:PA02<1><default><default><0>
+gpio_pin_17 = port:PC02<1><default><default><0>
+gpio_pin_18 = port:PC03<1><default><default><0>
+gpio_pin_19 = port:PA21<1><default><default><0>
+gpio_pin_20 = port:PA19<1><default><default><0>
+gpio_pin_21 = port:PA18<1><default><default><0>
+gpio_pin_22 = port:PA07<1><default><default><0>
+gpio_pin_23 = port:PA08<1><default><default><0>
+gpio_pin_24 = port:PG08<1><default><default><0>
+gpio_pin_25 = port:PA09<1><default><default><0>
+gpio_pin_26 = port:PA10<1><default><default><0>
+gpio_pin_27 = port:PG09<1><default><default><0>
+gpio_pin_28 = port:PA20<1><default><default><0>
+gpio_pin_29 = port:PG06<1><default><default><0>
+gpio_pin_30 = port:PG07<1><default><default><0>
+
+;[led_assign]
+;normal_led = "gpio_pin_2"
+;standby_led = "gpio_pin_1"
+
+[leds_para]
+leds_used = 1
+green_led = port:PL10<1><default><default><0>
+green_led_active_low = 0
+red_led = port:PA15<1><default><default><0>
+red_led_active_low = 0
 
 [ths_para]
 ths_used = 1
-ths_trip1_count = 5
-ths_trip1_0 = 75
-ths_trip1_1 = 85
-ths_trip1_2 = 90
-ths_trip1_3 = 100
-ths_trip1_4 = 105
-ths_trip1_5 = 0
+ths_trip1_count = 6
+ths_trip1_0 = 70
+ths_trip1_1 = 80
+ths_trip1_2 = 85
+ths_trip1_3 = 90
+ths_trip1_4 = 95
+ths_trip1_5 = 100
 ths_trip1_6 = 0
 ths_trip1_7 = 0
 ths_trip1_0_min = 0
@@ -264,21 +281,22 @@ ths_trip1_2_max = 3
 ths_trip1_3_min = 3
 ths_trip1_3_max = 4
 ths_trip1_4_min = 4
-ths_trip1_4_max = 4
-ths_trip1_5_min = 0
-ths_trip1_5_max = 0
+ths_trip1_4_max = 5
+ths_trip1_5_min = 5
+ths_trip1_5_max = 5
 ths_trip1_6_min = 0
 ths_trip1_6_max = 0
 ths_trip2_count = 1
 ths_trip2_0 = 105
 
 [cooler_table]
-cooler_count = 5
-cooler0 = "1536000 4 4294967295 0"
+cooler_count = 6
+cooler0 = "1296000 4 4294967295 0"
 cooler1 = "1200000 4 4294967295 0"
 cooler2 = "1008000 4 4294967295 0"
-cooler3 = "816000 3 4294967295 0"
-cooler4 = "504000 1 4294967295 0"
+cooler3 =  "816000 4 4294967295 0"
+cooler4 =  "648000 4 4294967295 0"
+cooler5 =  "480000 1 4294967295 0"
 
 [nand0_para]
 nand_support_2ch = 0
@@ -316,17 +334,15 @@ hdmi_mode_check = 1
 disp_init_enable = 1
 disp_mode = 0
 screen0_output_type = 3
-screen0_output_mode = 10
+screen0_output_mode = 4
 screen1_output_type = 3
-screen1_output_mode = 10
+screen1_output_mode = 4
 fb0_format = 0
 fb0_width = 0
 fb0_height = 0
 fb1_format = 0
 fb1_width = 0
 fb1_height = 0
-fb0_framebuffer_num = 3
-sunxi_fb_mem_reserve = 32
 
 [hdmi_para]
 hdmi_used = 1
@@ -340,6 +356,7 @@ tv_dac_src0 = 0
 [pwm0_para]
 pwm_used = 0
 pwm_positive = port:PA05<3><0><default><default>
+;       If set gamc_phy to use = 2
 
 [gmac0]
 gmac_used = 2
@@ -500,8 +517,8 @@ smc_sda = port:PA08<2><default><default>
 
 [usbc0]
 usb_used = 1
-usb_port_type = 1
-usb_detect_type = 0
+usb_port_type = 2
+usb_detect_type = 1
 usb_id_gpio = port:PG12<0><1><default><default>
 usb_det_vbus_gpio = port:PG12<0><1><default><default>
 usb_drv_vbus_gpio = port:PL02<1><0><default><0>
@@ -693,31 +710,54 @@ ir_addr_code12 = 65344
 ir_used = 1
 ir_tx = port:PH07<2><default><default><default>
 
+;----------------------------------------------------------------------------------
+; dvfs voltage-frequency table configuration
+;
+; pmuic_type:0:none, 1:gpio, 2:i2c
+; pmu_gpio0: gpio config.
+; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low.
+;
+; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk
+;                     1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator
+; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz
+; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz
+;
+; LV_count: count of LV_freq/LV_volt, must be < 16
+;
+; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz,  1536Mhz]
+; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz,  1296Mhz]
+; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz,  1200Mhz]
+; LV4: core vdd is 1.20v if cpu frequency is (816Mhz,   1008Mhz]
+; LV5: core vdd is 1.10v if cpu frequency is (648Mhz,    816Mhz]
+; LV6: core vdd is 1.04v if cpu frequency is (0Mhz,      648Mhz]
+; LV7: core vdd is 1.04v if cpu frequency is (0Mhz,      648Mhz]
+; LV8: core vdd is 1.04v if cpu frequency is (0Mhz,      648Mhz]
+;
+;----------------------------------------------------------------------------------
 [dvfs_table]
 pmuic_type = 2
 pmu_gpio0 = port:PL06<1><1><2><1>
 pmu_level0 = 11300
-pmu_level1 = 576
-extremity_freq = 1536000000
-max_freq = 1536000000
-min_freq = 480000000
+pmu_level1 = 1100
+max_freq = 1296000000
+min_freq = 648000000
 LV_count = 8
-LV1_freq = 1536000000
-LV1_volt = 1500
+LV1_freq = 1296000000
+LV1_volt = 1340
 LV2_freq = 1200000000
-LV2_volt = 1300
-LV3_freq = 0
-LV3_volt = 1100
-LV4_freq = 0
+LV2_volt = 1320
+LV3_freq = 1008000000
+LV3_volt = 1200
+LV4_freq = 816000000
 LV4_volt = 1100
-LV5_freq = 0
-LV5_volt = 1100
+LV5_freq = 648000000
+LV5_volt = 1040
 LV6_freq = 0
-LV6_volt = 1100
+LV6_volt = 1040
 LV7_freq = 0
-LV7_volt = 1100
+LV7_volt = 1040
 LV8_freq = 0
-LV8_volt = 1100
+LV8_volt = 1040
 
 [gpu_dvfs_table]
 G_LV_count = 3
@@ -797,13 +837,3 @@ din_gpio = port:PD00<1><default><default
 clk_gpio = port:PD01<1><default><default><1>
 stb_gpio = port:PD02<1><default><default><1>
 
-[mali_para]
-mali_used = 1
-mali_clkdiv = 1
-mali_extreme_freq = 600
-mali_extreme_vol = 1400
-
-[w1_para]
-w1_used = 1
-gpio = 20
-

ファンがなくても、まぁいいようにクロックダウンしたほうが良さそうですね。ということで、fex2bin で作ったscript.bin でリブートしておきました。しばらくこれで様子をみることに。

 

▼まとめ

・script.bin は、bin2fex や fex2bin で取り扱う

・これがブート領域からkernel に引き渡すパラメータを持っている模様

・VDD を1.34vで扱うLV2 が安全の模様

・*.txt から読み込むようにする u-boot イメージはどうやって作るのか?

・あるいは、今でも kernel に渡す方法があるのかも。

・sunxi からのfex ファイルには gpio ピンのマッピングも追加変更されているようだ

・ヒートシンク+ファンをつければ、40度くらいまでアイドル時になるようで、負荷時は60度くらいかな?

・ファンの効果は絶大だけれども、もう少し設定を下げて運用しようかと思う。

OPIにFAN をつけると温度はどのくらい下がるか?

aliexpress からFAN と熱シールが届きましたので、OPI に取り付けました。

 

1

FAN は2個入り、3M の熱伝道シールは3枚で14mmにカットしてあります。1枚に5x7で35枚でした。

2

CPU とメモリ部分にシールを取り付け、簡易的にファンもシールで貼り付け。

3

安い割りには、薄いのでこれで十分ですね。実測で、6.87mm です。

ファンを回す前と、回さない前でCPU 温度をmunin で取得しようと以下を設定。

[root@opi 19:43:22 plugins]# pwd
/etc/munin/plugins
[root@opi 19:43:23 plugins]# cat h3_temp 
#!/bin/sh

#%# family=auto
#%# capabilities=autoconf

GETNUM=`/bin/cat /sys/class/thermal/thermal_zone0/temp`

if [ "$1" = "autoconf" ]; then
        if [ -n ${GETNUM} ] ; then
                echo yes
                exit 0
        else
                echo no
                exit 0
        fi
fi

if [ "$1" = "config" ]; then
        echo 'graph_title CPU Temp'
        echo 'graph_args -r --lower-limit 0'
        echo 'graph_vlabel Temp'
        echo 'graph_category Apps'
        echo 'total.label CPU0 Temp'
        echo 'total.min 0'
        echo 'total.draw AREA'
        echo 'total.type GAUGE'
        exit 0
fi

echo "total.value $GETNUM";

確認は以下を実行。

[root@opi 19:46:32 plugins]# ./h3_temp autoconf
yes
[root@opi 19:46:37 plugins]# ./h3_temp config
graph_title CPU Temp
graph_args -r --lower-limit 0
graph_vlabel Temp
graph_category Apps
total.label CPU0 Temp
total.min 0
total.draw AREA
total.type GAUGE
[root@opi 19:46:44 plugins]# ./h3_temp 
total.value 57
[root@opi 19:46:52 plugins]# 

で、munin-node を再起動

# systemctl restart munin-node

すると、以下な感じでグラフができます。

h3_temp-day

ファンをつける前のデータをとりあえず記録するため、まだ回していません。結構熱そうですね。70 度くらいになっています。

しばらく、このまま記録をとってからファンを回したいと思います。最初、テストで回していたときは、上のグラフの最初の部分で40 度くらいでした。効果はかなり期待できそうです。

 

参考

muninプラグインを作成

https://www.seeds-std.co.jp/seedsblog/671.html

1us Lチカ

2016年 謹賀新年、あけましておめでとうございます。おせち料理も31日と1日で食べつくしてしまいました。

さて、今年最初のブログですね。0.000001秒のLチカをロジックアナライザーでモニタリングして光らせてみました。

あと、オレンジパイで、8本のGPIO を使って安価なロジックアナライザーで採取できるかも確認してみました。

 

サンプルプログラムを採取したデータが以下です。8本分は取れていますが、速すぎるところは取りこぼしているようです。

1

矢印は500ns で光っている部分で採取に失敗し、取りこぼす事がありました。このあたりが2Mhz の限界なんですね。今のファームウェアとソフトウェアだとこれが限界のようです。

2

複数のLED は、blink ファンクションにて光らせていますが、呼び出しと初期化の処理で250us 程度使っているようです。

3

usleep 関数を使っても思ったより、処理に時間がかかるようです。1us を指定して光らせているんですが、実際は69us 光っています。nanosleep を使っても66us は使われてしまうようで、1us を光らせる為にwhile で調整してみました。

4

サンプルのプログラムは以下です。

/*
 *  +-----+-----+----------+------+---+--OrangePiPC--+---+------+---------+-----+--+
 *  | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 *  +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 *  |     |     |     3.3v |      |   |  1 || 2  |   |      | 5v       |     |     |
 *  |   2 |  -1 |    SDA.0 |      |   |  3 || 4  |   |      | 5V       |     |     |
 *  |   3 |  -1 |    SCL.0 |      |   |  5 || 6  |   |      | 0v       |     |     |
 *  |   4 |   6 | IO6 PA06 |  OUT | 0 |  7 || 8  |   |      | TxD3     |     |     |
 *  |     |     |       0v |      |   |  9 || 10 |   |      | RxD3     |     |     |
 *  |  17 |  -1 |     RxD2 |      |   | 11 || 12 | 0 | OUT  | IO1 PD14 | 1   | 18  |
 *  |  27 |  -1 |     TxD2 |      |   | 13 || 14 |   |      | 0v       |     |     |
 *  |  22 |  -1 |     CTS2 |      |   | 15 || 16 | 0 | OUT  | IO4 PC04 | 4   | 23  |
 *  |     |     |     3.3v |      |   | 17 || 18 | 0 | OUT  | IO5 PC07 | 5   | 24  |
 *  |  10 |  -1 |     MOSI |      |   | 19 || 20 |   |      | 0v       |     |     |
 *  |   9 |  -1 |     MISO |      |   | 21 || 22 |   |      | RTS2     |     |     |
 *  |  11 |  -1 |     SCLK |      |   | 23 || 24 |   |      | SPI-CE0  |     |     |
 *  |     |     |       0v |      |   | 25 || 26 |   |      | CE1      |     |     |
 *  |   0 |  -1 |    SDA.1 |      |   | 27 || 28 |   |      | SCL.1    |     |     |
 *  |   5 |   7 |  IO7 PA7 |  OUT | 0 | 29 || 30 |   |      | 0v       |     |     |
 *  |   6 |   8 |  IO8 PA8 |  OUT | 0 | 31 || 32 | 0 | OUT  | IO9 PG08 | 9   | 12  |
 *  |  13 |  10 | IO10 PA9 |  OUT | 0 | 33 || 34 |   |      | 0v       |     |     |
 *  |  19 |  12 | IO12PA10 |  OUT | 0 | 35 || 36 | 0 | OUT  | IO13PG09 | 13  | 16  |
 *  |  26 |  14 | IO14PA20 | ALT3 | 0 | 37 || 38 | 0 | OUT  | IO15PG06 | 15  | 20  |
 *  |     |     |       0v |      |   | 39 || 40 | 0 | OUT  | IO16PG07 | 16  | 21  |
 *  +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 *  | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 *  +-----+-----+----------+------+---+--OrangePIPC--+------+----------+-----+-----+
 *         ^^^^ Pin NO                                                   ^^^^ Pin NO
 * 1us LED blink.
 * building ex) gcc -lwiringPi -lpthread -I/usr/local/include -L/usr/local/lib -levent -o 2016blinkall 2016blinkall.c
 * 
 *
*/
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <wiringPi.h>

#define MSEC 1
#define USEC 33
#define NANOSEC 1000

int blink2(int led, int delay);

int main (void)
{
  int led;
  int i = 0;

  while (i < 3)
  {
    blink2(16, 1000);
      blink2(15, 1000); //Next blink 250 us
      blink2(13, 1000);
      blink2(9, 1000);
      blink2(5, 1000);
      blink2(4, 1000);
      blink2(1, 1000);
      blink2(6, 1000);

    i++;
  }

  delay (MSEC);
  return 0;
}

int blink2(int led, int delay){
    // unsigned int usecs;
    // usecs = delay;
    // sec = delay;
    led = led;
    int i = 0;

    // nano sec
    struct timespec nano;
    nano.tv_sec = 0;
    nano.tv_nsec = delay;

    wiringPiSetup () ;
    pinMode (led, OUTPUT) ;

    digitalWrite (led, HIGH) ;
    nanosleep(&nano, NULL); // 66us
    // usleep (usecs) ; // 66us
    // delay (delay);
    digitalWrite (led,  LOW) ;
    usleep (1);

    digitalWrite (led, HIGH) ;

    // 1us
    while (i < 100)
    {
        i++;
    }
    digitalWrite (led,  LOW) ;
    usleep (1); // 66us

    digitalWrite (led, HIGH) ;
    // 500 ns
    digitalWrite (led,  LOW) ;
}

GPIO の8本を同時に処理させるにはどうしたらいいんでしょうかね。マルチスレッド処理ですかね?シフトレジスタに投げて、一括処理とかですかね?

 

前ちょっと触ったイベント処理のlibevent とかを使うとどのくらいの精度になるんでしょうかね。いろいろ疑問がわいてきます。

E-ink を表示するためにはまだまだ超えないといけない山がたくさんあるようです。

なんとか、春までには表示したいんですが。こつこつとやっていきます。

Sigrok の Pulsview 0.3.0 動きました

とりあえず、なんとか動かしたいのでソースをコードも見ましたが、特に問題となりそうな部分もなく、ちょっと場を離れてから、brew版のをサイド入れてみることに。とりあえず、動作させることができました。

なんとか、今年中に出来たのですっきり。

 

0.3.0-git-5d73886 では、以下のようにトリガーが設定できて楽になりました。Runを押せばトリガーがでるまで、stop して採取されます。サンプル数を設定しておけば、採取されて停止します。ロジックアナライザーとしては基本機能だと思いますが、手持ちのハードでなんとか動いてよかったです。

7

拡大すると、500ns とか取れています。1us 単位くらいまでは見れそうということがわかりました。

8

サンプルレートは、2MHz 以上あげるとどうしても採取後にクルクル回って、操作を受け付けないスタック状態のような感じになります。コマンドライン版でドライバを指定してみると、以下のようです。

$ sigrok-cli --show --driver fx2lafw
Driver functions:
    Logic analyzer
Scan options:
    conn
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
fx2lafw:conn=28.2 - Saleae Logic with 8 channels: 0 1 2 3 4 5 6 7
Supported configuration options:
    continuous: 
    limit_samples: 0 (current)
    conn: 28.2 (current)
    samplerate - supported samplerates:
      20 kHz
      25 kHz
      50 kHz
      100 kHz
      200 kHz
      250 kHz
      500 kHz
      1 MHz
      2 MHz
      3 MHz
      4 MHz
      6 MHz
      8 MHz
      12 MHz
      16 MHz
      24 MHz
    Supported triggers: 0 1 r f e 
    captureratio: 0 (current)

ここに出ているサンプリング周波数は採取できるはずなんですが、なぜか2MHz までしかとれません。

まぁ、最初の一台ですし、これで勉強させてもらって、物足りなければまた考えることにします。

 

automator でシェルスクリプトを実行するものを作り、アイコンをつけて、app 化します。

6

python の環境変数を一度 unset して消去して、python3.4 とか3.x のをセットしてアプリをバックグランドで呼び出します。

unset PYTHONPATH
export PYTHONPATH="/usr/local/lib/python3.4/site-packages/:$PYTHONPATH"

/usr/local/Cellar/pulseview/HEAD/bin/pulseview >/dev/null 2>&1 &

 

配布用にするには、ライブラリのパスを全部書き換えないといけないので、やめました。このあたりのスキルは、もう少し勉強しないと嵌りそうです。

5

brew 版のインストールは、wiki に書いてあるとおりで以下のようです。

https://sigrok.org/wiki/Mac_OS_X

$ brew tap rene-dev/sigrok

$ brew install python3

$ brew install –HEAD libserialport

$ brew install –HEAD –with-libserialport libsigrok

$ brew install –HEAD libsigrokdecode

$ brew install –HEAD –with-libserialport sigrok-cli

$ brew install –HEAD pulseview

ポイントとしては、マニュアルビルドしてソースから入れたものは一度、綺麗に消して、brew docter で問題をクリアにしてからやることと、以下の libsigrokdecode が2つ出てくるのでbrew のを無効にすることくらいです。

$ brew install –HEAD libsigrokdecode

Error: Formulae found in multiple taps:

* homebrew/science/libsigrokdecode

* rene-dev/sigrok/libsigrokdecode

 

$ brew untap homebrew/science

$ brew tap –repair

$ brew update

 

あと、ファームウェアの格納場所は、デフォルトで

/usr/local/share/sigrok-firmware

になるので、ここにディレクトリを作成し、最新のファームウェアを入れておきます。これで最初のデバイスを見つけてファームがなくエラーになるのを迂回できます。エラーでも、落ちはしませんが。前回落ちたのは別の原因で、QT 関連のライブラリのパスが書き換わっていないのが原因でした。ltool で見ると、/usr 配下となっていました。そのほかの原因もあったとは思いますが、ライブラリの依存関係でおそらくは、brew 版のを見に行っていたのかもしれません。まぁ、詳細は不明です。

 

ということで、とりあえずは動いてよかったです。トリガーもかけられるようになったし、インターフェイスは少しよくなった感じ。ボタンの配置とか。

 

▼まとめ

・EZ-USB FX2LP CY7C68013A で、sigrok の pulsview は動作

・このハードは実質6ドルくらいなので、ロジックアナライザーとして最初の一台で遊ぶには十分

・0.3.0-git-f3697d3 は動作した

・トリガーがかけられるようになった

・少しインターフェイスがよくなった

・2Mhz サンプリングまでは出来ることを確認

・1チャンネル採取で500ns は採取できた。1us くらいが精度か?

・8チャンネル同時採取はまだやっていない

・ファームウェア格納場所は、/usr/local/share/sigrok-firmware

・brew 版で HEAD で入れているので、時期によっては動作しない場合もあるかも

・配布用に、ライブラリを書き換えるのはどうすれば楽になるのか?要研究

FX2LP でsigrok のロジックアナライザー

年末で、何かとイベントごとがあってなかなかブログを更新できずにいました。

Aliexpress からもどんどんお品が届いて、ロジックアナライザーとして使うボードも到着しました。テストがてら、OrangePi PC の GPIO につないだLED のタイミングを計測してみること。

配線は、とりあえず1チャンネルでテスト。全部で8チャンネルいけます。

logic2

ちょっとわかりにくいですが、PB0 ~ PB7 までの端子が sigrok でいう0から7 までに対応しています。とりあえず今回はPB0 の端子につないで1チャンネルの表示をしてみました。

PulseView1

全体のテスト配線は以下のような感じです。

 

logic

osx だと sigrok のソフトウェアの中にファームウェアがあります。最新のファームウェアは、以下にビルド済みのものがあります。

fx2lafw (pre-built firmware files の項を参照)
http://sigrok.org/wiki/Fx2lafw

つい先月にリリースされている0.1.3 を使いました。

sigrok-firmware-fx2lafw-bin-0.1.3.tar.gz

http://sigrok.org/download/binary/sigrok-firmware-fx2lafw/

ほどよく、配置。*.fw がファームウェアです。

HOPE:sigrok-firmware junkhack$ pwd
/Applications/PulseView.app/Contents/share/sigrok-firmware
HOPE:sigrok-firmware junkhack$ ll
total 1088
-rw-r--r--@ 1 junkhack  admin  45268 11  3  2014 asix-sigma-100.fw
-rw-r--r--@ 1 junkhack  admin  45396 11  3  2014 asix-sigma-200.fw
-rw-r--r--@ 1 junkhack  admin  45396 11  3  2014 asix-sigma-50.fw
-rw-r--r--@ 1 junkhack  admin  45360 11  3  2014 asix-sigma-50sync.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-braintechnology-usb-lps.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-cwav-usbeeax.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-cwav-usbeedx.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-cwav-usbeesx.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-cypress-fx2.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-saleae-logic.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-sigrok-fx2-16ch.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-sigrok-fx2-8ch.fw
-rw-r--r--@ 1 junkhack  admin  81808 11  3  2014 sysclk-lwla1034-extneg.rbf
-rw-r--r--@ 1 junkhack  admin  81808 11  3  2014 sysclk-lwla1034-extpos.rbf
-rw-r--r--@ 1 junkhack  admin  81460 11  3  2014 sysclk-lwla1034-int.rbf
-rw-r--r--@ 1 junkhack  admin  48521 11  3  2014 sysclk-lwla1034-off.rbf
HOPE:sigrok-firmware junkhack$ 

sigrok の PluseView を開きます。

現在、手元でビルドしていないので、ELIAS さんのビルドしたものです。

osx PulseView.dmg (0.2.0 : 2014/11/04 build)

http://eliasoenal.com/2014/11/04/sigrok-for-os-x/

File Menu から Connect to Device を選択して、以下のようにスキャンすると出ました。

Connect_to_Device

osx の USB 認識は、以下のようでした。

osxusb

system_profiler で見ると以下のように出ます。

 

$ system_profiler SPUSBDataType
USB:
::

            fx2lafw:

              Product ID: 0x3881
              Vendor ID: 0x0925
              Version:  0.01
              Speed: Up to 480 Mb/sec
              Manufacturer: sigrok
              Location ID: 0x1c120000 / 2
              Current Available (mA): 500
              Current Required (mA): 100

 

で、LEDをGPIO で光らせるプログラムで、LED を ON するタイミングを以下のように、usleep を使って1ms 光らせてみました。

抜粋箇所だけ載せておきます。

#include <event.h>
#include <wiringPi.h>
#include <unistd.h>

#define LED 16
#define MSEC 10
#define USEC 1000 // 1000 = 1ms (0.000001 sec = 1 micro second)

int
blink(void){
    wiringPiSetup () ;
    pinMode (LED, OUTPUT) ;

    digitalWrite (LED, HIGH) ;
    // delay (MSEC);
    usleep(USEC);
    digitalWrite (LED,  LOW) ;
}
::

全体のプログラムは、末尾につけておきます。このプログラムは、libevent を使ってfifo ファイルに read イベントがあったら、上記のblink ファンクションが呼ばれる仕組みです。あとで、書きますが、nginx のログをパイプさせて監視させています。

で、他のホストから ab で web アクセスしてみます。

$ ab -n 5 -c 1 /index.html

とりあえず、5回くらいで。nginx のアクセスログには、5回記録されています。

192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"
192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"
192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"
192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"
192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"

そのタイミングを取ると以下のようです。

PulseView

今度は、300us ほどにして、100回アクセスしてみました。ちゃんと100回、凹凸があるか数えたらありました。

PulseView_2

マウスホイールすると拡大できます。300us より若干大きくなっているのは、イベント処理のプログラムや時計の誤差などの影響ですかね。

300us

1ms くらいのものは問題なく見れそうということがわかりました。2Mhz 以上あげると、固まるのはなぜですかね。24Mhz までいけるはずですが?

 

1us 単位の計測が今のところできないです。あと、トリガーをかけようとチャンネルをクリックすると落ちる。うーん、独自にコンパイルしてみるしかなさそうですね。

 

▼まとめ

・EZ-USB FX2LP CY7C68013A というのをゲット(非常に安価だった)

・sigrok の PluseView の osx 版(0.2.0)を使ったが、無事チャンネル0のパルスが取れた

・PCB上のPB0 ~ PB7 までの端子が sigrok でいう0から7 までに対応

・fx2lafw はビルド済みの0.1.3 を使用

・2Mhz までは計測できるが、それ以上でかたまる

・fx2lafw が悪いのか、PluseView が悪いのか切り分ける必要あり

・テストプログラム側のusleep を削除して、単純に点灯消灯をしてタイミングを取ったら、500ns という単位が出たので、1us の単位でも取得できそう。