「懸鉤子」的全部文章

勇闖新世界︰ 《 Kernel 4.X 》之整裝蓄勢‧事件驅動‧一

古文觀止》‧卷十 ‧ 心術論  蘇洵

為將之道,當先治心。泰山崩於前而色不變,麋鹿興於左而目不瞬 ,然後可以制利害,可以待敵。

凡兵上義,不義,雖利勿動。非一動之為害,而他日將有所不可措手足也。夫惟義可以怒士,士以義怒,可與百戰。

凡戰之道,未戰養其財,將戰養其力,既戰養其氣,既勝養其心。謹烽燧,嚴斥堠,使耕者無所顧忌,所以養其財;豐犒而優游之,所以養其力;小勝益急,小挫益厲,所以養其氣;用人不盡其所欲為,所以養其心。故士常蓄其怒,懷其欲而不盡。怒不盡則有餘勇 ,欲不盡則有餘貪。故雖并天下,而士不厭兵。此黃帝之所以七十戰而兵不殆也。不養其心,一戰而勝,不可用矣。

凡將欲智而嚴,凡士欲愚。智則不可測,嚴則不可犯,故士皆委己而聽命,夫安得不愚?夫惟士愚,而後可與之皆死。

凡兵之動,知敵之主,知敵之將,而後可與動於險。鄧艾縋兵於蜀中,非劉禪之庸,則百萬之師可以坐縛,彼固有所侮而動也。故古之賢將,能以兵嘗敵,而又以敵自嘗,故去就可以決。

凡主將之道,知理而後可以舉兵,知勢而後可以加兵,知節而後可以用兵。知理則不屈,知勢則不沮,知節則不窮。見小利不動,見小患不避,小利小患,不足以辱吾技也,夫然後有以支大利大患。夫惟養技而自愛者,無敵於天下。故一忍可以支百勇,一靜可以制百動。

兵有長短,敵我一也。敢問:「吾之所長,吾出而用之,彼將不與吾校;吾之所短,吾蔽而置之,彼將強與吾角。奈何?」曰:「吾之所短,吾抗而暴之,使之疑而卻;吾之所長,吾陰而養之,使之狎而墮其中。此用長短之術也。」

善用兵者,使之無所顧,有所恃。無所顧,則知死之不足惜;有所恃,則知不至於必敗。尺箠當猛虎,奮呼而操擊;徒手遇蜥蜴,變色而卻步,人之情也。知此者,可以將矣。袒裼而按劍,則烏獲不敢逼;冠冑衣甲,據兵而寢,則童子彎弓殺之矣。故善用兵者,以形固。夫能以形固,則力有餘矣。

『泰山崩於前』且『麋鹿興於左』,眼見目睹可以置若無聞,可以觸而不動,此『定功』之強,可與『言兵』矣!若夫眼耳鼻舌身意常為『外物』所『觸動』而不得定靜,『事件』川流不斷,目眩而神迷,終將淹沒於『萬象』中,不知其所止耶?

『事件驅動』會意容易,鉤深索隱困難,因為萬象駁雜隨機而發,所以『事件』繁亂無序自來。在此就從如何知道『發生了一件事』說起,略探『事件驅動』的基本想法,講講『中斷服務程序』 ISR interrupt service routine 的概念。維基百科『中斷處理』詞條講︰

In computer systems programming, an interrupt handler, also known as an interrupt service routine or ISR, is a callback function in microcontroller firmware, an operating system or a device driver, whose execution is triggered by the reception of an interrupt. In general, interrupts and their handlers are used to handle high-priority conditions that require the interruption of the current code the processor is executing.[1][2]

Interrupt handlers have a multitude of functions, which vary based on the reason the interrupt was generated and the speed at which the interrupt handler completes its task. For example, pressing a key on a computer keyboard,[1] or moving the mouse, triggers interrupts that call interrupt handlers which read the key, or the mouse’s position, and copy the associated information into the computer’s memory.[2]

An interrupt handler is a low-level counterpart of event handlers. These handlers are initiated by either hardware interrupts or interrupt instructions in software, and are used for servicing hardware devices and transitions between protected modes of operation such as system calls.

 

這裡所說的『中斷interrupt 一般是指『事件告知』方法︰

電腦科學中,中斷英語Interrupt)是指處理器接收到來自硬體或軟體的信號,提示發生了某個事件,應該被注意,這種情況就稱為中斷。

通常,在接收到來自外圍硬體(相對於中央處理器記憶體)的非同步訊號,或來自軟體同步訊 號之後,處理器將會進行相應的硬體/軟體處理。發出這樣的訊號稱為進行中斷請求(interrupt request,IRQ)。硬體中斷導致處理器通過一個執行資訊切換(context switch)來儲存執行狀態(以程式計數器和程式狀態字等暫存器資訊為主);軟體中斷則通常作為CPU指令集中的一個指令 ,以可編程的方式直接指示這種 執行資訊切換,並將處理導向一段中斷處理代碼。中斷在電腦多工處理,尤其是即時系統中尤為有用 。這樣的系統,包括執行於其上的作業系統,也被稱為「中斷驅動的」(interrupt-driven)。

Interrupt_Process

 

然而知道『事件發生』不只有一種方法,比方說『輪詢polling

