2019年12月30日 星期一

[python] Why Enclosing Function?




有時候函式某些參數, 可能只要第一次代入後,

而之後呼叫時參數都是相同的, 不希望每次呼叫都要一直代入相同的參數… 



  1. 使用global 變數 ? 程式結構不佳
  2. 使用預設參數? 但預設的又不是我想要的, 也是等於每一次呼叫都要代入
  3. 拿掉該參數? 但因為至少第一次呼叫時可能要代入不同的值, 但拿掉後此函數後就無法有代入參數的能力了


.


更多python程式設計請參考 Python 程式設計

2019年12月16日 星期一

什麼是Device Tree?



什麼是Device Tree?

目前Raspberry Pi 3 的kernel 核心為 4.4.y, 只可以使用 Device Tree 來描述 Internal SoC 及 External (Board level) 的硬體資源.

Device Tree 就是把 Platform Device 架構中用來描述硬體資源的部份給抽出來, 因為Platform Device 的檔案是用C code去描述的, 但概念上硬體資源的描述應和程式無關也與Linux版本無關. 用C 去描述很慘, 因為只要重新定義硬體資源都要重新編譯核心, 很浪費時間. 再來, 要去描述硬體資源,如果不熟悉C的語法, 也很難去寫 ,因為C語法不對會導致編譯失敗。

 Device Tree架構, 解決了上述這些問題, 不用懂C也能定義硬體資源, 如此硬體工程師也可以做了,因為pin 腳拉那根做什麼功能, 硬體工程師最清楚 ,不然做軟體,寫code的人就要自己去對線路圖 (也不是不行, 但如果有對的人做掉, 豈不更快!)


硬體資源: 包含 SoC-level (.dtsi)及 board level (.dts)

  1. 描述CPU, RAM size
  2. 描述 Memory-mapped 上的元件, PWM、UART、I2C、SPI等晶片內部元件的描述, 如暫存器位址及大小, 中斷號碼、DMA,, pinctrl
  3. 描述外部連接裝置, 如裝置規格, 以flash來說,包含 page size, flash size等資訊, 通常寫device driver會從這裡取得裝置資訊. 外部裝置通常使用 device tree overlay (產生.dtbo)的方式而不要直接修改.dts.
Device Tree  
1.  不用重新 compile source code 即可以更改系統的 configuration
2.  當硬體只有小小的更改,只需要 dts 檔小改, 然後再重新編譯出dtb即可。
3.  可以重複使用已存在的 dts 檔在其他地方,也可以覆蓋過去定義的功能
4.  移除 C code ,使得硬體的描述架構更清楚。 




實測:

(1) 加入MCP3008 ADC device到 device tree 中, 會自動掛載 .compatible="mcp3008" 的驅動程式. 

> dtc -@ -I dts -O dtb -o mcp300x.dtbo mcp300x.dts
sudo dtoverlay ./mcp300x.dtbo

(2) 讀取ADC channel 0

cat /sys/bus/iio/devices/iio:device0/in_voltage0_raw





References










2019年12月1日 星期日

好用的PDF度量功能



這可以用來量PCB元件尺寸及其他任何時候你只有PDF的時候..你仍然可以量尺寸
只要透過 Distance  功具, 底下以房屋平面圖來說明..

[Comment] Distance 



















拉的時候..可以同時按下鍵盤的Shift 鍵 , 可以拉出水平及垂直的直線






可以為每一把尺設定自己比例尺  

[ Measuring Tools ]--> [Format ] --> Scale

例如 : 1pt=1.77 公分










2019年11月20日 星期三

[python] dict 依據value排序

不使用內建的sorted()函式, 例如

new_data=sorted(data.items(), key=lambda x: x[1],reverse=True) 


將dict依照value 進行排序 new_data=sort_dict_by_value(data,reverse=True)



2019年10月6日 星期日

Pi 新手教學(零) --艾鍗Raspberry Pi I/O Shield 規格介紹



艾鍗Raspberry Pi 擴充板 (適用Pi 3, Pi 3+, Pi 4)

ADC、DC馬達驅動、G-sensor、紅外線收發器、OLED、Buzzer、LED、Button、DIP Switch、Relay

