2017年3月29日 星期三

事件驅動多工系統設計

規劃很久了,直到另一個功能出現才有動力去寫。寫出來程式不大。
系統只有二個檔案,測試一個,模擬一個。
event_drive.h 如下
extern void OS_ENTER_CRITICAL(void);
extern void OS_EXIT_CRITICAL(void);
extern void SimInit(void);

#define INIT_DEVICE() SimInit()
#define DIS_INTR() OS_ENTER_CRITICAL()
#define ENA_INTR() OS_EXIT_CRITICAL()

#define MAX_EVENT 8
#define MAX_TIMER 32

extern void execute(void);
extern void setTimeout(void (*p_func)(void), unsigned int tick);
extern void ISR_setTimeout(void (*p_func)(void), unsigned int tick);
extern void timerAction(void);

使用者可以設定同時執行的事件數目及要管理的延時事件數

event_drive.c 如下
#include "event_drive.h"

unsigned int eventInCnt = 0;
unsigned int eventOutCnt = 0;
void (*eventFunc[MAX_EVENT])(void);
void (*delayFunc[MAX_TIMER])(void);
unsigned int delayCnt[MAX_TIMER];

void execute(void)
{
    // FIFO function array
    if (eventInCnt != eventOutCnt)
    {
        eventFunc[eventOutCnt % MAX_EVENT]();
        eventOutCnt++;
    }
}

void setTimeout(void (*p_func)(void), unsigned int tick)
{
    int i;

    if (!tick)
        tick = 1;
    DIS_INTR();
    for (i = 0; i < MAX_TIMER; i++)
    {
        if (delayCnt[i] == 0)
            break;
    }
    delayFunc[i] = p_func;
    delayCnt[i] = tick;
    ENA_INTR();
}

void ISR_setTimeout(void (*p_func)(void), unsigned int tick)
{
    int i;

    if (!tick)
        tick = 1;
    for (i = 0; i < MAX_TIMER; i++)
    {
        if (delayCnt[i] == 0)
            break;
    }
    delayFunc[i] = p_func;
    delayCnt[i] = tick;
}

void timerAction(void)
{
    int i;
    for (i = 0; i < MAX_TIMER; i++)
    {
        if (delayCnt[i])
        {
            delayCnt[i]--;
            if (!delayCnt[i])
            {
                eventFunc[eventInCnt % MAX_EVENT] = delayFunc[i];
                eventInCnt++;
            }
        }
    }
}

只有4個函式:
execute()是執行的地方,放在main()中的while(1)內就可以了。
timerAction()放在時間中斷內,用來管理延遲執行的函式何時要回復執行。
setTimeout()是使用者註冊一個延遲執行的函式。
ISR_setTimeout()是使用者用於中斷內的函式。

Sim.c windows下的模擬界面
#include <windows.h>
#include <winbase.h>

#include "event_drive.h"

HANDLE OSSemaphore;
DWORD WINAPI OSTickW32(LPVOID lpParameter);
HANDLE OSTick32Handle;

void SimInit(void)
{
    DWORD dwID;

    OSSemaphore = CreateSemaphore(NULL11NULL);
    OSTick32Handle = CreateThread(NULL0, OSTickW32, 00, &dwID);
    SetPriorityClass(OSTick32Handle, THREAD_PRIORITY_HIGHEST);
    SetThreadPriority(OSTick32Handle, THREAD_PRIORITY_HIGHEST);
}

DWORD WINAPI OSTickW32(LPVOID lpParameter)
{
    while (1)
    {
        timerAction();
        Sleep(1);
    }
    return 0;
}

void OS_SLEEP(unsigned int count)
{
    Sleep(count);
}

void OS_INIT_CRITICAL(void)
{
    return;
}

void OS_ENTER_CRITICAL(void)
{
    WaitForSingleObject(OSSemaphore, INFINITE);
}

void OS_EXIT_CRITICAL(void)
{
    ReleaseSemaphore(OSSemaphore, 1NULL);
}

測試用程式


#include <stdio.h>
#include "event_drive.h"

void print_dot(void);
void print_0(void);

void main()
{
    INIT_DEVICE();
    setTimeout(print_dot, 1);
    setTimeout(print_0, 1);
    while (1)
    {
        execute();
    }
}