輪詢Polling)是一種CPU決策如何提供週邊設備服務的方式,又稱「程式控制輸出入」(Programmed I/O)。輪詢法的概念是,由CPU定時發出詢問,依序詢問每一個週邊設備是否需要其服務,有即給予服務,服務結束後再問下一個週邊,接著不斷週而復始。

也是一種常見的方式。這兩種方法的主要差異在於,『中斷法』是由『外部』軟硬體『偵測』事件發生了與否,然後才『告知』系統軟體 ;然而『輪詢法』是作業軟體自己『偵測』事件發生了與否。其中『中斷法』因『效能高』常為作業系統所習用。

linux 是一個『多人多工』的作業系統,假使只有一顆 CPU 要如何完成『多人多工』的呢?靠著 CPU 的『分時分享』 time sharing ,背後的主要『軟硬件』就是『Kernel Timer System』核心計時系統的『中斷處理』流程︰

Timer Wheel, Jiffies and HZ

The original kernel timer system (called the “timer wheel) was based on incrementing a kernel-internal value (jiffies) every timer interrupt. The timer interrupt becomes the default scheduling quamtum, and all other timers are based on jiffies. The timer interrupt rate (and jiffy increment rate) is defined by a compile-time constant called HZ. Different platforms use different values for HZ. Historically, the kernel used 100 as the value for HZ, yielding a jiffy interval of 10 ms. With 2.4, the HZ value for i386 was changed to 1000, yeilding a jiffy interval of 1 ms. Recently (2.6.13) the kernel changed HZ for i386 to 250. (1000 was deemed too high).

Ingo Molnar’s explanation of timer wheel performance

Ingo Molnar did an in-depth explanation about the performance of the current “timer wheel” implementation of timers. This was part of a series of messages trying to justify the addition of ktimers (which have different characteristics).

It is possibly the best explanation of the timer wheel avaiable: See http://lkml.org/lkml/2005/10/19/46 and http://lwn.net/Articles/156329/

 

或許因為樹莓派上並沒有真實時鐘『RTC』 Real Time Clock ,因此引發好奇,那個系統『滴答聲』到底怎麼來的︰

[BareMetal] Timer on Raspi

by dom » Sun Jul 01, 2012 9:45 am
There is a GPU timer which has 4 comparison registers, and 4 interrupts.
There is an ARM timer interrupt.
The ARM timer is derived from the GPU core clock, which unless you force it (with core_freq= in config.txt) is variable due to power management, so not much use as a timer.
So, linux uses the GPU timer for its interrupts.
Note the GPU uses timers 0 and 2. 3 is reserved for linux, so would be most suitable for a bare metal OS. 1 is currently unallocated, so could be used.

 

『事件處理』通常建構於『中斷處理』程序之上,維基百科 event handler 詞條裡說了一個模型︰

Delegate event model

A very common and very “programmer-friendly” variant is the delegate event model, which is provided by the most popular graphic frameworks.

Delegate event model. clickme is the event source –a button in this example–, and it contains a list of listeners.

This model is based on three entities:

  • a control, which is the event source,
  • consumers, also called listeners, that receive the events from the source,
  • interfaces (in the broader meaning of the term) that describe the protocol by which every event is to be communicated.

Furthermore, the model requires that

  • every listener must implement the interface for the event it wants to listen to
  • every listener must register with the source to declare its desire to listen to some particular event
  • every time the source generates an event, it communicates it to the registered listeners, following the protocol of the interface.

也許能對『事件處理』程序之內容,多些一般性的了解。

最後就讓我們用 PiTFT 上的四個 GPIO 按鍵為範例,嘗試以派生三來解說什麼是『輪詢法』和『中斷法』︰

【 polling 】

import RPi.GPIO as GPIO
import time

# 採用 BCM 編號制
GPIO.setmode(GPIO.BCM)

# PiTFT GPIO BCM 之編號
入浮針上 = 17
入浮針中上 = 22
入浮針中下 = 23
入浮針下 = 27

# GPIO 設定
GPIO.setup(入浮針上, GPIO.IN)
GPIO.setup(入浮針上, GPIO.IN,pull_up_down = GPIO.PUD_UP)

GPIO.setup(入浮針中上, GPIO.IN)
GPIO.setup(入浮針中上, GPIO.IN,pull_up_down = GPIO.PUD_UP)

GPIO.setup(入浮針中下, GPIO.IN)
GPIO.setup(入浮針中下, GPIO.IN,pull_up_down = GPIO.PUD_UP)

GPIO.setup(入浮針下, GPIO.IN)
GPIO.setup(入浮針下, GPIO.IN,pull_up_down = GPIO.PUD_UP)

while True:

    if GPIO.input(入浮針上) == 0:
        print("按下入浮針上")
    if GPIO.input(入浮針中上) == 0:
        print("按下入浮針中上")
    if GPIO.input(入浮針中下) == 0:
        print("按下入浮針中下")
    if GPIO.input(入浮針下) == 0:
        print("按下入浮針下")

# 其它作業

# 注意間隔時距的給定。太短,同一事件輸出多次;太長,那個事件或被忽略。
    time.sleep(0.1)

 

【 interrupt 】

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

