Atomthreads像眾多操作系統一樣,在沒有任務調度是會調用idle。(by cpuwolf) static void atomIdleThread (uint32_t param) { /* Compiler warning */ param = param; /* Loop forever */ while (1) { /** \todo Provide user idle hooks*/ } } atomthreads中atomIdleThread()是以線程的形式存在,也就是最低優先級線程。作者默認沒有填寫這個函數。 uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size) { uint8_t status; /* Initialise data */ curr_tcb = NULL; tcbReadyQ = NULL; atomOSStarted = FALSE; /* Create the idle thread */ status = atomThreadCreate(&idle_tcb, IDLE_THREAD_PRIORITY, atomIdleThread, 0, idle_thread_stack_top, idle_thread_stack_size); /* Return status */ return (status); } 針對STM8我們最自然想到的是在其中加一個wfi,STM8進入wfi模式幾乎不會影響任何外設的運行。以STM8S105K4為例,其進入該模式的典型電流是1.8mA。這個電流,用一節2000mA手機供電,理論上也最多能堅持46天,才一個月多點。這個記錄太差了。 STM8還有一個HALT模式,這是該芯片的最低功耗模式,電流是uA級別。但是該模式有諸多限制,進入該模式系統幾乎所有的clock都停止,你的timer,adc,uart等等全部停止,除了AWU。 atomthreads如果你在idle直接進入HALT,因為基本只有外部中斷可以喚醒退出這個模式,當系統醒來了,請你想想,你的系統心跳還準么?你的應用線程如果使用了定時器,本來希望1秒鐘后調用某個CALLBACK,結果HALT睡了5分鐘,那還是定時器API本身參數的意義么? 對datasheet熟悉的讀者可能,可能立刻想到了AWU,似乎可以解決這個問題。在idle進入HALT前,把還能睡的時間填入AWU,這樣系統就可以在制定的時間被喚醒。粗略的一看,還以為問題解決了。 暫時不談AWU的時間不是任意值都可以接受的,是一個非常不準確的喚醒時鐘。 舉個其他例子,如果idle進入HALT前,系統還可以睡20分鐘,我覺的一個設計優良的低功耗系統,應用層讓系統有睡20分鐘的可能性是很起碼的。不幸的是,在5分鐘的時候,一個外部中斷進來了,系統很自然退出HALT。我想問你,從系統的角度看,系統之前睡了多久。不要告訴玩我是5分鐘,大哥,那是我假設的,我問得是,從系統的角度。睡了多久?AWU這個唯一在運行的模塊,上面是沒有時間讓你讀的,你完全無法得知剛才睡了多久。 其實上面的這個理念不是我創造的,在linux中早就有了,它叫variable tick timer,什么意思?通常我們的心跳時鐘,是有規律的觸發中斷,比如10ms一次,這導致系統最多能安靜10ms,想多睡會兒?沒門!10ms后中斷就來了。這種設計對低功耗是不利的。后來就有大牛,引入了variable tick timer,這里tick timer就是我們上面一直說的心跳時鐘。variable就是可變的羅!表面意思就是我們的心臟可以走走停停,這樣想已經不符合人類的自然規律,所以也確實不能再叫heart beattimer。當系統醒的時候,是有規律的跳動,當系統睡眠的時候, timer就停跳。其實就是上面想實現的東西。 |