亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? sch51.c

?? 嵌入式 時間觸發的嵌入式系統內核程序
?? C
字號:
/*------------------------------------------------------------------*-

   SCH51.C (v1.00) 

  ------------------------------------------------------------------

   *** THESE ARE THE CORE SCHEDULER FUNCTIONS ***
   --- These functions may be used with all 8051 devices ---

   *** SCH_MAX_TASKS *must* be set by the user ***
   --- see "Sch51.H" ---

   *** Includes (optional) power-saving mode ***
   --- You must ensure that the power-down mode is adapted ---
   --- to match your chosen device (or disabled altogether) ---


   COPYRIGHT
   ---------

   This code is from the book:

   PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS by Michael J. Pont 
   [Pearson Education, 2001; ISBN: 0-201-33138-1].

   This code is copyright (c) 2001 by Michael J. Pont.
 
   See book for copyright details and other information.

-*------------------------------------------------------------------*/

#include "Main.h"
#include "Port.h"

#include "Sch51.h"

// ------ Public variable definitions ------------------------------

// The array of tasks
sTask SCH_tasks_G[SCH_MAX_TASKS];

// Used to display the error code
// See Main.H for details of error codes
// See Port.H for details of the error port
tByte Error_code_G = 0;

// ------ Private function prototypes ------------------------------

static void SCH_Go_To_Sleep(void);

// ------ Private variables ----------------------------------------

// Keeps track of time since last error was recorded (see below)
static tWord Error_tick_count_G;

// The code of the last error (reset after ~1 minute)
static tByte Last_error_code_G;


/*------------------------------------------------------------------*-

  SCH_Dispatch_Tasks()

  This is the 'dispatcher' function.  When a task (function)
  is due to run, SCH_Dispatch_Tasks() will run it.
  This function must be called (repeatedly) from the main loop.

-*------------------------------------------------------------------*/
void SCH_Dispatch_Tasks(void) 
   {
   tByte Index;

   // Dispatches (runs) the next task (if one is ready)
   for (Index = 0; Index < SCH_MAX_TASKS; Index++)
      {
      if (SCH_tasks_G[Index].RunMe > 0) 
         {
         (*SCH_tasks_G[Index].pTask)();  // Run the task

         SCH_tasks_G[Index].RunMe -= 1;   // Reset / reduce RunMe flag

         // Periodic tasks will automatically run again
         // - if this is a 'one shot' task, remove it from the array
         if (SCH_tasks_G[Index].Period == 0)
            {
            SCH_Delete_Task(Index);
            }
         }
      }

   // Report system status
   SCH_Report_Status();  

   // The scheduler enters idle mode at this point 
   SCH_Go_To_Sleep();          
   }