入浮針上 = 17
入浮針中上 = 22
入浮針中下 = 23
入浮針下 = 27

GPIO.setup(入浮針上, GPIO.IN)
GPIO.setup(入浮針上, GPIO.IN,pull_up_down = GPIO.PUD_UP)

GPIO.setup(入浮針中上, GPIO.IN)
GPIO.setup(入浮針中上, GPIO.IN,pull_up_down = GPIO.PUD_UP)

GPIO.setup(入浮針中下, GPIO.IN)
GPIO.setup(入浮針中下, GPIO.IN,pull_up_down = GPIO.PUD_UP)

GPIO.setup(入浮針下, GPIO.IN)
GPIO.setup(入浮針下, GPIO.IN,pull_up_down = GPIO.PUD_UP)

# 定義總事件處理程式。可以分別定義。
def 回呼程序(來源通道):
    print(來源通道)

# 設定回呼程序。注意 bouncetime 的數值。
GPIO.add_event_detect(入浮針上, GPIO.FALLING, callback=回呼程序, bouncetime=300)
GPIO.add_event_detect(入浮針中上, GPIO.FALLING, callback=回呼程序, bouncetime=300)
GPIO.add_event_detect(入浮針中下, GPIO.FALLING, callback=回呼程序, bouncetime=300)
GPIO.add_event_detect(入浮針下, GPIO.FALLING, callback=回呼程序, bouncetime=300)


while True:
# 其它作業
    time.sleep(1)

 

 

 

 

 

 

 

 

 

勇闖新世界︰ 《 Kernel 4.X 》之整裝蓄勢‧PiTFT | 事件驅動

熟悉 notro/fbtft-spindle 的人,也許已經發現

GPIO keyboard

notro edited this page · 3 revisions

GPIO connected switches can be turned into a keyboard recognized by Linux. It is also possible to execute commands on the Pi based on keyboard events.

gpio_keys

The gpio_keys module creates a keyboard that listens on GPIO’s for keypresses. Keypresses generates events that other processes can receive. The driver is configured with the gpio_keys_device module.

Here is an example creating a keyboard with one key:

sudo modprobe gpio_keys

# KEY_POWER 116 /* SC System Power Down */
sudo modprobe gpio_keys_device active_low keys=22:116

Make it permanent by adding it to /etc/modules

gpio_keys
gpio_keys_device active_low keys=22:116

Note: If there is no external pullup/pulldown resistor, the internal ones must be activated with the pullup or pullup argument to gpio_keys_device.

───

在 Kernel 4.0.9 上並不完整︰

pi@raspberrypi ~ cd /lib/modules/4.0.9-v7+/kernel/drivers/input/keyboard pi@raspberrypi /lib/modules/4.0.9-v7+/kernel/drivers/input/keyboard ls
gpio_keys.ko
pi@raspberrypi /lib/modules/4.0.9-v7+/kernel/drivers/input/keyboard modinfo gpio_keys.ko filename:       /lib/modules/4.0.9-v7+/kernel/drivers/input/keyboard/gpio_keys.ko alias:          platform:gpio-keys description:    Keyboard driver for GPIOs author:         Phil Blundell <pb@handhelds.org> license:        GPL srcversion:     02AA147826065F02B1DCE87 alias:          of:N*T*Cgpio-keys* depends:         intree:         Y vermagic:       4.0.9-v7+ SMP preempt mod_unload modversions ARMv7  pi@raspberrypi /lib/modules/4.0.9-v7+/kernel/drivers/input/keyboard 

 

缺少了 gpio_keys_device ,將要如何定義顯示器上按鍵的呢?由於作者沒有玩過這個模組,所以不知道將來是否會再現??就讓我們借此機會談談所謂的『事件驅動程式設計』。維基百科說︰

事件驅動程式設計英語Event-driven programming)是一種電腦程式設計模型。這種模型的程式執行流程是由使用者的動作(如滑鼠的按鍵,鍵盤的按鍵動作)或者是由其他程式的訊息來決定的 。相對於批次程式設計(batch programming)而言,程式執行的流程是由程式設計師來決定。批次的程式設計在初級程式設計教學課程上是一種方式。然而,事件驅動程式設計這種設計模型是在互動程式(Interactive program)的情況下孕育而生的。

 

,而且又講︰

Event-driven architecture (EDA) is a software architecture pattern promoting the production, detection, consumption of, and reaction to events.

An event can be defined as “a significant change in state“.[1] For example, when a consumer purchases a car, the car’s state changes from “for sale” to “sold”. A car dealer’s system architecture may treat this state change as an event whose occurrence can be made known to other applications within the architecture. From a formal perspective, what is produced, published, propagated, detected or consumed is a (typically asynchronous) message called the event notification, and not the event itself, which is the state change that triggered the message emission. Events do not travel, they just occur. However, the term event is often used metonymically to denote the notification message itself, which may lead to some confusion.

