|
楼主 |
发表于 2012-4-21 10:44:37
|
显示全部楼层
本帖最后由 Gorgon_Meducer 于 2012-4-21 11:06 编辑
为了丰富例子,增加可读性,证明这个software framework不是离开了调度器就不能活了,
特此增加一个不使用调度器实现同样功能的例子——当然是使用传统状态机结构。
特别说明
调度器是通过在顶层app_cfg.h中的配置宏来控制的
- //! \name configure safe task service
- //! @{
- #define TASK_SCHEDULER DISABLED
- #define SAFE_TASK_CALL_STACK ENABLED
- #define SAFE_TASK_QUEUE_POOL_SIZE (1u) //!< task queue pool size
- #define SAFE_TASK_POOL_SIZE (3u) //!< task pool size
- #define TASK_EVENT DISABLED //!< enable task event system
- #define TASK_EVENT_POOL_SIZE (4u) //!< event pool size
- #define TASK_EVENT_EMBEDDED_SCANNER ENABLED //!< scan events in scheduler
- //! @}
复制代码 当TASK_SCHEDULER被设置为除ENABLED以外的任何值,就会关闭调度器,编译时不会生成任何
调度器相关的代码。特别说明下,SAFE_TASK_POOL_SIZE直接决定了调度器开启的时候,允许
同时处于活跃状态的状态机数目(不是状态机状态的数目,也不是状态机的数目,而是同时处于
活跃状态的状态机数目)
- /***************************************************************************
- * Copyright(C)2009-2012 by Gorgon Meducer<Embedded_zhuoran@hotmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2 of the *
- * License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
- /*============================ INCLUDES ======================================*/
- #include ".\app_cfg.h"
- #include ".\es_framework\platform.h"
- /*============================ MACROS ========================================*/
- /*============================ MACROFIED FUNCTIONS ===========================*/
- //! \brief macro for sending byte to serial port in none-block style
- #define SERIAL_OUT(__BYTE) usart_serial_out_byte(&USART[0],(__BYTE))
- //! \brief macro for receiving byte from serial port in none-block style
- #define SERIAL_IN(__ADDR) usart_serial_in_byte(&USART[0],(__ADDR))
- /*============================ TYPES =========================================*/
- /*============================ GLOBAL VARIABLES ==============================*/
- /*============================ LOCAL VARIABLES ===============================*/
- /*============================ PROTOTYPES ====================================*/
- static bool app_init(void);
- static bool task_ping_pang(void);
- static bool task_hello_world(void);
- /*============================ IMPLEMENTATION ================================*/
- /*! \note initialize system
- * \param none
- * \retval true system initialization succeeded.
- * \retval false system initialization failed
- */
- static bool system_init( void )
- {
- bool bResult = true;
- /*! initialize platform */
- bResult &= platform_init();
- /*! add your application initialization here */
- bResult &= app_init();
- return bResult;
- }
- #if TASK_SCHEDULER == ENABLED
- /*! \note system idle task
- *! \param none
- *! \return none
- */
- static void idle_task( void )
- {
- #ifdef ON_BEFORE_SLEEP_EVENT
- ON_BEFORE_SLEEP_EVENT
- #endif
- //! try to enter a max allowed sleep mode
- try_to_sleep();
-
- #ifdef ON_AFTER_SLEEP_EVENT
- ON_AFTER_SLEEP_EVENT
- #endif
-
- }
- #endif
- /*! \note main function
- * \param none
- * \return none
- */
- #if __IS_COMPILER_IAR__
- __task void main( void )
- #elif __IS_COMPILER_GCC__
- int main( void )
- #endif
- {
- /* initialize whole system */
- system_init();
- while(true) { //!< super loop
- #ifdef INSERT_SUPPER_LOOP
- INSERT_SUPPER_LOOP
- #endif
- #if TASK_SCHEDULER == ENABLED
- if (!scheduler()) { //!< scheduler
- idle_task(); //!< idle state
- }
- #endif
- task_ping_pang(); //!< task 1
- task_hello_world(); //!< task 2
- }
- #if __IS_COMPILER_GCC__
- return 0;
- #endif
- }
- static bool s_bBusyFlag = false;
- /******************************************************************************
- * DEMO APPLICATION: Ping Pang Demo *
- ******************************************************************************/
- /*
- static uint8_t s_chByte;
- STATIC_FSM(Ping_Pang_Demo)
- PRIVATE STATE(Ping_Pang_Demo_Start);
- PRIVATE STATE(Ping_Pang_Demo_Wait_Busy_Flag);
- PRIVATE STATE(Ping_Pang_Demo_Output);
- END_FSM
- PRIVATE STATE(Ping_Pang_Demo_Start) BEGIN
- //! receive new byte
- if (SERIAL_IN(&s_chByte)) {
- //! got one, then tranfer to output state;
- TRANSFER_TO_STATE(Ping_Pang_Demo_Wait_Busy_Flag);
- //! exit current state;
- EXIT_STATE;
- }
- //! keep current state
- REFLEXIVE_STATE;
- END
- PRIVATE STATE(Ping_Pang_Demo_Wait_Busy_Flag) BEGIN
- if (!s_bBusyFlag) {
- //! free, then set the flag
- s_bBusyFlag = true;
-
- TRANSFER_TO_STATE(Ping_Pang_Demo_Output);
- //! exit current state;
- EXIT_STATE;
- }
- //! keep current state
- REFLEXIVE_STATE;
- END
- PRIVATE STATE(Ping_Pang_Demo_Output) BEGIN
- //! output received byte
- if (SERIAL_OUT(s_chByte)) {
- //! success, then transfer to start state
- TRANSFER_TO_STATE(Ping_Pang_Demo_Start);
- //! clear busy flag
- s_bBusyFlag = false;
- //! exit current state
- EXIT_STATE;
- }
- //! keep current state;
- REFLEXIVE_STATE;
- END
- */
- #define PING_PANG_START 0
- #define PING_PANG_WAIT_BUSY_FLAG 1
- #define PING_PANG_OUTPUT 2
- static bool task_ping_pang(void)
- {
- static uint8_t s_chState = 0;
- static uint8_t s_chByte;
- switch(s_chState) {
- case PING_PANG_START:
- if (SERIAL_IN(&s_chByte)) {
- s_chState = PING_PANG_WAIT_BUSY_FLAG;
- }
- break;
- case PING_PANG_WAIT_BUSY_FLAG:
- if (!s_bBusyFlag) {
- s_bBusyFlag = true;
- s_chState = PING_PANG_OUTPUT;
- }
- break;
- case PING_PANG_OUTPUT:
- if (SERIAL_OUT(s_chByte)) {
- s_bBusyFlag = false;
- s_chState = PING_PANG_START;
- }
- break;
-
- }
- return true;
- }
- /******************************************************************************
- * DEMO APPLICATION: Hello world *
- ******************************************************************************/
- /*
- DEF_ARG(ArgStream)
- uint8_t *pchSrc;
- uint8_t chLength;
- END_DEF_ARG
- //! \brief sub state machine
- STATIC_FSM(Stream_Output)
- PRIVATE STATE(Stream_Out_Start);
- PRIVATE STATE(Stream_Out_Byte_Output);
- END_FSM
- PRIVATE STATE(Stream_Out_Start) BEGIN
- //! check argument
- if (!CHECK_ARG(ArgStream)) {
- //! illegal, just exit sub state machine
- EXIT_STATE;
- }
- if ( (NULL == REF_ARG(ArgStream).pchSrc)
- || (0 == REF_ARG(ArgStream).chLength)) {
- //! complete
-
- EXIT_STATE;
- }
-
-
- TRANSFER_TO_STATE(Stream_Out_Byte_Output);
- EXIT_STATE;
- END
- PRIVATE STATE(Stream_Out_Byte_Output) BEGIN
-
- uint8_t chByte;
- //! check argument
- if (!CHECK_ARG(ArgStream)) {
- //! illegal, just exit sub state machine
- EXIT_STATE;
- }
- chByte = *(REF_ARG(ArgStream).pchSrc);
- //! output received byte
- if (SERIAL_OUT(chByte)) {
- REF_ARG(ArgStream).pchSrc++;
- REF_ARG(ArgStream).chLength--;
- //! success, then transfer to start state
- TRANSFER_TO_STATE(Stream_Out_Start);
- //! exit current state
- EXIT_STATE;
- }
- //! keep current state;
- REFLEXIVE_STATE;
- END
- */
- #define STREAM_OUT_START 0
- #define STREAM_OUT_BYTE_OUTPUT 1
- static bool stream_out(uint8_t *pchStream, uint8_t chLength)
- {
- static uint8_t s_chState = 0;
- static uint8_t s_chLength;
- static uint8_t *s_pchSrc;
- if (STREAM_OUT_START == s_chState) {
- s_pchSrc = pchStream;
- s_chLength = chLength;
- s_chState = STREAM_OUT_BYTE_OUTPUT;
- } else if (STREAM_OUT_BYTE_OUTPUT == s_chState) {
- if ((0 == s_chLength) || (NULL == s_pchSrc)) {
- s_chState = STREAM_OUT_START;
- return false;
- }
- if (SERIAL_OUT(*s_pchSrc)) {
- s_pchSrc++;
- s_chLength--;
- }
- }
- return true;
- }
- //----------------------------------------------------------
- //! \brief demo task
- /*
- FSM(Hello_World,1)
- PRIVATE STATE(HW_Start);
- PRIVATE STATE(HW_Init_Delay);
- PRIVATE STATE(HW_Delay);
- END_FSM
- uint32_t s_hwDelay = 0;
- ARG(ArgStream) s_DemoArg = {0};
- SAFE_TASK_ARG s_Arg = {0};
- PRIVATE STATE(HW_Start) BEGIN
- if (!s_bBusyFlag) {
- //! free
- s_bBusyFlag = true; //!< set busy flag
- //! initialize argument
- s_DemoArg.pchSrc = (uint8_t *)"Hello world!\r\n";
- s_DemoArg.chLength = sizeof( "Hello world!\r\n");
- s_Arg.pArg = &s_DemoArg;
- s_Arg.hwLength = sizeof(s_DemoArg);
- //! success, then transfer to start state
- CALL_FSM_EX(
- REF_STATE(Stream_Out_Start), &s_Arg, //!< sub-statemanchine
- REF_STATE(HW_Init_Delay), pArg); //!< return statemachine
- //! exit current state
- EXIT_STATE;
- }
- REFLEXIVE_STATE;
- END
- PRIVATE STATE(HW_Init_Delay) BEGIN
-
- //! release busy flag
- s_bBusyFlag = false;
- s_hwDelay = 20000;
- TRANSFER_TO_STATE(HW_Delay);
- EXIT_STATE;
- END
- PRIVATE STATE(HW_Delay) BEGIN
- if (s_hwDelay) {
- s_hwDelay --;
- } else {
- TRANSFER_TO_STATE(HW_Start);
- EXIT_STATE;
- }
- REFLEXIVE_STATE;
- END
- */
- #define STREAM_OUT(__STR) stream_out((__STR),sizeof(__STR))
- #define HW_START 0
- #define HW_PRINT_STR 1
- #define HW_DELAY 2
- static bool task_hello_world(void)
- {
- static uint8_t s_tState = 0;
- static uint32_t s_wDelay;
- switch (s_tState) {
- case HW_START:
- if (!s_bBusyFlag) {
- s_bBusyFlag = true;
- s_tState = HW_PRINT_STR;
- }
- break;
- case HW_PRINT_STR:
- if (!STREAM_OUT("Hello world!\r\n")) {
- //! return false means complete
- s_bBusyFlag = false;
- s_wDelay = 20000;
- s_tState = HW_DELAY;
- }
- break;
- case HW_DELAY:
- if (s_wDelay) {
- s_wDelay--;
- } else {
- s_tState = HW_START;
- }
- break;
-
- }
- return true;
- }
- static bool app_init(void)
- {
- bool bResult = true;
- //bResult &= NEW_STATIC_FSM( Ping_Pang_Demo, REF_STATE(Ping_Pang_Demo_Start));
- //bResult &= NEW_FSM( Hello_World, REF_STATE(HW_Start));
- return bResult;
- }
- /* EOF */
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|