void print_dot(void)
{
    printf(".");
    setTimeout(print_dot, 7);
}

void print_0(void)
{
    printf("0");
    setTimeout(print_0, 10);
}

2017年2月8日 星期三

超級預測 心得

人類判定事情,多半不客觀。
只依自己的習慣、所知,就快速給出答案。

在研究大數據及追尋科學源頭過程中,不斷的發現人並不太使用數據做判定。
這也是為何大數據只要數據量大,找出來的就是比人下的判定要來得好。

得手"超級預測"一書,更是說明一件事,近代可能發生的事,可以由前期環境資料預測出來。
但人類仍不習慣使用客觀方式做分析。尤其是和自己相關的事物上。
大前研一的書也提出類似觀點。客觀分析才是正確的分析心態。

反問,是建立客觀的方法。
心態抽離也是方法。
這二個動作都不像是一般人會用的。

所以超級預測不是給出方法,而是給出心態上的建立。
也就是沒有正確的心態,就不會有正確的結果。
而大數據,它沒有心態上的問題,往往結果是正確的。反而人不見得會相信。

其實在一開始看這本書,心態上就會決定是否會讀完。
只想找出如何去學到"超級預測"的方法,結果是找不到,沒讀完就會放棄。
而我只看了半本,就發覺不對勁,書本不是沒有內容,而是另有表達。
所以讀此書,還是將心態放空。它不是教科書,讀法是不一樣的。

2017年1月13日 星期五

2016年MCU發展回顧

重回MCU,發現有一大堆新發展。

QSPI正式納入MCU標準:它不是新的介面,但在2016年出現了很多新裝置,使得MCU有很好的擴充性。除了原先的Flash外,今年還加入了FRAM,MRAM,SRAM等裝置。加上可以直接映射到內部空間。使用上變得很方便。

MIPI介面:VR應用下,總算使用了這個介面統一了Camera, TFT, Touch。圖型式人機界面開始統一。

Cordova開發工具成熟:MCU和手機利用此開發工具可以很快打造出可用的原型。相信APP和MCU一併開發會產生更多的應用。

RISC-V開源核心出現:在IOT需求下8051已不勘負荷,以BLE核心為例8051核心的應用就不再有發展,不然就要轉到Cortex-M0+。開源CPU核心就以RISC-V為主了。這個核心出現,只會加速將8051擠出IOT的應用。

2016年12月30日 星期五

Wifi module的戰役

在IOT未流行前,就已在使用了。當時算貴的,大部分在10鎂以上。
也有很多廠商,記得當時用了一家很大的,公司主要在上海,接觸的是台灣分公司。
但在使用上有些問題,也問過問題。不幸的回應不如預期,也來來回回的用mail在除錯。
後來問題無法有效解決,就換另一家的Module,研發在台灣,有問題借出電路,很快的找出問題在那。
於是就用了Wifi Module成功了第一個案子。
過了三年,沒想到IOT紅了,又回來看資料。什麼?ESP8266是那個?一個剩不到3鎂!記得不是開放原碼的,怎麼如今也開放了!
三年內類似功能的Module價格剩不到1/3,還不只一家做,大家都改用開放原始碼的Module。

現在在做BLE應用,看著各廠商的Module資料,又遇到了不開放原始碼的廠商,讓我想到Wifi Module的故事。
生意不是不能做,但真的不能用硬體的方式去思考。
程式碼是重要,但開放標準的元件,去鎖軟體能擋多久?你不開放,一堆其他公司就開放和你搶。
要不然,價格戰,相信市場很快就爛掉,誰也不想見(客戶除外)。
現在是軟體主導時代,應以軟體的角度去看市場。因為硬體廠商真的太多了!

2016年12月21日 星期三

發明?還是發展成功?

看人類科技發展,再加上經濟上的發展。
可以確定科技發明,並不等於發展。
往往發展人會變成發明人,再加上以前文字沒有留下明確記錄。發展人就直接變成發明人。
但發展就和發明不是直接相關了。
以中國4大發明來說,指南針和火藥就給西方人有效的發展。
火藥最為明顯。
其實又和其經濟效益有關。