This architectural pattern may be applied by the design and implementation of applications and systems which transmit events among loosely coupled software components and services. An event-driven system typically consists of event emitters (or agents), event consumers (or sinks), and event channels. Emitters have the responsibility to detect, gather, and transfer events. An Event Emitter does not know the consumers of the event, it does not even know if a consumer exists, and in case it exists, it does not know how the event is used or further processed. Sinks have the responsibility of applying a reaction as soon as an event is presented. The reaction might or might not be completely provided by the sink itself. For instance, the sink might just have the responsibility to filter, transform and forward the event to another component or it might provide a self-contained reaction to such event. Event channels are conduits in which events are transmitted from event emitters to event consumers. The knowledge of the correct distribution of events is exclusively present within the event channel. The physical implementation of event channels can be based on traditional components such as message-oriented middleware or point-to-point communication which might require a more appropriate transactional executive framework[clarify].

Building applications and systems around an event-driven architecture allows these applications and systems to be constructed in a manner that facilitates more responsiveness, because event-driven systems are, by design, more normalized to unpredictable and asynchronous environments.[2]

Event-driven architecture can complement service-oriented architecture (SOA) because services can be activated by triggers fired on incoming events.[2][3] This paradigm is particularly useful whenever the sink does not provide any self-contained executive [clarify].

 

讀起來相當抽象,或許因為『事件』 ── 時空點上發生了一件事 ── 的『概念』本身就很抽象之故。假使我們再讀

Criticism_and_best_practice

Event-driven programming is widely used in graphical user interfaces, for instance the Android concurrency frameworks are designed using the Half-Sync/Half-Async pattern,[1] where a combination of a single-threaded event loop processing (for the main UI thread) and synchronous threading (for background threads) is used. This is because the UI-widgets are not thread-safe, and while they are extensible, there is no way to guarantee that all the implementations are thread-safe, thus single-thread model alleviates this issue.

The design of those toolkits has been criticized, e.g., by Miro Samek, for promoting an over-simplified model of event-action, leading programmers to create error prone, difficult to extend and excessively complex application code. He writes,

Such an approach is fertile ground for bugs for at least three reasons:

  1. It always leads to convoluted conditional logic.
  2. Each branching point requires evaluation of a complex expression.
  3. Switching between different modes requires modifying many variables, which all can easily lead to inconsistencies.

— Miro Samek, Who Moved My State?, C/C++ Users Journal, The Embedded Angle column (April 2003)

and advocates the use of state machines as a viable alternative.[2][clarification needed]

 

能不對這個『範式』 Pattern 訝異嗎!那些常與『事件流』打交道的『程式師』,當真是武功高強的耶!?如果思索有一堆『獨立』運作的程式,分享某些共同『資料』與『設備』,各自以自己的『邏輯』解讀『事件流』,產生『事件流』,讀寫那些『資料』和『設備』,沒有良好的邏輯『規劃』,混亂的『狀態』祇靠想像可推知,程式『修補』以符合『目的』之術,能不應運而生的乎!!

如是當知『覺有情』之『觀世音』名號實難得難能也。

佛說如幻三摩地無量印法門經》記載:

能仁作大師子吼,天人一切普得聞,我等今對世尊前,各發誠實最上願:我等乃至未來際,願我所行經多劫,隨入生死輪迴中,救度無數眾生類;我等今者以此緣,盡未來際悉思念,普為利樂諸眾生 ,於無邊劫行無懈;我等從今日已去,永滅貪瞋痴等垢,十方現在佛世尊,證我所說誠無妄;我等今發菩提心,不樂聲聞緣覺果,我等若有樂小心,決定當招妄語報;我所不樂二乘果,但以悲心為眾生,縱經俱胝多劫中,願我常行而不懈;如佛世尊所成就,如應佛剎廣莊嚴,願我當來得佛時,剎土倍多俱胝數;又願當來佛剎中,無有聲聞緣覺眾,純一菩薩所莊嚴,廣集無量諸智聚;願我得是莊嚴已,當令眾生得離垢,從諸佛法所出生,普使當持佛法藏;若我今時諸所說,真實無妄無別異,願此大海及山川,乃至大地皆震動 ;當發如是願言時,大地實時皆震動,不鼓音樂自然鳴,出微妙音遍十方;天雨眾華眾妙香,殊麗嚴好極可愛,俱胝百千妙天衣,周遍繽紛而散布。(這是觀自在菩薩、大勢至菩薩,在「師子遊戲金光王如來」處,一起首發菩提心的誓願。)

 

 

 

 

 

 

 

 

勇闖新世界︰ 《 Kernel 4.X 》之整裝蓄勢‧PiTFT‧三

有關 SPI 界面顯示器的零零種種,在

音樂播放器之 CD 轉成 mp3《三》下‧上

音樂播放器之 CD 轉成 mp3《三》下‧中

音樂播放器之 CD 轉成 mp3《三》下‧下

已經作過很多介紹,雖然當時是用『 PiTFT 3.5″ 觸控螢幕』,事實上原理相同,此處就減筆帶過,僅補之以

【Kernel 4.0.9 開機訊息】