/*------------------------------------------------------------------*-

  SCH_Add_Task()

  Causes a task (function) to be executed at regular intervals 
  or after a user-defined delay

  Fn_P   - The name of the function which is to be scheduled.
           NOTE: All scheduled functions must be 'void, void' -
           that is, they must take no parameters, and have 
           a void return type. 
                   
  DELAY  - The interval (TICKS) before the task is first executed

  PERIOD - If 'PERIOD' is 0, the function is only called once,
           at the time determined by 'DELAY'.  If PERIOD is non-zero,
           then the function is called repeatedly at an interval
           determined by the value of PERIOD (see below for examples
           which should help clarify this).


  RETURN VALUE:  

  Returns the position in the task array at which the task has been 
  added.  If the return value is SCH_MAX_TASKS then the task could 
  not be added to the array (there was insufficient space).  If the
  return value is < SCH_MAX_TASKS, then the task was added 
  successfully.  

  Note: this return value may be required, if a task is
  to be subsequently deleted - see SCH_Delete_Task().

  EXAMPLES:

  Task_ID = SCH_Add_Task(Do_X,1000,0);
  Causes the function Do_X() to be executed once after 1000 sch ticks.            

  Task_ID = SCH_Add_Task(Do_X,0,1000);
  Causes the function Do_X() to be executed regularly, every 1000 sch ticks.            

  Task_ID = SCH_Add_Task(Do_X,300,1000);
  Causes the function Do_X() to be executed regularly, every 1000 ticks.
  Task will be first executed at T = 300 ticks, then 1300, 2300, etc.            
 
-*------------------------------------------------------------------*/
tByte SCH_Add_Task(void (code * pFunction)(), 
                   const tWord DELAY, 
                   const tWord PERIOD)    
   {
   tByte Index = 0;
   
   // First find a gap in the array (if there is one) //注意在這里 MAIN()運行了SCH_Delete_Task(const tByte TASK_INDEX) 
   //就把所有的任務	的函數指針SCH_tasks_G[Index].pTask清零了,所以如果沒有添加的任務,SCH_tasks_G[Index].pTask == 0
   while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
      {
      Index++;
      } 
   
   // Have we reached the end of the list?   
   if (Index == SCH_MAX_TASKS)
      {
      // Task list is full
      //
      // Set the global error variable
      Error_code_G = ERROR_SCH_TOO_MANY_TASKS;

      // Also return an error code
      return SCH_MAX_TASKS;  
      }
      
   // If we're here, there is a space in the task array
   SCH_tasks_G[Index].pTask  = pFunction;
     
   SCH_tasks_G[Index].Delay  = DELAY;
   SCH_tasks_G[Index].Period = PERIOD;

   SCH_tasks_G[Index].RunMe  = 0;

   return Index; // return position of task (to allow later deletion)
   }

/*------------------------------------------------------------------*-

  SCH_Delete_Task()

  Removes a task from the scheduler.  Note that this does
  *not* delete the associated function from memory: 
  it simply means that it is no longer called by the scheduler. 
 
  TASK_INDEX - The task index.  Provided by SCH_Add_Task(). 

  RETURN VALUE:  RETURN_ERROR or RETURN_NORMAL

-*------------------------------------------------------------------*/
bit SCH_Delete_Task(const tByte TASK_INDEX) 
   {
   bit Return_code;

   if (SCH_tasks_G[TASK_INDEX].pTask == 0)
      {
      // No task at this location...
      //
      // Set the global error variable
      Error_code_G = ERROR_SCH_CANNOT_DELETE_TASK;

      // ...also return an error code
      Return_code = RETURN_ERROR;
      }
   else
      {
      Return_code = RETURN_NORMAL;
      }      
   
   SCH_tasks_G[TASK_INDEX].pTask   = 0x0000;
   SCH_tasks_G[TASK_INDEX].Delay   = 0;
   SCH_tasks_G[TASK_INDEX].Period  = 0;

   SCH_tasks_G[TASK_INDEX].RunMe   = 0;

   return Return_code;       // return status
   }


/*------------------------------------------------------------------*-

  SCH_Report_Status()

  Simple function to display error codes.

  This version displays code on a port with attached LEDs:
  adapt, if required, to report errors over serial link, etc.

  Errors are only displayed for a limited period 
  (60000 ticks = 1 minute at 1ms tick interval).
  After this the the error code is reset to 0. 

  This code may be easily adapted to display the last
  error 'for ever': this may be appropriate in your
  application.

  See Chapter 10 for further information.

-*------------------------------------------------------------------*/
void SCH_Report_Status(void)
   {
#ifdef SCH_REPORT_ERRORS
   // ONLY APPLIES IF WE ARE REPORTING ERRORS
   // Check for a new error code
   if (Error_code_G != Last_error_code_G)
      {
      // Negative logic on LEDs assumed
      Error_port = 255 - Error_code_G;
      
      Last_error_code_G = Error_code_G;

      if (Error_code_G != 0)
         {
         Error_tick_count_G = 60000;
         }
      else
         {
         Error_tick_count_G = 0;
         }
      }
   else
      {
      if (Error_tick_count_G != 0)
         {
         if (--Error_tick_count_G == 0)
            {
            Error_code_G = 0; // Reset error code
            }
         }
      }
#endif
   }