V3.0 Raspberry Pi 擴充板簡要說明 
  1. 由於Raspberry Pi 沒有類比輸入的能力: 所以此擴充板加入ADC 晶片以提供8 通道的類比訊號輸入, 如此可以讓Raspberry Pi 可以擁有連接類比感測器的的能力
  2. 拉出Pi的硬體PWM訊號腳, 並加入DC 驅動電路, 使Pi 可以直接連接DC 馬達、BLDC無刷馬達
  3. USB Debug Console: 不用再買Serial-TO-USB的轉接線材了, 本擴充板已內建PL2303晶片了, 故可以直接接到PC USB
  4. 同時擁有IR紅外線發送器及接收器, 可以讓Pi當作多媒體的應用平台或IR遙控器
  5. 附有OLED的模組,可以直接接上OLED用來顯示系統狀態
  6. TH1 可以直接連接光敏電阻, 可以進行光度感測 (光敏電阻將隨出貨附贈)
  7. 內建 G-Sensor (LIS3DH) 可以感測Pi 在X,Y,Z軸方向的移動狀態
  8. 附有nRF24L01的2.4G RF通訊模組,可進行2.4G 無線通訊實驗
  9. 用DIP Switch 記錄不同狀態,Pi 就能有不同的啓動狀態或選擇進入不同的功能模式
  10. 接出I2C連接座和SPI連接座方便外接更多的數位式感測器





2019年9月6日 星期五

常用數學符號的 LaTeX 表示方法


在jupyter notebook 插入LaTeX數學公式, 前後要包 $$..............$$


## Euclidean and Cosine distance
Euclidean:  $$d(x,y)=\sqrt{\sum^n_{i=1}(x_i - y_i)^2}$$

Cosine:  $$\theta(x,y)=\frac{x \bullet y}{ \sqrt{x \bullet x} \sqrt{y \bullet y}}$$


常用數學符號的 LaTeX 表示方法
http://mohu.org/info/symbols/symbols.htm

Online LaTeX Equation Editor - create, integrate and download
https://latex.codecogs.com/eqneditor/editor.php
About LaTeX 
很多論文及科學文章都會用到LaTeX。它是一個公式編輯系統,使用簡單的指令構建出專業的數學公式。


Markdown Cell內容




輸出結果




如果公式不要換行,則只要使用一個$去包,Letex

$\alpha$ 愈小等同於Linear Regression

在Jupyter Notebook 輸出會像這樣



2019年8月16日 星期五

Raspberry Pi Mail Box--tag buffer


Raspberry Pi Mailbox的機制是你CPU 送出Request所用的buffer , 在GPU Response 回來時是會被修改的.因為使用的是同一塊Buffer, 所以Request傳送的資料佔了幾個byte (bit 30:0 Value Length)及 Response回來有多少個byte ,在送出Request就要決定了
 value buffer 的大小一定是max(Request data length, Response data length)




value buffer size in bytes 是指value buffer的大小;
  value length in bytes 是請求欄位佔幾個Byte



ARM Bare metal 開發課程連結

2019年8月14日 星期三

[Linux Driver 問題] Linux GPIO Host Controller驅動程式