pi@raspberrypi ~ dmesg | grep spi [    1.967198] spi-bcm2835 3f204000.spi: no tx-dma configuration found - not using dma mode [    2.023855] spi spi0.1: setting up native-CS1 as GPIO 7 [    2.027364] stmpe-spi spi0.1: stmpe610 detected, chip id: 0x811 [    2.049302] spi spi0.0: setting up native-CS0 as GPIO 8  # 注意 DMA buffer 訊息 [    2.305710] graphics fb1: fb_ili9340 frame buffer, 320x240, 150 KiB video memory, 4 KiB DMA buffer memory, fps=20, spi0.0 at 32 MHz [    2.493734] fbtft_device:      stmpe610 spi0.1 500kHz 8 bits mode=0x00 [    2.493751] fbtft_device:      ili9340 spi0.0 32000kHz 8 bits mode=0x00 [    2.586974] input: stmpe-ts as /devices/platform/soc/3f204000.spi/spi_master/spi0/spi0.1/stmpe-ts/input/input0 [  198.507575] fb_ili9340 spi0.0: fbtft_update_display: start_line=239 is larger than end_line=0. Shouldn't happen, will do full display update </pre>    <span style="color: #ff0000;">【Kernel 4.1.4 開機訊息】</span> <pre class="lang:sh decode:true ">pi@raspberrypi ~ dmesg | grep spi
[    1.894438] spi spi0.1: setting up native-CS1 as GPIO 7
[    1.903764] stmpe-spi spi0.1: stmpe610 detected, chip id: 0x811
[    1.930096] spi spi0.0: setting up native-CS0 as GPIO 8
[    2.389676] graphics fb1: fb_ili9340 frame buffer, 320x240, 150 KiB video memory, 4 KiB DMA buffer memory, fps=20, spi0.0 at 32 MHz
[    2.584208] fbtft_device:      stmpe610 spi0.1 500kHz 8 bits mode=0x00
[    2.584225] fbtft_device:      ili9340 spi0.0 32000kHz 8 bits mode=0x00
[    2.676952] input: stmpe-ts as /devices/platform/soc/3f204000.spi/spi_master/spi0/spi0.1/stmpe-ts/input/input0

※ 由於此系列多篇文本是以 Kernel 4.0.9 為主作的驗證以及測試,此篇之後,若是 Kernel 4.1.4 之比對測試沒有問題, 將不再出校記 。

 

【中文化 pygame 測試程式】

# -*- coding: utf-8 -*- ← python3 optional, but still good to indicate encoding

# Source: http://inventwithpython.com/drawing.py
# 中文檔改自來源檔

import pygame, sys, os
from pygame.locals import *

# pygame PiTFT 環境設定
os.environ["SDL_VIDEODRIVER"] = "fbcon"
os.environ["SDL_FBDEV"] = "/dev/fb1"

# Uncomment if you have a touch panel and find the X value for your device
os.environ["SDL_MOUSEDRV"] = "TSLIB"
os.environ["SDL_MOUSEDEV"] = "/dev/input/touchscreen"

pygame.init()

# set up the window
顯示面 = pygame.display.set_mode((320, 240), 0, 32)
pygame.display.set_caption('畫圖')

# set up the colors
黑色 = (  0,   0,   0)
白色 = (255, 255, 255)
紅色   = (255,   0,   0)
綠色 = (  0, 255,   0)
藍色  = (  0,   0, 255)

# draw on the surface object
顯示面.fill(白色)
pygame.draw.polygon(顯示面, 綠色, ((16, 0), (111, 106), (36, 277), (56, 27), (0, 106)))
pygame.draw.line(顯示面, 藍色, (60, 60), (120, 60), 4)
pygame.draw.line(顯示面, 藍色, (120, 60), (60, 120))
pygame.draw.line(顯示面, 藍色, (60, 120), (120, 120), 4)
pygame.draw.circle(顯示面, 藍色, (40, 50), 20, 0)
pygame.draw.ellipse(顯示面, 紅色, (110, 200, 40, 80), 1)
盒子 = pygame.draw.rect(顯示面, 紅色, (100, 150, 100, 50))

pixObj = pygame.PixelArray(顯示面)
pixObj[120][144] = 黑色
pixObj[122][146] = 黑色
pixObj[124][148] = 黑色
pixObj[126][158] = 黑色
pixObj[126][158] = 黑色
del pixObj

# run the game loop
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            print("Pos: %sx%s\n" % pygame.mouse.get_pos())
            if 盒子.collidepoint(pygame.mouse.get_pos()):
                pygame.quit()
                sys.exit()
    pygame.display.update()

 

有興趣用 pygame 在 PiTFT 上,開發軟體的朋友,請注意

# pygame PiTFT 環境設定

os.environ[“SDL_VIDEODRIVER”] = “fbcon”
os.environ[“SDL_FBDEV”] = “/dev/fb1”

# Uncomment if you have a touch panel and find the X value for your device

# 觸控裝置宣告
os.environ[“SDL_MOUSEDRV”] = “TSLIB”
os.environ[“SDL_MOUSEDEV”] = “/dev/input/touchscreen”

。其次在

Physical computing ︰ python 《補充》︰ IDE 用法……

系列中,我們介紹過一個特別的 Python IDE︰

這個『 Ninja-IDE 』有一個特色,就是能找出 Python 程式不符合『 PEP8 』建議的『原始碼』,彰顯了『 Pythonic Way 』的重要組成部分。在此讓我們舉個出自美國 Simpson College 的 Paul Vincent Craven 所著的線上書《 Program Arcade Games With Python And Pygame 》第二十章中的『 fractal.py 』為例,比較符不符合『 PEP8 』的異同︰