/*------------------------------------------------------------------*-

  SCH_Go_To_Sleep()

  This scheduler enters 'idle mode' between clock ticks
  to save power.  The next clock tick will return the processor
  to the normal operating state.

  Note: a slight performance improvement is possible if this
  function is implemented as a macro, or if the code here is simply 
  pasted into the 'dispatch' function.  

  However, by making this a function call, it becomes easier 
  - during development - to assess the performance of the 
  scheduler, using the 'performance analyser' in the Keil 
  hardware simulator. See Chapter 14 for examples for this. 

  *** May wish to disable this if using a watchdog ***

  *** ADAPT AS REQUIRED FOR YOUR HARDWARE ***

-*------------------------------------------------------------------*/
void SCH_Go_To_Sleep()
   {
   PCON |= 0x01;    // Enter idle mode (generic 8051 version)

   // Entering idle mode requires TWO consecutive instructions 
   // on 80c515 / 80c505 - to avoid accidental triggering
   //PCON |= 0x01;    // Enter idle mode (#1)
   //PCON |= 0x20;    // Enter idle mode (#2)
   }

/*------------------------------------------------------------------*-
  ---- END OF FILE -------------------------------------------------
-*------------------------------------------------------------------*/

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
精品少妇一区二区三区日产乱码| 国产精品国产三级国产普通话99| 国产嫩草影院久久久久| 亚洲色欲色欲www| 美女视频黄 久久| 成人精品一区二区三区中文字幕| 欧美日韩激情一区二区三区| 国产欧美日韩在线| 亚洲第一会所有码转帖| 成人激情动漫在线观看| 欧美一级久久久久久久大片| 亚洲乱码精品一二三四区日韩在线| 老司机免费视频一区二区三区| 在线观看日韩精品| 国产精品三级视频| 国产精品自在欧美一区| 欧美日韩一区二区三区在线看| 中文字幕国产精品一区二区| 久久精品国产99久久6| 欧美午夜免费电影| 亚洲另类色综合网站| 99久久伊人网影院| 国产日韩高清在线| 国产美女娇喘av呻吟久久| 日韩一区二区在线看片| 亚洲小少妇裸体bbw| 一本久道中文字幕精品亚洲嫩| 久久无码av三级| 久久99久国产精品黄毛片色诱| 9191久久久久久久久久久| 亚洲精品欧美综合四区| 成人午夜在线视频| 欧美国产综合一区二区| 国产在线精品不卡| 精品99一区二区| 黄一区二区三区| 精品国产凹凸成av人网站| 美日韩一区二区三区| 欧美一区二区播放| 久久爱www久久做| 欧美tickling网站挠脚心| 美女网站视频久久| 久久精品视频在线看| 国产精一品亚洲二区在线视频| 久久综合久久鬼色| 国产不卡视频一区| 国产精品你懂的在线欣赏| 国产一区二区福利视频| 国产欧美一区二区三区鸳鸯浴| 国产成人精品在线看| 国产精品美女久久福利网站| av亚洲精华国产精华精| 亚洲精品国产精品乱码不99| 欧美日韩黄色一区二区| 免费成人av资源网| 欧美国产一区二区在线观看| 色综合天天狠狠| 偷窥国产亚洲免费视频| 2欧美一区二区三区在线观看视频| 国产精品综合av一区二区国产馆| 国产精品视频在线看| 色狠狠综合天天综合综合| 午夜精品成人在线| 日韩精品在线一区| 成人精品免费网站| 亚洲一区国产视频| 日韩欧美在线123| 菠萝蜜视频在线观看一区| 亚洲一区免费视频| 国产午夜亚洲精品午夜鲁丝片| 99国内精品久久| 美女视频一区在线观看| 欧美精彩视频一区二区三区| 色婷婷一区二区| 久久精品国产一区二区三| 国产片一区二区三区| 在线观看网站黄不卡| 韩国午夜理伦三级不卡影院| 亚洲免费av观看| 欧美一区二区国产| 色久优优欧美色久优优| 国产一区二区三区免费| 亚洲一区二区三区美女| 久久久精品黄色| 欧美日韩成人一区二区| 国产99久久久精品| 免费看日韩a级影片| 国产精品久久久久久久裸模| 91精品国产一区二区三区蜜臀| 国产a久久麻豆| 久久99精品国产91久久来源| 亚洲激情在线播放| 久久精品免视看| 欧美一区二区免费视频| 91麻豆swag| 国产成人免费视频网站高清观看视频| 亚洲午夜精品网| 亚洲日本丝袜连裤袜办公室| 久久久久国产精品厨房| 日韩欧美三级在线| 欧美日韩成人在线| 在线这里只有精品| 91论坛在线播放| 成人国产精品免费观看动漫| 精品亚洲国产成人av制服丝袜| 亚洲va欧美va国产va天堂影院| 亚洲一区在线观看免费| 中文字幕欧美一| 国产午夜精品一区二区三区视频| 精品国产免费一区二区三区四区| 91国产福利在线| 91视频.com| av一区二区不卡| 99热这里都是精品| 国产在线视频一区二区三区| 香蕉影视欧美成人| 亚洲va欧美va人人爽| 亚洲高清免费一级二级三级| 亚洲专区一二三| 亚洲国产综合在线| 天堂va蜜桃一区二区三区漫画版 | 中文字幕一区二区三区在线不卡| 久久久久久一级片| 中文在线一区二区 | 国产东北露脸精品视频| 久色婷婷小香蕉久久| 久久精品国产久精国产| 久久99久久99精品免视看婷婷 | 亚洲精品一区二区三区影院 | 国产偷v国产偷v亚洲高清| 久久精品视频免费| 国产精品久久久99| 亚洲柠檬福利资源导航| 亚洲一区二区三区视频在线 | 国产一区二区三区免费看| 国产不卡视频在线观看| 91天堂素人约啪| 欧美色图片你懂的| 国产亚洲欧美日韩日本| 国产精品二区一区二区aⅴ污介绍| 成人免费一区二区三区在线观看| 亚洲日本丝袜连裤袜办公室| 亚洲国产精品影院| 久久电影国产免费久久电影 | 日本不卡一区二区三区| 久久成人麻豆午夜电影| av成人老司机| 7777精品伊人久久久大香线蕉| 欧美成人精品二区三区99精品| 久久精品视频一区二区三区| 亚洲男人天堂av| 免费不卡在线视频| 99re视频精品| 正在播放一区二区| 国产精品热久久久久夜色精品三区| 亚洲精品五月天| 久久er99精品| 日本韩国一区二区三区| 欧美哺乳videos| 伊人婷婷欧美激情| 日本在线播放一区二区三区| 国产91在线|亚洲| 欧美女孩性生活视频| 中文字幕 久热精品 视频在线| 亚洲激情图片一区| 国产激情偷乱视频一区二区三区| 91视频免费播放| 久久精品一区二区| 午夜激情一区二区| 波多野结衣中文字幕一区二区三区 | 国产在线播精品第三| 99精品久久免费看蜜臀剧情介绍| 欧美一区二区视频在线观看| ...av二区三区久久精品| 免费在线观看视频一区| 日本道色综合久久| 久久精品欧美一区二区三区不卡| 婷婷开心激情综合| 91在线视频观看| 久久久国际精品| 美女视频黄久久| 欧美日韩高清不卡| 自拍偷拍欧美精品| 处破女av一区二区| 日韩精品一区二区三区在线观看| 夜夜爽夜夜爽精品视频| 成人国产精品免费观看视频| 精品国产sm最大网站| 日韩影院免费视频| 欧美色涩在线第一页| 国产精品乱码人人做人人爱| 国产传媒久久文化传媒| 精品美女在线播放| 免费日韩伦理电影| 日韩欧美视频一区| 久久精品久久精品| 精品美女一区二区| 国内精品伊人久久久久av影院 | 色综合久久综合| 亚洲色图.com|