1. 簡述
本文不涉及對測試中所用到的裝置或軟體的推廣。
micro:bit 是一款由英國廣播電視公司(BBC)為青少年程式設計教育設計,並由微軟,三星,ARM,英國蘭卡斯特大學等合作伙伴共同完成開發的微型電腦,目前推出V1,V2兩款,後者較比前者效能稍強。
MakeCode 是微軟所推行的應用於程式設計教育的圖形程式語言,也是micro:bit 目前主流應用的程式語言。
其編輯器主要由三個部分組成,圖形化積木(blocks)編輯器,模擬模擬器,圖形化積木所對應的JavaScript程式碼編輯器。
我對其中關於forever積木在micro:bit 上實機執行的多工效能用邏輯分析儀進行了測試,由於micro:bit V1及V2版本效能有差異,將分別測試並記錄。
2. 測試環境
micro:bit V1及V2版本各一塊,將micro:bit 的引腳全部引出的擴充套件板,SX24M8邏輯分析儀,PulseView。
3. 測試程式1 在五個forever積木中分別控制引腳電平
javascript程式碼:
pins.digitalWritePin(DigitalPin.P12, 0)
pins.digitalWritePin(DigitalPin.P13, 0)
pins.digitalWritePin(DigitalPin.P14, 0)
pins.digitalWritePin(DigitalPin.P15, 0)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(2000)
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P12, 1)
pins.digitalWritePin(DigitalPin.P12, 0)
})
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P13, 1)
pins.digitalWritePin(DigitalPin.P13, 0)
})
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P14, 1)
pins.digitalWritePin(DigitalPin.P14, 0)
})
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P15, 1)
pins.digitalWritePin(DigitalPin.P15, 0)
})
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P16, 1)
pins.digitalWritePin(DigitalPin.P16, 0)
})
3.1 關於forever積木
在on start內的程式執行完後,forever內的程式會被迴圈執行。
forever內沒有while(True)死迴圈的時候,執行完自身內部的程式後會讓出纖程(fiber),此時允許執行其他的forever,即可以在後臺存在多個forever,而多個forever將在系統中組成一個“大迴圈”。
3.2 五個forever的執行順序
micro:bit V1-測試程式1-PulseView截圖:
D0連線P12,D1連線P13,D2連線P14,D3連線P15,D4連線P16。
由此圖可見,執行順序是以javascript程式碼中的順序為準的,而此順序與在圖形化積木編輯器內建立forever積木的順序有關。
3.3 執行digital write pin積木所需要的時間
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
micro:bit V1:6微秒(μs)
micro:bit V2:1微秒(μs)
3.4 從第一個forever開始執行到五個結束執行過後再次拉起第一個forever所需要的最少時間
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
micro:bit V1:24毫秒(ms)
micro:bit V2:20毫秒(ms)
在測試程式1中,即使只有一個forever在執行,再次拉起forever所需要的最少時間也不會改變。
3.5 從一個forever執行完畢到下一個forever開始執行所需要的間隔時間
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
上圖分別是micro:bit V1和V2剛開機時與持續執行約20秒後的表現,發現隨著執行時間的持續,forever之間的執行間隔時間變得不均勻。
4. 測試程式2 加入while迴圈及pause 1ms延時積木
javascript程式碼:
pins.digitalWritePin(DigitalPin.P12, 0)
pins.digitalWritePin(DigitalPin.P13, 0)
pins.digitalWritePin(DigitalPin.P14, 0)
pins.digitalWritePin(DigitalPin.P15, 0)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(2000)
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P12, 1)
pins.digitalWritePin(DigitalPin.P12, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P13, 1)
pins.digitalWritePin(DigitalPin.P13, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P14, 1)
pins.digitalWritePin(DigitalPin.P14, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P15, 1)
pins.digitalWritePin(DigitalPin.P15, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P16, 1)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(1)
}
})
4.1 再次拉起第一個forever所需要的最少時間
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
較比 3.4 中所測得的數值有顯著的減少
micro:bit V1:6毫秒(ms)
micro:bit V2:4毫秒(ms)
4.2 改變pause 1ms延時積木的位置
將pause 1ms延時積木的位置調換到頂部,經過邏輯分析儀測試對結果沒有影響,但如果放置在需要執行的兩個積木中間則會改變執行時間。
4.3 加入while迴圈及pause 1ms延時積木提高了執行效率
while(Ture)迴圈積木單獨加入forever中將形成死迴圈無法讓出纖程(fiber),而再在while中加入pause延時積木,則會使程式執行到此處時,在等待延時的時間同時讓出纖程(fiber),允許其他forever的執行,且延時結束並執行完一次while迴圈內的程式後並不會退出到while迴圈外等待forever積木再次被系統喚起(除非加入了break的條件),while迴圈內的程式將立即迴圈執行,多個forever中都如此設計將極大提高系統執行效率。
並非一定要將pause延時設定為1ms,只要在micro:bit V1中設定低於6ms,micro:bit V2中設定低於4ms,實際執行都將等於這個最低值,而若超出這個值後將按照設定的值來等待延時。
5. 測試程式3 將第一個forever中的pause 1ms延時積木換為show number顯示積木
javascript程式碼:
pins.digitalWritePin(DigitalPin.P12, 0)
pins.digitalWritePin(DigitalPin.P13, 0)
pins.digitalWritePin(DigitalPin.P14, 0)
pins.digitalWritePin(DigitalPin.P15, 0)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(500)
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P12, 1)
pins.digitalWritePin(DigitalPin.P12, 0)
basic.showNumber(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P13, 1)
pins.digitalWritePin(DigitalPin.P13, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P14, 1)
pins.digitalWritePin(DigitalPin.P14, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P15, 1)
pins.digitalWritePin(DigitalPin.P15, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P16, 1)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(1)
}
})
5.1 show number顯示積木在邏輯分析儀中的表現
micro:bit V1-PulseView截圖:
micro:bit V2 表現一致。
在micro:bit 上顯示數字1需要750ms,這750ms的時間裡讓出了纖程(fiber)讓另外4個forever得以正常執行,這證明顯示積木也可以像pause延時積木一樣在while迴圈中讓出纖程(fiber)。
6. 測試程式4 將所有pause 1ms延時積木換為show number顯示積木
6.1 實機LED矩陣顯示效果
micro:bit V1和V2都只能觀察到LED矩陣顯示數字1.
6.2 在邏輯分析儀中的表現
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
在micro:bit V1中僅show number 1所在的while迴圈還在執行,其餘迴圈都沒有執行。
在micro:bit V2中表現的比較特殊,即使LED矩陣並沒有顯示對應數字,也會在每一次show number 1所在的while迴圈完成後,依順序每次迴圈執行一個forever中對引腳電平控制的積木。
7. 測試程式4 再次加入pause 1ms延時積木
7.1 實機LED矩陣顯示效果
micro:bit V1和V2都能觀察到LED矩陣按照順序依次顯示12345.
7.2 在邏輯分析儀中的表現
micro:bit V1-PulseView截圖:
micro:bit V2 表現一致。
與5.1,6.2中所測得的結果相比較,表明show number顯示積木可以在while迴圈中讓出纖程(fiber)允許其他forever中的積木執行,卻無法允許相同的show number顯示積木執行。
只有加入pause 1ms延時積木才可將讓出纖程(fiber)讓其他的show number顯示積木所在的forever得以執行,且必須等到前一個show number顯示積木執行完畢後才可以執行後續的show number顯示積木。
另外show leds,show icon,show arrow顯示積木與之相同,但同樣用於控制LED矩陣顯示的plot X0 Y0積木及其相關聯的積木則無法在while迴圈中讓出纖程(fiber)。
8. 測試程式5 音樂積木
javascript程式碼:
pins.digitalWritePin(DigitalPin.P12, 0)
pins.digitalWritePin(DigitalPin.P13, 0)
pins.digitalWritePin(DigitalPin.P14, 0)
pins.digitalWritePin(DigitalPin.P15, 0)
pins.digitalWritePin(DigitalPin.P16, 0)
music.setVolume(25)
music.setTempo(60)
basic.pause(500)
basic.forever(function () {
while (true) {
music.playTone(262, music.beat(BeatFraction.Whole))
pins.digitalWritePin(DigitalPin.P12, 1)
pins.digitalWritePin(DigitalPin.P12, 0)
}
})
basic.forever(function () {
while (true) {
music.playTone(294, music.beat(BeatFraction.Half))
pins.digitalWritePin(DigitalPin.P13, 1)
pins.digitalWritePin(DigitalPin.P13, 0)
}
})
basic.forever(function () {
while (true) {
music.playTone(330, music.beat(BeatFraction.Quarter))
pins.digitalWritePin(DigitalPin.P14, 1)
pins.digitalWritePin(DigitalPin.P14, 0)
}
})
basic.forever(function () {
while (true) {
music.playTone(349, music.beat(BeatFraction.Eighth))
pins.digitalWritePin(DigitalPin.P15, 1)
pins.digitalWritePin(DigitalPin.P15, 0)
}
})
basic.forever(function () {
while (true) {
music.playTone(392, music.beat(BeatFraction.Sixteenth))
pins.digitalWritePin(DigitalPin.P16, 1)
pins.digitalWritePin(DigitalPin.P16, 0)
}
})
8.1 實際發聲效果
僅測試了micro:bit V2,因為其板載蜂鳴器,如果是micro:bit V1則需痛過引腳外接音響裝置。
從聽覺上大致能判斷實際播放的是“和聲”,即多個音調同時響起,並不會按照forever的順序逐一播放。
8.2 在邏輯分析儀中的表現
micro:bit V2-PulseView截圖:
在while迴圈中沒有加入pause延時積木的情況下也能讓出纖程(fiber)去執行其他的forever。
程式依舊按照forever積木的順序來迴圈執行,但各個forever中的play tone積木將持續執行完其設定的節拍所需的時間後才會執行後續的控制引腳高低電平的積木。
9.小結
micro:bit 應用MakeCode進行程式設計時可以善用forever積木內建一層while迴圈積木和一個pause 1ms延時積木來增強 多工 的效能表現,pause 1ms延時積木新增在所要執行的程式開頭或結尾都可以。