feature-errors
Highlight Static and PEP8 errors in the document, you can also see that the files containing PEP8 errors are shown with an icon in the tab where the file is opened, and files containing code static errors are shown with a bug icon in that tab.

 

關於 pygame 的線上書,增加 Albert Sweigart 先生所寫的

Invent with Python 系列書籍。

header image

Automate the Boring Stuff with Python cover thumbnail Invent with Python cover thumbnail Making Games cover thumbnail Hacking Secret Ciphers cover thumbnail

 

以及簡單的 PiTFT

【按鍵測試程式】

pi@raspberrypi ~ $ sudo -s
root@raspberrypi:/home/pi# python3
Python 3.2.3 (default, Mar  1 2013, 11:53:50) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO as GPIO
>>> import time
>>> GPIO.setmode(GPIO.BCM)
>>> 入浮針 = 17
>>> GPIO.setup(入浮針, GPIO.IN)
>>> GPIO.input(入浮針)
0
>>> GPIO.input(入浮針)
0
>>> GPIO.input(入浮針)
0
>>> GPIO.input(入浮針)
0
>>> GPIO.input(入浮針)
0
>>> GPIO.setup(入浮針, GPIO.IN,pull_up_down = GPIO.PUD_UP)
>>> GPIO.input(入浮針)
1
>>> GPIO.input(入浮針)
0
>>> GPIO.input(入浮針)
1
>>> 

※ 注意! Adafruit 不過是用 BCM 『編碼制』及『編號』的樹莓派 GPIO 輸入也。

 

 

 

 

 

 

 

 

 

勇闖新世界︰ 《 Kernel 4.X 》之整裝蓄勢‧PiTFT‧二

大自然用著『基因』紀錄『譜系』,人類為著『分類』而將產品作『編號』。然而透過『編號』有時後並不容易區分事物,因此務須小心。比方說 PiTFT 名目下有前後多種產品,『編號』雖是不同,『名稱』卻是相同,但是不同版本或來源之『核心』 Kernel 的控制很可能不同。在此我們採用的是

【40 PIN 按鍵在右的 #2298

2298-16

 

不是【早期 26 PIN 按鍵在下的 #1601

x1601-00.jpg.pagespeed.ic.ptI8PZq86n

 

若是不審慎一點,當閱讀某些網路文章片段時︰

Backlight Control

Controlling the backlight

There’s a 4-LED backlight on the TFT and it draws ~75mA at all times. There might be times you’d like to save some power and turn off the backlight. The screen and touchplate will still work, you just can’t see anything. We designed the board with the STMPE610 touchscreen controller which has 2 extra GPIO and tied one of them to the transistor that controls the backlight. You can use the command line to control the backlight.

Start by getting access to the GPIO by making a device link

sudo sh -c “echo 508 > /sys/class/gpio/export”
ls -l /sys/class/gpio

Please note, previous versions of the PiTFT kernel had the STMPE GPIO pin ‘252’ not ‘508’ so just substitue that number

Once you verify that you see GPIO #508, then you can set it to an output, this will turn off the display since it will output 0 by default

sudo sh -c “echo ‘out’ > /sys/class/gpio/gpio508/direction”

Then turn the display back on with

sudo sh -c “echo ‘1’ > /sys/class/gpio/gpio508/value”

or back off

sudo sh -c “echo ‘0’ > /sys/class/gpio/gpio508/value”

 

將不知所指,或許會誤解叢生的吧!

這裡的『/sys/class/gpio/』使用者界面,就是之前

Physical computing ︰《三》 GPIO 溯源《上》》文本中所講的︰

二零零六年,在

LKML.ORG? 】︰

In case you haven’t read the titlebar of your webbrowser’s window: this site is the (unofficial) Linux Kernel Mailing List archive. This mailing list is a rather high-volume list, where (technical) discussions on the design of, and bugs in the Linux kernel take place. If that scares you, please read the FAQ.

David Brownell 的一封《電郵》【 Re: [-mm patch 1/4] GPIO framework for AVR32 】開啟了『 GPIO 』之『軟體架構』的討論,大體可說到二零零八年【※Re: [ patch 2.6.24-rc6-mm 2/9] gpiolib: add gpio provider infrastructure 】之前, Linux kernel 的
GPIO Sysfs Interface for Userspace 》整體已經完成。讀者可以參考《  GPIO Interfaces 》與《 Linux/include/linux/gpio.h 》文件作進一步了解。

……

讀者也許可以讀讀那《》《》《》三篇文章,對於『GPIO』之架構與實務能有多一些了解。雖說有部份內容,因著核心改版而變遷,讀書之法或應如

M♪o 之學習筆記本《子》開關︰【青木仁】格物致知

的 M♪o 般與時偕行,能自主驗證,這才是格物致知之道也︰

行 ︰《小狐狸》之書曾寫過︰

就讓我們透過『 Sysfs 』── 是 Linux 2.6 所提供的一種『虛擬檔案系統』 VFS virtual files system 。這個檔案系統不僅可以把『裝置』 devices 和『驅動程式』 device drivers 的資訊從『核心』 kernel 內部輸出到『使用者空間』 user space ,也可以用來對裝置和驅動程式做『設定』。── 來控制『系統 ACT LED』,與 GPIO建立聯繫』吧!