目前課程影片進行到CH3-3 Linux GPIO Host Controller驅動程式,有一些問題如下:

  1. 01_LED中chr_led.c使用gpio_set_value對GPIO Pin設定輸出值,往Kernel Source Code追: gpio_set_value -> __gpio_set_value -> gpiod_set_raw_value -> _gpiod_set_raw_value ->


    static void _gpiod_set_raw_value(struct gpio_desc *desc, bool value)
    {
            struct gpio_chip        *chip;

            chip = desc->chip;
            trace_gpio_value(desc_to_gpio(desc), 0, value);
            if (test_bit(FLAG_OPEN_DRAIN, &desc->flags))
                    _gpio_set_open_drain_value(desc, value);
            else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags))
                    _gpio_set_open_source_value(desc, value);
            else
                    chip->set(chip, gpio_chip_hwgpio(desc), value);
    }

    追到最後是課程影片中提到的struct gpio_chip,但是課程提供的Image中找不到bcm2708_gpio.c這個檔案,struct gpio_chip中的function應該都是實作在這個檔案中?
        ~/linux-rpi-4.4.y/drivers/bcma/driver_gpio.c  ==> gpio chip driver 
  1. 根據課程影片,gpio_set_value是上層API,由Kernel定義。struct gpio_chip中的function pointer實作則為底層硬體相關,這個部分理論上應該是SoC廠實作並提供給客戶嗎?想知道業界實務上怎麼分配?實務上,如果拿到一塊公版,SoC Vendor會提供整包Linux或Android Source Code,我們只需要針對自己選擇的外接硬體寫驅動程式嗎?
       
            
  1. SoC Vendor是否連Driver Template都會一起提供於整包OS Source Code中,只需要修改對應硬體部分?譬如,選擇的Display不同,選擇的Sensor不同,只需要在module_init()中修改初始化代碼?

             晶片廠通常提供的BSP ,會做好大部份SoC Driver. 若是自己自行外接的, 則要靠自己去撰寫或移植

             同類型硬體其Driver 寫法差異不大,所以可以參考現有的code去修改即可.. 

2019年8月12日 星期一

如何界定User Space Driver和Kernel Space Driver?


課程提供的Image中有一個bcm2835_clibbcm2835_clib資料夾,裡面有兩個資料夾。其中一個example應該是控制IT Shield上面不同External Device的Source Code。另一個src資料夾是不是類似"SoC HAL或BSP"之類的腳色,看起來比較像HAL,因為沒有包成板上Device控制的API,而是SoC Peripheral? 這是底層的HAL code 供上層使用 其中,下面的程式碼中為什麼是MAP_FAILED,而不是BCM2835_GPIO_BASEADDR之類的暫存器位置,而且找不到MAP_FAILED這個MACRO的定義 bcm2835_init () 會給正確值 另外,這樣子的寫法如果理解沒有錯誤,應該是Base Metal的寫法。為什麼blink.c編譯出來的執行檔可以直接執行? 這樣是不是等於不是走syscall -> LDD的方式,這樣Kernel怎麼管理這種Process? 這種方式如何界定User Space和Kernel Space? 這是User Space Driver 的寫法.. Kernel 只當它是一般User Process來管理..所以無法像Kernel Space Driver可以在底層做設備管理
User Space Driver 作法可以走 device file 的方式, 也可以用mmap(2)方式來操作SFR (special function register) . 細節可以自行參考 bcm2835_init () 函式

2019年8月6日 星期二

將vim預設語法Highlight 打開



sudo apt-get install vim

將vim開啓程式,預設即是語法Highlight 打開 (syntax highlighting in vim)

修改 vim $HOME/.vimrc


加入這一行

syntax on

存檔離開



2019年8月5日 星期一

[ARM Boot Loader ] code 說明


有個問題請教一下
Linker Start up code那個章節 56分:28秒的那一段
1. For broad com的bootloader,是不是也應該會把vector table copy to RAM 0x00的位置?
2. Power on and Reset 是一樣的嗎? 都會直接執行RAM上面0x00的位置? 還是Power on的時候會從走一次bootloader,然後copy vector table to RAM 0x00.
是會有誰把vector table copy過去才對。但影片中說reset一開始就跑0x00,0x00要有instructions.讓我聽得有點模糊。reset的時候 , RAM的內容都還保留著? 只有Power on and Power on的情況才會重新從bootloader copy vector table to RAM?

 每個系統有其 PowerOn 流程,如從ROM, EEPROM, NOR Flash或特定bootable devcie開機,而這些地方就是要先放好Exception Vector Table的地方,Power on 即觸發ARM Reset Exception , 故立即進行ARM Reset Handler 的工作。而這個Reset 工作的執行 (Stage 1 boot ),是屬於XIP (Excute In Place) ,即boot code是在ROM或Nor Flash 內被執行的。
Reset 工作初始化SDARM, SDRAM  , ROM 分別映射到CPU定址空間的一塊位址, 如SDRAM 位於 0x0, 若啓用CPU virtual address , 舉例 0x8000 (使用CPU virtual) 也是對應到SDRAM 。接著copy 一份完整的boot code 到SDRAM (頭幾行的內容當然也會是Exception Vector )。

