2017年7月19日 星期三

資訊社會的衝擊

工業社會早已是習以為常,但目前社會已進入資訊社會。
於是看到有許多人出現適應不良的狀況。
老實說,個人也是。一但覺得適應不良,一般人是直接退回去。

資訊社會最大的特徵是資訊量大到人腦無法承受。在智慧手機出現後,這已是無人可以避免的問題。
所以就出現有人,寧願用功能手機也不想換成智慧型手機。但在2017年7月1日後,這個可能性也沒了。因為2G退場,功能手機門號失效。
不願換掉2G門號,那就換成3G吧!不幸的是3G在2018年底退場,二者只差1年半,時間一到,功能手機就是失效。

這種資訊爆炸的社會,是對的?是正常的? 我也很存疑。資訊化的另一個產物=自動化,同時也在侵蝕社會經濟。
之所以會有這種感覺,是因為從工業社會的角度看過去。
工業社會的特性是經濟總是正成長,產品一代出過一代,人只要努力沒有賺不到錢。工業社會是以人為生產主體,人才是經濟重心。
那資訊社會呢?則是以資訊為重心,人是被分析的對象。當自動化再次進化成人工智慧時,人變成被管理的對象!
這種變化,我想大部分人都無法接受。
但這就是人類社會,當高智能種族出現,低智能的人種變成被管理。只是這回是機器爬上那個位置。

人類出現高智能不是沒有前例,第一次是語言出現,人類和動物不同了。動物被人類管理。
第二次出現是文字,沒有文字,人類無法管理國家。有文字的國家常常去打沒有文字的種族。
文字的出現科技才得以進展,不是嗎?
文字為何要發明出來?因為人腦超載了。當土地大了,要管理的事變多了,光用人腦已無法記憶。要使用符號來提醒,於是文字發明。
文字是人腦記憶的擴充。

那這次,又是怎麼回事,資訊社會再次使人腦超載。這次超載的不只是量的超載,更是處理上的超載。
所有可以電子化的資料都可以被存下來,資訊量爆炸的時代,就算有文字,人腦也無法負荷,因為連消化都來不及。
資訊社會的一大特徵是資訊產出速度無與倫比。在這種狀況下人要如何適應?
第一個方法是,增加資料輸入及消化的頻寬。也就是讀書看得比別人快,學習速度比別人快,應是可以追上。
這個方法筆者早在20年前就在使用了。但現在也只是勝過大部分人類,還是比不上電腦,在20年前沒有想到電腦會勝過人腦。
第二個方法是,改變知識的吸收層級。
這個理論的重點是:不是所有資料都是重要的,資料量大,重覆性大的可以被壓縮成現象。
資料可以被整理,如果換成另一種角度看。就像是數學中的FFT,在時域上看不清的,在頻域上就很明顯。
人工智慧及大數據相關資料查了,會發現和機率統計很有關係。機率統計也是一種大範圍的行為探討,這也是資訊社會中極為重要的常識。
不過有正確的機率統計概念的人,我想還不是很多。
再來是處理能力的增強,用人腦算計,我看很難。反過來用,用電腦去算出機率統計的結果,由人腦來理解,這是一項可行的方法。
在電腦的操作上,最實用化的科技全都是電玩發展出來的。筆者老早看到這個趨勢,很早就在追電玩理論。
現在電玩理論也相當發達:
電玩心理學:人如何看資訊,資訊對心理影響
電玩UI :資訊展現方法,如何規劃使用者需求資訊
電玩人工智能: 就是現在的人工智能
電玩伺服器: 伺服器即時反應技術,多重伺服器同步
電玩行銷:互動式網路行銷,客服機器人
電腦去完成大量資料的操作,現在已叫做大數據。
這些都是人可以對資訊操作的方法。只可惜,電玩被很多家長視為不良玩具。其實不玩電玩,才是擋住人往下個世紀的門票。

再來是經濟問題,工業社會的經濟方式在資訊社會是行不通的,所以會造成經濟退化。實際上忽略了資訊社會的新經濟。
手遊經濟目前已超越PC加上遊戲主機,電腦硬體一向是近年來經濟龍頭,被超越了代表什麼意思。
傳統行銷在手遊上是行不通的,現在經濟已不是學校理論可以去探討的,一定要換個方法才行。
但經濟真的退化?還是只是新經濟來不及接手的暫態。
行銷是不是要換個方法來看手機經濟要如何操作。

這次的衝擊是全面性的。以人為主的概念不再是絕對。
電腦不是人腦可以拼的,還是想辦法去利用電腦,提高人腦的對資訊的認知高度才是適應時代的方法。

2017年5月24日 星期三

VS Code使用IAR設定

VS Code C/C++插件升級後,變成無法去找出原先定義的地方。
後來發現是VS Code沒有IAR設定生成的問題,就試著手工填看看,結果有成功。
開入STM32專案目錄後,開C檔會有一堆紅標。
點任一個紅標字,左側會出現一個小燈泡,去點它,會開啟c_cpp_properties.json檔
先借用win32的除錯器來用。
原文:
"name": "Win32",
"includePath": [
"${workspaceRoot}",
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10586.0/um",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10586.0/ucrt",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10586.0/shared",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10586.0/winrt"
],
"defines": [
"_DEBUG",
"UNICODE"
],
改成:
"name": "Win32",
"includePath": [
"${workspaceRoot}/",
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10586.0/um",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10586.0/ucrt",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10586.0/shared",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10586.0/winrt",
"${workspaceRoot}/BLE_CNTR/Inc",
"${workspaceRoot}/BLE_CNTR/Drivers/STM32L0xx_HAL_Driver/Inc",
"${workspaceRoot}/BLE_CNTR/Drivers/STM32L0xx_HAL_Driver/Inc/Legacy",
"${workspaceRoot}/BLE_CNTR/Middlewares/Third_Party/FreeRTOS/Source/portable/IAR/ARM_CM0",
"${workspaceRoot}/BLE_CNTR/Drivers/CMSIS/Device/ST/STM32L0xx/Include/",
"${workspaceRoot}/BLE_CNTR/Middlewares/Third_Party/FreeRTOS/Source/include",
"${workspaceRoot}/BLE_CNTR/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS",
"${workspaceRoot}/BLE_CNTR/Drivers/CMSIS/Include"
],
"defines": [
"_DEBUG",
"UNICODE",
"USE_HAL_DRIVER",
"STM32L051xx"
],
就可以用了。

2017年4月21日 星期五

FreeRTOS Coroutine的限制

MCU因RAM不足,去動Coroutine的方法,但不太順。有switch case存在時就會掛。
後來改為if else就好了。然後找到這篇;
http://www.freertos.org/co-routine-limitations.html
難怪很少人用,有坑。
用photothreads則沒有看到這個問題。
因為Coroutine也是由switch case做出來的,才會有此問題。
結論是,不要在switch case內使用crDELAY,就可以。那只好改成一長串的if else。

記下來,以免又採到坑。

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的應用。