# 為什麼一定得是 root 呢?可以只用 sudo 嗎??
sudo -s

echo none > /sys/class/leds/led0/trigger
echo 1 >/sys/class/leds/led0/brightness
echo 0 >/sys/class/leds/led0/brightness
echo 1 >/sys/class/leds/led0/brightness
echo 0 >/sys/class/leds/led0/brightness
exit

 

Ah Ha!!這樣想要有顆『閃爍』的『小星星』,怕是不可得的了,何不閱讀《 Advanced Bash-Scripting Guide 》一下,寫個『 Shell 』程式呢??

。雖說曾聞『早鳥氏』實證時否定了,然『盡信書,不如無書』,況此一時彼一時已經不同,何不自己格之!!

root@raspberrypi:/sys/class/gpio# cd /sys/class/leds/
root@raspberrypi:/sys/class/leds# ls
led0  led1
root@raspberrypi:/sys/class/leds# cd led0
root@raspberrypi:/sys/class/leds/led0# ls
brightness  device  max_brightness  subsystem  trigger	uevent
echo none > /sys/class/leds/led0/trigger
root@raspberrypi:/sys/class/leds/led0# echo 1 >/sys/class/leds/led0/brightness
root@raspberrypi:/sys/class/leds/led0# echo 0 >/sys/class/leds/led0/brightness
root@raspberrypi:/sys/class/leds/led0# 

果然大功告成。噫!怎有個『 led1 』哩?何妨依樣畫葫蘆!… ☿☺

 

【Kernel 4.0.9 系統參考】

pi@raspberrypi ~ cd /sys/class/gpio/  pi@raspberrypi /sys/class/gpio ls
export  gpiochip0  gpiochip506  unexport

# 背光 LED 測試
pi@raspberrypi /sys/class/gpio sudo sh -c "echo 508 > /sys/class/gpio/export"  pi@raspberrypi /sys/class/gpio ls
export  gpio508  gpiochip0  gpiochip506  unexport

# 關閉背光 LED
pi@raspberrypi /sys/class/gpio sudo sh -c "echo 'out' > /sys/class/gpio/gpio508/direction"  # 打開背光 LED pi@raspberrypi /sys/class/gpio sudo sh -c "echo '1' > /sys/class/gpio/gpio508/value"

# 系統 LED 
pi@raspberrypi /sys/class/gpio cd /sys/class/leds/ pi@raspberrypi /sys/class/leds ls
led0  led1
pi@raspberrypi /sys/class/leds cd  # Kernel 版本 pi@raspberrypi ~ cat /proc/version 
Linux version 4.0.9-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #807 SMP PREEMPT Fri Jul 24 15:21:02 BST 2015
pi@raspberrypi ~ </pre>    <span style="color: #ff0000;">───</span>  <span style="color: #ff0000;">【※ 最新 Kernel 4.1.4 系統參考對比測試 OK】</span> <pre class="lang:sh decode:true ">pi@raspberrypi ~ cat /proc/version 
Linux version 4.1.4-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #808 SMP PREEMPT Thu Aug 6 16:59:39 BST 2015

pi@raspberrypi ~ cd /sys/class/gpio/ pi@raspberrypi /sys/class/gpio ls
export  gpiochip0  gpiochip506  unexport
pi@raspberrypi /sys/class/gpio sudo sh -c "echo 508 > /sys/class/gpio/export" pi@raspberrypi /sys/class/gpio ls
export  gpio508  gpiochip0  gpiochip506  unexport
pi@raspberrypi /sys/class/gpio sudo sh -c "echo 'out' > /sys/class/gpio/gpio508/direction" pi@raspberrypi /sys/class/gpio sudo sh -c "echo '1' > /sys/class/gpio/gpio508/value"
pi@raspberrypi /sys/class/gpio cd /sys/class/leds/ pi@raspberrypi /sys/class/leds ls
led0  led1
pi@raspberrypi /sys/class/leds $ 

 

 

 

 

 

 

 

 

勇闖新世界︰ 《 Kernel 4.X 》之整裝蓄勢‧PiTFT‧一

起初樹莓派上並沒有以 SPI 匯流排為界面的 TFT LCD 之 Framebuffer 驅動程式。許多的發展與貢獻來自 notro 先生,如今這個驅動程式已經合併於官方板的核心內,從

/fbtft

Home

notro edited this page · 142 revisions

Linux Framebuffer drivers for small TFT LCD display modules.

For a list of all wikipages see Pages

FBTFT development has moved
The FBTFT drivers are now in the Linux kernel: drivers/staging/fbtft (details).

Install

The FBTFT drivers are now included in the Raspberry Pi Foundation kernel and can be installed with plain rpi-update.
There is one piece missing and that is a DMA capable SPI controller driver to get max performance. So for fbcp and showing movies, the FBTFT kernel still has to be used.

See /boot/overlays/README and FBTFT RPI overlays for information about Device Tree overlays.

To use fbtft_device instead of a DT overlay, add to /boot/config.txt:

dtparam=spi=on