將CPU的PC 指向ARM Reset Handler ( Stage 2 boot ) , 而此時的Reset Handler 是在SDRAM內。並且這時候的ARM Reset Handler 和前面一開始開機的ARM Reset 做不一樣的事了。前面ARM reset 可以只作少量的事, 後面的Reset 做更多事, 如驅動裝置,如 UART, LED, 等, 還有準備好OS載入的相關工作。



我想知道一般broadcom的bootloader,不含我們bootloader的流程。到底有沒有copy vector table to RAM 0x00,以及power on/off and reset是否一樣?

ARM Reset時, 做copy o RAM (可參考上課實作的程式碼)

 如果不一樣,是否power on/off, bootloader會重新copy vector table to RAM, 至於reset是用之前已經copy過存留在RAM的vector table.

  

還有一個問題,RAM and ROM share 相同的位置空間嗎? 不同空間 
課程中常提到 0x8000 and 0x0。這個位置 是RAM 還是 ROM。當我拿到一個位置的時候,我怎麼知道他是RAM還是ROM還是某個peripheral?
   
    0x8000 and 0x0 都可以對應到RAM 

   詳看SoC 晶片手冊..一般 memory map 會告訴你address指的是什麼....

    

2019年8月4日 星期日

軟體開發工具



SVN 基本概念







SVN基本使用步驟:

1.  下載並安裝 Windwos SVN Client工具-- tortoisesvn
2.  新增資料匣, 然後按右鍵新選擇 [SVN Checkout.] , 輸入URL of Repository ,
 , 接著輸入SVN 帳密. 即可checkout 程式碼.






3. 之後可以若要更新程式(即和SVN Server 同步) 則可以按右鍵執行 [SVN Update].

  svn update 

4. 對於既有的檔案有修改可以[SVN Commit] 上傳到SVN Server上

  svn commit -m "message"

5. 對SVN Repository 有要新增/刪除的檔案或目錄,到則要先用 [SVN Add]/[SVN Del], 再SVN Commit 才正式納入版本控制,別人SVN Update 時也才看得到..

 svn add folder_name/file_name
 svn del folder_name//file_name





====================================

Trello 專題使用說明




在Trello上對於文字的格式處理採用Markdown語法, 這點和github上的README.md
相同

How To Format Your Text in Trello

2019年8月3日 星期六

ESP8266 HTTP GET/POST





開始進入HTTP Body,  HTTP Header 結尾必定是連續2組\r\n \r\n , 接著就是準備好實際HTTP要傳送的內容,


ESP8266 寫法1:
String cmd = "GET /test.html HTTP/1.1"; 
ESP8266.println("AT+CIPSEND=4," + String(cmd.length() + 4)); 
delay(1000);
ESP8266.println(cmd);
 delay(1000); 
ESP8266.println(""); 

ESP8266 寫法2:
  sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //  access point
  sendData("AT+CIFSR\r\n", 1000, DEBUG); // get ip address
  sendData("AT+CIPMUX=1\r\n", 1000, DEBUG); // configure for multiple connections
  sendData("AT+CIPSTART=4,\"TCP\",\"api.thingspeak.com\",80\r\n", 1000, DEBUG); // turn on server on port 80
  key = 23;   //random number for testing
  String web = "GET http://api.thingspeak.com/update?api_key=KTQXXXXXXXXXXXXX&field1="";
  web += key;
  web += "HTTP / 1.0";
  web += "\r\n";
  web += "\r\n";

//HTTP Body 開始
  String cipsend = "AT + CIPSEND = ";
  cipsend += 4;
  cipsend += ", ";
  cipsend += String(web.length());

ReadMore:


  1. HTTP 的訊息格式處理
  2. 可以透過wireshark 抓封包軟體, 解析出HTTP 通訊協定https://www.wireshark.org/download.html



2019年7月26日 星期五

在anaconda 下,tensorflow 如何降版本?



例如tensorflow 1.13.0降到 1.12.0

conda install tensorflow=1.12.0
會問你是否要降..包含其他dependency 套件也一併會降

回答Y, 就會開始降版

之後再檢查版本是否己降版
import tensorflow as tf
print(tf.__version__)