2019年2月27日 星期三

利用Vrefint校正ADC

電池相關裝置,因為省電,一般不會安裝穩壓元件,Pin數少的MCU也無外部Vref可用。
可以利用STM32內建的ADC_IN17生成的固定電壓源做數值校正。
aADCxConvertedData[4]就是ADC_IN17,預設值為1510,若是現值變了,轉換值就存於v_factor。故ADC取值成功,就先做轉換值計算,其他的ADC值就可以依轉換值回推到原值。

int v_factor;
unsigned short adc_value[ADC_CONVETED_DATA_BUFFER_SIZE - 1];
#define V_STD (1510)
#define V_FACTOR_SET(n) (v_factor = ((V_STD << 16) / (n)))
#define V_FACTOR_ADJ(x) (((x)*v_factor) >> 16)
HAL_ADCEx_EnableVREFINT();
MX_ADC_Init();
HAL_ADC_Start_DMA(&hadc, (uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE);
crDELAY(xHandle, MS(2));
V_FACTOR_SET(aADCxConvertedData[4]);
adc_value[0] = V_FACTOR_ADJ(aADCxConvertedData[0]);
adc_value[1] = V_FACTOR_ADJ(aADCxConvertedData[1]);
adc_value[2] = V_FACTOR_ADJ(aADCxConvertedData[2]);
adc_value[3] = V_FACTOR_ADJ(aADCxConvertedData[3]);


2019年1月29日 星期二

量子時代

手機是現科技及經濟指標產品。它的下一代也是科技方向。所以再下去就是量子時代。
鏡頭用量子光學薄膜,取代光學透鏡。
螢幕色彩用量子點,可以自由控制發光波長。
環境檢知(AR用)雷射,用量子光陷阱共振腔。
通信用量子加密。
服務用計算機是量子電腦。手機上會不會引入量子電腦看來只是時間上的問題。
觸控用的石墨烯運作原理也和量子有關。
記憶體不知何時會有量子記憶體。
只剩下電池還沒有看到量子插手,但不保證。



看來已不是只有量子霸權問題,根本是進入量子時代。

2019年1月28日 星期一

FreeRTOS標準化最後一哩路:POSIX

MCU一直無法標準化的一項原因在於RAM/ROM太小且計算力不足。
所以RTOS才會推展速度不快。
MCU受限最大的資源是RAM。而PC資源上RAM往往是不缺的,不管做什麼事都在RAM上。
MCU卻是RAM的限制,RTOS無法有效用,解譯器也不太能用,其他標準化都不易。
但QSPI XIP解除限制,使得MCU上的RAM增加到可以用的量。可以說快要進入RAM應用的爆發點。

RAM足用的狀況下,第一個使用的管理軟體就是RTOS。
然後只差人工修整PC函式庫去符合MCU的使用環境。

這回Amazon助推了一把,實現的FreeRTOS POSIX界面。這樣人工修整的地方又可以少了很多。
MCU上的RTOS具有POSIX的不是新鮮事。這是廢話,只是發表性文章還是要再重提一次。要錢的RTOS都有提供。
但免費是一種力量。所以免費RTOS上有提供POSIX會直接將MCU推入高生產力程式設計。
再加上一堆Code Generator負責解決底層驅動問題。MCU程式生產力開始變成一種工程性設計,跳開以前的藝術性設計。

工程性設計:模組化,工具化,拼裝。都是為了可以快速生產而產生的。但要會用,自然要會它的SOP。不像藝術性程式設計,是個人化舞台。工程性設計是可以打群戰,更可以做到不同裝置不同人寫及驗證。然後組合後還可以正常運行。
MCU一直是單兵作戰的市場,但現在情況有變。RTOS及POSIX未來將變成高生產力的標準工具。心有餘力的工程師還是早早做準備。我知道很多人才從組合語言的坑中爬出來重新適應C,但再下來是RTOS及軟體工程這個大坑。

2019年1月10日 星期四

STM32 QSPI Flash XIP對MCU開發之影響:架構部分

QSPI Flash帶來了什麼:
MCU除了工業控制外,大部分對於價格是敏感的。消費性產品只能用1美金以下的MCU,一般應用在3美金,工控也無法超過10美金。
QSPI Flash容量32Mb=4MB報價為0.3美金,除了消費性產品,對成本所造成的壓力還可以接受。一但使用上手,預估會有爆發性成長。
最重要的功能是XIP( Execute in place )中文叫在地執行,就是QSPI Flash全顆內容可以直接映射到MCU記憶體空間上,還可以執行程式。程式空間等於大幅增加,可以容納的程式更多。
新的MCU則是加大RAM的容量,相同價格下RAM容量也增加數倍。

架構規劃:
這個部分主要是評估使用架構在限定的硬體條件下是否可以完成韌體規格。
以往因為程式區不大,常常都不會安裝RTOS。
除了RTOS對很多工程師來說是一個不太確定的核心(遇到問題無法解決)。
另外是怕空間不足。像是省下EEPROM而使用internal Flash做參數存放區,而利用掉。
但以QSPI Flash的空間來說,已經沒有限定使用的理由。唯一的理由只剩下工程師自己了。
以STM32來說,STM32CubeMX(驅動程式產生器)可以很方便的就將FreeRTOS引入使用,完全不用理會如何安裝RTOS。
以正規的RTOS來說,開一個工作元(Task)都會消耗RAM,但FreeRTOS有另一種方法(=Coroutine)可以做到類Task又只需很少的RAM。
就算是只有10KB的RAM來說,要Run FreeRTOS也不是難事。
為何使用QSPI Flash RTOS會變得重要,主因是程式變多了。以往寫程式到一定程度,程式空間滿了,老闆就不會再要求新加功能。
現在這個理由消失,以前寫個128KB就可以阻止老闆的野心,現在要寫到4MB看來很難了。
要填滿4MB並非不可能,但不是一個人做,是數個人一起做。不同人同時寫一個MCU,若不用RTOS,是整合不起來的。
再來還有一個限制RAM。不過RAM的限制會有其他方案來擴張。
QSPI Flash使MCU對記憶體限制少了。相對軟體規格增加,對軟體管理功能也要一併提升,好的方法就是引用RTOS。

多模組整合:
程式空間加大,一定會引用一堆Open Source函式庫,有些還是從PC來的,它是有OS的環境。在MCU上RTOS的行為和PC OS相似,要引用也是需要RTOS。
再來是模組之間的格式必然不同,小型軟體介面就是為了膠合不同模組而來的。寫得好,還可以分給不同裝置來使用。
個人就有將Xmodem整理起來,可以用在不同的通信上(UART, SPI等)做為PC資料傳輸用。
只用一套程式,應用於不同裝置上,對軟體穩定性是一種考驗,但相對弄好就很穩定。

RAM超載的處理:
QSPI Flash容量雖大,相對RAM就小很多,RAM變成限定資源。
RAM是有可能因為工作量增加而產生超載。這是需要處理的,必須在架構一開始就對不同的工作想好方法,後補都是很危險的事。
處理方法只有二種:資料丟棄,或是部分工作放棄。
資料丟棄只要決定好放棄是新的還是舊的,只要不要損壞工作就好。
部分工作放棄比較難做。要決定部分程式不執行。有RTOS則又簡單得多,優先權設定可以解決這個問題。
另外多利用區域變數或是動態記憶體的方式也是解決的方法。

ROM表格及Hook的應用:
因為ROM大很多,有些設定資料其實變動有限,直接轉成固定值表格(資料結構陣列),再用Hook(=pointer)指向正在作用的資料內容。
這一類的程式會增加很多,因為ROM不用完,就好像是老闆失職,只好用這種方式吃掉ROM。
用得好,還可以一口氣將相同機台,不同客戶設定或是程式整合進來。

Ram內執行函式不再用:
以往在寫入Flash更新時,要將Flash寫入函式複製到RAM上再執行。現在改成由剩下的64KB internal flash來執行。
剩下的internal flash除了取代RAM function外,也是User Boot Loader的使用區域。QSPI Flash完全存放應用程式。

小型直譯器:
另類除錯方法,在系統存活時做測試用。用來補償RTOS存在時無法做單步除錯動作。但做單元測試很好用。
個人很看好這個應用,做得好時,可以動態新增使用者程式,在不用全機升級的狀況下做小功能新增。
以往直譯器對MCU來說很吃資源,現在則可以有效使用。



但目前QSPI Flash XIP也有缺點,就是Compiler支援不足。舊版本無法將程式配置在QSPI Flash上。又要做Compiler升級才行。

2019年1月7日 星期一

程式設計的層次

是我太敏感?
教程式,但一直覺得少了什麼。
外型,使用上都對,但就是少了一點點。

就像廚師學徒,拿到對的菜料,做出來的菜顏色也對,用看的看不出問題,但就是少了一點點佐料,整個味道就是出不來。

然後我提出程式設計層次,是個人學習不同方法所得的,以C為例
1. 程式語言控制
   基本語法的使用,主要在程式可以執行出想要的結果。
   換成不同語言,就會重來。像從組合語言轉成C,很多人重建程式語言控制不如預期,會退回去。

2. 資料結構
   程式不只處理單次資料,不斷的有資料會進來。於是要學會多種不同型式的資料處理。
   然後就會將資料打包,以方便程式可以做批次處理。也就是處理一整包的資料。若不這樣做,程式會很散亂。
   大一點的程式也會出現管理問題。
   圖型處理很考驗這個等級。

3. 結構化程式設計
   資料結構化了之後,發現程式也可以。同時認知程式其實是以資料處理為主。程式設計開始有架構性。也開始有簡單的程式模型行為:資料流,控制流。在控制流上的數值,可以改變程式執行流程。一般人會利用switch case等結構做為主體。

4. 函式指標
   因為結構化程式設計對於規格改變會有較大的程式調整,就是改switch case的內容。但不可能每次都可以小調整。運用函式指標可以得到更大的靈活性。控制流以函式指標做切換,大幅簡化程式架構。使得修改及管理變得很方便。

5. 物件化資料結構
   將函式指標和資料結構合起來管理的方法。軟體規格開始工程化。C只能做到這個地步。
   作業系統會寫,就算是這個層級畢業了。因為已可以動態新增工作。

6. 物件導向程式設計
   變成程式架構設計,物件可以在需要時才生成,沒有用時消減掉。需要語言支援。但理論仍可以套用到C及MCU設計上。架構設計個人一直卡很久,直到學了電腦語言設計才知道如何使用。
   原來可以利用程式新創另一個執行模型,一般就是創造一個新的語言。一個語言有自己的心中思想,有些部分想到靈活化,有些部分想要簡化(中間步驟要自動化)。

最後二階必須要學會作業系統設計及電腦程式語言設計才算是畢業。

2018年12月21日 星期五

如何在Flash ROM上實現直譯語言4: MCU需求修改

原先的LbForth是在DOS-Box上執行,在RAM上執行且記憶體空間完全獨立。
有數個功能要修改:
1 . 記憶體從矩陣改成指標,這樣才能做MCU內的配置。包括生成字典的地方才可以控制。
2 . 記憶體空間管理,因為寫回的記憶體若是Flash區,要轉去Flash燒寫函式去執行。其他讀寫一樣。
3 . 屬性標記修改,因為NOR Flash清空時是0xFF,一般RAM清空是0,且Flash只能單向設定(1轉0),所以內容要反過來,判定程式也要反過來。

實作時前二項修改很容易。
再來是屬性,它有二個flag在用,各佔一個bit,剩下的bit則是數值,標示名字字串長度,用於尋找字。
一個flag是immediate,它是編譯模式下特權標記,標記設定後的字在編譯模式下是執行,而非媥譯,用來形成控制結構用的。
一個flag是hide,它是將此字標記為廢字,不執行也不會進查找。這個設計很奇怪的和Flash寫入程序很合。因為編譯時沒有做全文章分析,有可能會出現程式中有錯,但寫了一大堆的字進入Flash內,但它不完全,所以不可以執行及查找,故需要這個flag去標記。用在Flash上面可以先留下1(設定),在新字確定完成時再回來清除(設成0)。
又剛好STM32L系列及STM32F系列其Flash動作相反。故要修改成可以設定反相又可以運作的程式。

改完後放入MCU,不會動。因為Flash Erase是有規則的,可以Erase大塊,不能Erase單元,但Write可以寫入一個單元。變成又要加入Flash邊界檢知,在字典長到下一個sector時,發動Erase。
然後,還是不行。發現Flash不能只改一個bit,這個和個人認知有出入。測試一下動作,發現對Flash寫入單元可以做的只有二個動作: 寫入資料,寫入0(全清)。
這下頭大了,屬性欄位要改,若是要可以用,immediate及hide要分出來不能和字串長度放一起。
這下動到字典管理了。要符合,變成用資料的值來做為flag應用。變成Erase後的值是hide,若是沒改,新字就是廢字。若要是有用字就要寫入值(非清除),若是為immediate設定,則再加寫0(只能加寫成全清)。

改完後,還有一些Flash上小問題,再以程式解決。然後總算看到去執行字典生成的高階字編譯。又出問題了。
高階字的空值預設是0,但Nor-Flash不是,所以要去改高階指令。這下又要去理解Forth編譯的細節,硬著頭皮上了。
改完後,真的弄清楚了整個Forth語言系統。
總算在STM32F系列上執行了。不過事情沒有完,移去STM32L系列又掛掉。因為它的Flash除了是0寫成0xFF外,又不能亂寫有ECC在,二次寫入是不行的。看來只能改用在QSPI Flash上看可不可以。

如何在Flash ROM上實現直譯語言3: Forth系統分析

LBForth和一般Forth不同,因為它不用從CPU指令來建造,所以沒有基本指令再堆積成高階功能的問題。
因為由C建造,所以它只要專心應付語言實現問題。這使得系統簡單不少。

所以只要看幾個大的函式,弄清其功能,就可以知道如何動作。
但在解析前,有一個必須解決的問題,它的字典資料結構要先弄清楚。
因為這個是Forth運行最重要的結構。

字典的主要內容:
1.字名(函式名): 輸入的文字代表
2.內容(執行欄): op code或是指標,op code是基本執行功能。高階字以指標表代,遇到指標會跳去對應的記憶體內容再解析,直到執行op code。
3 .結構串接: 以link-list串起來
4. 屬性及標記,後面用到時再分析
實際排列:有固定長度的放在前面,所以link-list為第一個word,第二個是屬性,和名字共用32個byte(佔4個word),接下來是執行欄,長度不定。

字典在程式碼內是看不到的,因為它是在執行才生成,這個動作有利於Flash的寫入,也是可以利用未用的程式Flash的原因。個人覺得這個設計解決MCU上可以動態增加函式的方法。

再來是Forth的執行結構,它和CPU設計有相關,所以很像硬體的方式。
主要有二個堆疊,一個是資料堆,所以資料及參數全部放在此運算。
另外是一個返回堆,主要是呼叫返回堆疊及一些控制結構變數也放在內。
二個堆疊各有一個管理指標暫存器。
另外在執行上,有一個指令指標暫存器(IP)用來標記目前執行位址。

使用二個堆疊原因:
資料處理全部在資料堆疊上,故使用者要去做堆疊內容管理,這個在高階電腦語言是沒有的。因為此動作沒有執行效果,但可以限定RAM的使用只在資料堆疊上。這也是為何Forth使用RAM很少就可以運作。
MCU一向RAM就是不多,其他語言都有RAM需求問題,若是RAM大,MCU就不用寫得辛苦了。

實際上執行,有分成直譯模式及編譯模式。
平時在直譯模式下,輸入一個字串結束(空白字元出現),就去字典查找這個字,有找到,就依執行欄內容再進一步查找或是執行。
若是直譯失敗,再來是進行數字解析,因為這個字串有可能是數字字串,解析成功,就放入資料堆。
若再次直譯失敗,就沒法了,就執行錯誤處理(顯示輸入錯誤)。
有多字輸入下,會一個一個去執行,直到沒有新的輸入。
但有個直譯指令是不一樣的,它會進入編譯模式。
編譯模式下一樣有找字和轉換數字字串的動作,但再下去的動作不同,它不執行而是寫入Flash,生成新的字進入字典內。
在編譯模式下,一樣找字,找到字就將其執行欄位址寫入新字的內容,然後找下一個字。遇到數字時有點不一樣,會先寫入一個lit指令碼再寫入資料值。執行到lit指令碼會將下一欄的內容吐回資料堆疊。這樣就完成固定值的編譯。

了解Forth的運作後,才能做下一步的修改。