FBTFT kernel with SPI DMA

sudo REPO_URI=https://github.com/notro/rpi-firmware rpi-update

2015-07-11

2015-03-27

  • FBTFT support is now in raspberrypi/linux. This release only adds SPI DMA support on top of that.
  • pitft overlay changed name to pitft28-resistive
  • These modules are no longer present:
    • gpio_keys_device – DT overlay example
    • ads7846_device – Use ads7846 DT overlay instead. See /boot/overlays/README
    • gpio_mouse_device
    • stmpe_device
    • gpio_backlight_device
    • rpi_power_switch
    • spi-config
  • Builtin console fonts are not enabled (fbcon=font:XX).
  • Other kconfig options no longer enabled:
    • MOUSE_GPIO
    • GPIO_MCP23S08
    • DYNAMIC_DEBUG
  • 2015-02-07
    • Add Raspberry Pi 2 support

……

網頁日誌來看,已經大功告成,或將功成身退的了。

一個小型的顯示器對於許多應用十分重要,甚至不可或缺。假使要考察『新世界物品』,不得不及於此物之介紹,在此選擇介紹最早成名且聽聞銷售很好的『PiTFT』顯示器之安裝設定以饗讀者,也許可當成一般性的範例的吧。為了更貼近即將到來的樹莓派硬體界面之『 HATs 』Hardware Attached on Top 規範,我們將採用 40 pins 的

PiTFT Plus Assembled 320×240 2.8″ TFT + Resistive Touchscreen – Pi 2 and Model A+ / B+

Description

Is this not the cutest little display for the Raspberry Pi? It features a 2.8″ display with 320×240 16-bit color pixels and a resistive touch overlay. The plate uses the high speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images or video etc. Best of all it plugs right in on top!This updated design fits perfectly onto the Pi Model A+, B+, or Pi 2! Works just like the Model B version, but now matches the outline of the Raspberry Pi 2 and Model B+. It also has all 40 pins GPIO pins brought out so you can connect a 40-pin GPIO cable underneath. Now that it’s the same outline as a Pi 2/B+ it fits well on top of a Pi in our Raspberry Pi Enclosure base.The display and touchscreen uses the hardware SPI pins (SCK, MOSI, MISO, CE0, CE1) as well as GPIO #25 and #24. All other GPIO are unused. Since we had a tiny bit of space, there’s 4 slim tactile switches wired to four GPIOs, that you can use if you want to make a basic user interface. For example, you can use one as a power on/off button. See below for the link to get the optional tact switches, they’re not included.

Use it for console access or easily pop up X11 onto the PiTFT for a mini monitor, although its rather small at 320×240. Instead, we recommend using PyGame or other SDL-drawing programs to write onto the frame buffer.

作為討論範本。

無論讀者是否安裝過這個顯示器,首先請詳細閱讀

Adafruit PiTFT – 2.8″ Touchscreen Display for Raspberry Pi 》 之說明文件,應當很容易將此顯示器安裝而且設定好。我們將在此基礎上,談談如何修改設定檔使之適合樹莓派基金會官方板 raspbian 之 Kernel 4.X 升級。為了避免冗長重複,此處說明極為減省,尚祈讀者體諒。一般 raspbian 版本上的安裝 PiTFT 概要︰※必須有網際網路

加載 Adafruit 網路程式庫

curl -SLs https://apt.adafruit.com/add | sudo bash

 

安裝 Adafruit 編譯的 Kernel 與 顯示器安裝程式

sudo apt-get install raspberrypi-bootloader
sudo apt-get install adafruit-pitft-helper

 

安裝 2.8″ 電阻式觸控 PiTFT

sudo adafruit-pitft-helper -t 28r

 

選擇 Y 啟動開機顯示

At the end you will be prompted on whether you want the text console to appear on the PiTFT. Answer Y or N depending on your personal desires!

 

就是這麼簡單就已經完成的了。請經過開機驗證後,將

升級核心

sudo rpi-update

 

然後將『Adafruit /boot/config.txt』

[pi1]
device_tree=bcm2708-rpi-b-plus.dtb
[pi2]
device_tree=bcm2709-rpi-2-b.dtb
[all]
dtparam=spi=on
dtparam=i2c1=on
dtparam=i2c_arm=on
dtoverlay=pitft28r,rotate=90,speed=32000000,fps=20

 

更改為

# --- added by adafruit-pitft-helper 五  7月 24 15:22:47 CST 2015 ---
# [pi1]
# device_tree=bcm2708-rpi-b-plus.dtb
# [pi2]
# device_tree=bcm2709-rpi-2-b.dtb
# [all]
dtparam=spi=on
dtparam=i2c1=on
dtparam=i2c_arm=on

# 修改成 Kernel 4.X 內提供的 pitft28-resistive-overlay.dtb overlay
dtoverlay=pitft28-resistive-overlay.dtb,rotate=90,speed=32000000,fps=20
# --- end adafruit-pitft-helper 五  7月 24 15:22:47 CST 2015 ---

 

再次啟動後

sudo reboot

你已擁有 Kernel 4.X 版的 PiTFT 平台的了。

 

 

※ 註記︰ rpi-update 的核心已更新至 4.1.4 ,是否有問題待驗證!