砲: 石字,在中國發射的都是石頭。
而且和投石器常常混在一起。
火藥一定會是中國人發明,主因是煉丹。
但發展一定在地中海,主因是海戰。

早期砲身極重,只能放在車上移動,用來破城。但投石器也可以破城。
所以只能算是破城器之一。在很多的攻城器中不算特別突出。
傳到歐洲就不同了,大砲在陸地上不算太有用,在海上就不同了。
平射砲可以擊中船的吃水線,造成船底破洞,很容易使船隻失去功能。
一但用在海戰,直接變成殺手級兵器,不易移動及瞄準等缺點在船上也不是大問題。
於是大砲開始進化。從石砲彈變成鐵砲彈,那個時代鐵是高級物資,若非效果有差,怎可能做成消耗品?
大砲改變了船的地位,也開啟了人類放胆去探險的心,於是大航海時代就此展開。

發明又如何?
到後來發展才是重點。火藥改變了西方世界,再回頭改變了東方。回到東方已是另一個不一樣的東西了。

2016年10月18日 星期二

又一次新電腦時代

還記得當兵前的電腦和當兵後是完全不同的時代,也花了很久才追上。沒想到又發現這二年又有變化了。
當兵前的電腦是DOS模式,寫程式算是簡單的,輸出入不多,這個模式到MCU也是一樣。

之後進入圖形化界面時代,顯示卡大更新,作業系統大換。面對視窗程式,真的不好理解。
花了數年才學到一點點概念。圖型化界面是PC的全盛時期。
最新受到智慧手機影響,重新評估電腦技術,發現又進入新時代:網路時代。
網路時代,作業系統不重要,瀏覽器才是重點。或是另一端的伺服器程式才是關鍵。

語言也產生很大的變化,直譯語言總算成為主流。
程式模組共用,程式重點全部轉到應用層。
寫程式有近一半的時間在找最接近需求的元件,然後改成自己的需求。
網路時代,開源很重要,作業系統開源,伺服器軟體開源。這對於上一個階段的軟體公司來說是很大的改變。
因為電腦要使用網路聯合產生服務,變成橫跨硬體。從伺服器,手機,到裝置,跨度很大。中間原本皆使用不同語言,造成統合困難。
所以電腦語言產生統合,如果可以,會統合成單一語言。

結果發現以前所學的視窗程式架構又沒有什麼用了。因為現在改成網頁的方式做圖型界面描述。
單機執行程式也改成遠端支援型程式。
改變太大,才使我重新去判定又是一個新的電腦時代。
一切重頭來,已經浪費不少時間才弄清。還是丟掉以前的觀念,重新學習。

2016年10月3日 星期一

APP開發評估

這個月開始轉換,評估了新軟體生態。真的和以往認知有很大的不同。
PC環境式微,Web開發環境興起。主因還是在手機,因為web形式可以通吃。
主要語言也有轉型,看來JavaScript會是主流已經不用懷疑了。
看來學校教課也只剩下二個語言,不是教C,就是教JavaScript。
所以看看PC上的應用,就變成使用Node.js。
安裝好了Node.js試用,馬上發現我所想的另一個問題,巨量原始碼問題。
本來就有預估會遇到巨量原始碼這件事,因為PC程式一直很少用,所以沒有感覺到。
真的要用,大部分就用google找一下。但在npm下,我發現我的方法實在太原始了。
如何使用巨量原始碼這件事已經變成是新的程式技能,我卻沒有方法。

再來回到APP開發,本來想說用JS有機會弄好,結果不如所想。
Android Studio是不可能避開的,它是不好用。
所以公司又弄了BCB來,這個打開頭更大,它是以win32開發為主,又套上跨平台,複雜度加倍。
我想還是以可以網路找文件的方法為主,只能先回Android Studio。

然後中間先學了JavaScript,本想這個解譯語言應是不難,又錯。
Node.js和想像的不一樣,它是非同步語言,光是這個就可能弄倒一堆人。
非同步語言又是新的要學技術。

APP將軟體生態大改變,軟體和以往我所知的大大的不同了。
變成還要去補中間的段差,這個又變成是要追趕的技術。
因為手機環境至少十年內不會退,也還是只能痛苦吃下去了。