欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

C Programming for Embedded System

系統 2483 0

Introduction

Now for embedded system development people are using operating system to add more features and at the same time reduce the development time of a complex system. This article gives a simple & understandable overview of scheduling technique of embedded system programming for beginners and intermediate programmers. I am considering “C” as the programming language and an application running in a dedicated hardware/device without operating system. The binary output ( *.bin file) can be directly running from the device after Power on. In this case, the time scheduling is an important part of system development. We should ensure that the right task should execute at the right time.

What is Embedded System?

An embedded system is some combination of computer hardware and software, either fixed in capability or programmable - it is specifically designed for a particular kind of application device. Or in short we can say, an embedded system is a special-purpose computer system designed to perform one or a few dedicated functions.

All embedded systems need not be a real time system. Real Time systems are those in which timeliness is as important as the correctness of the outputs. Performance estimation and reduction are crucial in real time system. By definition, we can say a real time system is a system that must satisfy explicit (bounded) response time constraints or risk severe consequences, including failure.

Embedded system plays an important part in our daily lives. Most of the people around the globe are highly dependent on different types of gadgets like mobile phones, iPods and many more. The embedded systems used in industrial machines, automobiles, medical equipment, airplanes, and vending machines have to be real time.

I thought of sharing my experience in Embedded systems. This is my first ever article on CodeProject, so I am expecting your valuable feedback and suggestions for betterment.

Background

People are using operating system (RTOS) for complex devices to make it more flexible, add more features and minimize the development time. But it will increase the cost of the device for a small application. So for small application firmware development without operating system is very much popular.

Time scheduling is an important aspect of real-time system. Real time software are executed in response to external events. This event may be periodic, in which case an appropriate scheduling of events and related task is required to guarantee performance. The scheduling strategy also depends on scheduling facilities that the chosen RTOS offers. This article emphasis on the event based technique when there was no operating system running in the device.

Scheduling

Two kinds of scheduling techniques are used in Real-Time system:

  1. Static Scheduling
  2. Dynamic Scheduling

Static Scheduling

This involves analyzing the tasks statically and determining their timing properties. This timing property can be used to create a fixed scheduling table, according to which tasks will be dispatched for execution at run time. Thus the order of execution of the task is fixed, and it is assumed that their execution time is also fixed.

Round-Robin Scheduling

Round Robin scheduling by Time Slicing is one of the ways to achieve static scheduling. Round robin is one of the simplest and most widely used scheduling algorithms; in which a small unit of time known as time slice is defined. Schedulers go around the queue of ready-to-run processes and allocate a time slice to each such process.

Scheduling with Priority

Priority indicates the urgency or importance assigned to a task. There are two approaches of scheduling based on priority based execution – when the processor is idle, the ready task with the highest priority is chosen for execution; once chosen, the task is run to completion.

Pre-Emptive Scheduling

Preemptive Priority based execution is when the processor is idle, the ready task with highest priority is chosen for execution; at any time, the execution of a task can be preempted if a task of higher priority becomes ready. Thus, at all times, the processor is idle or executing the ready task with the highest priority.

Dynamic Scheduling

Another kind of scheduling mechanism is known as Dynamic Scheduling – In this case, a real-time program requires a sequence of decisions to be taken during execution of the assignment of resource to transactions. Here each decision must be taken without prior knowledge of the needs of future tasks. Dynamic scheduling is not in the scope of this article, so I am not discussing it in detail here. Perhaps we can discuss it in another article.

Code Snippet

Let us take a example of a Master-Slave communication system. Master system is connected to n number of slave systems over serial port (RS 485 network) in multi-drop architecture. Figure 1 shows the typical configuration of this system. Here only one system can talk at a time and others are in listen mode. The Master controls the communication.

Main Routine

Collapse | Copy Code
    
      
        void
      
    
     main(
    
      
        void
      
    
    )
{
    
    
      
        
          /*
        
        
           Initialise all register of processor and the peripheral devices */
        
      
    
    
    InitMain();

    
    
      
        
          /*
        
        
           Register the event handler */
        
      
    
    
    RegisterTask(MainEventHandler);

    RegisterTask(CheckDataIntegrity);
    ..............

    
    
      
        
          /*
        
        
           Turn on all the leds for 1 sec as lamp test */
        
      
    
    
    TurnOnLed(LED, 
    
      
        1000
      
    
    );

    
    
      
        
          /*
        
        
           Call the application event manager - no return */
        
      
    
    
    EventManager();
}
  

In the above case, the RegisterTast() and EventManager() are two important functions. For any application, we have number of tasks and a function represents the entry point of a task, like ' CheckDataIntegrity ' . When a device receives a complete data packet, it goes for data checking. RegisterTask() function creates a link-list of function pointers where each node represents a single task. Here I have passed the function pointer MainEventHandler or CheckDataIntegrity as an argument.

Main.h should have the following lines:

Collapse | Copy Code
    
      
        
          /*
        
        
           Application event handler function pointer */
        
      
    
    
      
        typedef
      
    
    
      
        void
      
    
     (*tEventHandler)(
    
      
        unsigned
      
    
    
      
        short
      
    
     *);


    
      
        
          /*
        
        
           Link-list definition */
        
      
    
    
      
        typedef
      
    
    
      
        struct
      
    
     TaskRecord
{
    tEventHandler EventHandler;
    
    
      
        struct
      
    
     TaskRecord *pNext;
}tTaskRecord;


    
      
        static
      
    
     tTaskRecord *mpTaskList = NULL;
  

Here mpTaskList represents a link-list of function pointers. Considering each node of link list as a entry point of a task, this will execute one by one in EventManager() function. Below is the definition of RegisterTask() function which adds the function pointer into the link-list.

Collapse | Copy Code
    
      
        void
      
    
     RegisterTask(tEventHandler EventHandlerFunc)
{
    tTaskRecord *pNewTask;

    
    
      
        
          /*
        
        
           Create a new task record */
        
      
    
    
    pNewTask = malloc(
    
      
        sizeof
      
    
    (tTaskRecord));
    
    
      
        if
      
    
    (pNewTask != NULL)
    {
        
    
      
        
          /*
        
        
           Assign the event handler function to the task */
        
      
    
    
        pNewTask-
    
      
        >
      
    
    EventHandler = EventHandlerFunc;
        pNewTask-
    
      
        >
      
    
    pNext = NULL;

        
    
      
        if
      
    
    (mpTaskList == NULL)
        {
            
    
      
        
          /*
        
        
           Store the address of the first task in the task list */
        
      
    
    
            mpTaskList = pNewTask;
        }
        
    
      
        else
      
    
    
        {
            
    
      
        
          /*
        
        
           Move to the last task in the list */
        
      
    
    
            mpActiveTask = mpTaskList;
            
    
      
        while
      
    
    (mpActiveTask-
    
      
        >
      
    
    pNext != NULL)
            {
                mpActiveTask = mpActiveTask-
    
      
        >
      
    
    pNext;
            }

            
    
      
        
          /*
        
        
           Add the new task to the end of the list */
        
      
    
    
            mpActiveTask-
    
      
        >
      
    
    pNext = pNewTask;
        }
    }
}
  

For this type of application, after initialization there should be an infinite loop for continuous execution. The function EventManager() at the end of the main which is nothing but a infinite loop always checks for active tasks or events. If any event occurs, then it passes that event flag as an argument of the function which is already added into the mpTaskList . So EventManager() function calls MainEventHandler() function with eventID as an argument. MainEventHandler will check the eventId and do the necessary action or execute the corresponding code. Here the event should be unique for each event-handler function, i.e. two event-handler functions should not check the same eventID .

Definition of EventManager Function

Collapse | Copy Code
    
      
        void
      
    
     EventManager(
    
      
        void
      
    
    )
{
    
    
      
        unsigned
      
    
    
      
        short
      
    
     AllEvents;
    tTaskRecord pActiveTask

    
    
      
        
          /*
        
        
           No return */
        
      
    
    
      
        while
      
    
    (
    
      
        1
      
    
    )
    {
        
    
      
        
          /*
        
        
           Read application events */
        
      
    
    
        AllEvents = mEventID;

        
    
      
        
          /*
        
        
           Process any application events */
        
      
    
    
        pActiveTask = mpTaskList;
        
    
      
        while
      
    
    ((AllEvents != 
    
      
        0
      
    
    ) && (pActiveTask != NULL))
        {
            
    
      
        if
      
    
    (pActiveTask-
    
      
        >
      
    
    EventHandler != NULL)
            {
                
    
      
        
          /*
        
        
           Call the task's event handler function */
        
      
    
    
                (mpActiveTask-
    
      
        >
      
    
    EventHandler)(&AllEvents);

                
    
      
        
          /*
        
        
           Read application events */
        
      
    
    
                AllEvents = mEventID;
            }

            
    
      
        
          /*
        
        
           Move to the next event handler */
        
      
    
    
            pActiveTask = pActiveTask-
    
      
        >
      
    
    pNext;
        }
    }
}
  

Event can be generated from interrupt service routine or by checking the status of an input pin in polling mode. SerialReceiveISR function generates anevent after receiving the complete packet. Since the variable mEventID is modified in the interrupt service routine, it is recommended to disable interrupt while reading.

Collapse | Copy Code
    
      
        #pragma
      
    
     interrupt_level 
    
      
        0
      
    
    
      
        void
      
    
     interrupt IService(
    
      
        void
      
    
    )
{
    
    
      
        
          /*
        
        
           Receive bit is set when a byte is received */
        
      
    
    
      
        if
      
    
    (Receivebit == 
    
      
        1
      
    
    )
    {
        SerialReceiveISR()
    }
    ...........
    
    
      
        
          /*
        
        
           code for other interrupt */
        
      
    
    
}
  

SerialReceiveISR Function

Collapse | Copy Code
    
      
        #pragma
      
    
    
      
        inline
      
    
     SerialReceiveISR

    
      
        void
      
    
     SerialReceiveISR(
    
      
        void
      
    
    )
{    
    
    
      
        static
      
    
    
      
        char
      
    
     RxMsgDataCount;
    
    
    
      
        
          /*
        
        
           If a framing or overrun error occurs then clear the error */
        
      
    
    
      
        if
      
    
    (Error == 
    
      
        1
      
    
    )
    {
        
    
      
        
          /*
        
        
           Indicate a problem was seen */
        
      
    
    
        mEventID = mEventID | ATTENTION_REQ_FLG;
    }
    
    
      
        else
      
    
    
      
        if
      
    
    ( RxMsgCount == DataLength)
    {
        
    
      
        
          /*
        
        
           Packet receive complete */
        
      
    
    
        mEventID = mEventID | DATA_RECEIVE_COMPLETE;
    }
    
    
      
        else
      
    
    
    {
        
    
      
        
          /*
        
        
           Store data in memory */
        
      
    
    
        Store(RxByte);
        RxMsgCount++;
    }
}
  

Here ATTENTION_REQ_FLAG & DATA_RECEIVE_COMPLETE flags are two bits of a Global variable mEventID , which is 16 bits and each bit triggers the corresponding event when set.

Collapse | Copy Code
    
      
        #define
      
    
     ATTENTION_REQ_FLAG  0x0008

    
      
        #define
      
    
     DATA_RECEIVE_COMPLETE  0x0001
  

When the flag is set, the EventManager will call all the registered functions with the eventID as argument.

Collapse | Copy Code
    
      
        void
      
    
     MainEventHandler(
    
      
        unsigned
      
    
    
      
        short
      
    
     *Event)
{
    
    
      
        if
      
    
    (*Event & DATA_RECEIVE_COMPLETE)
    {
        
    
      
        
          /*
        
        
           Do the corresponding action */
        
      
    
    
        .........
        
    
      
        
          /*
        
        
           Reset the flag */
        
      
    
    
        *Event &= ~DATA_RECEIVE_COMPLETE; 
    }
}
  

Now we can change the variable type to increase the number of flags. If you want to generate multiple number of events, then use a structure rather than a single variable.

<!-- Article Text End -->

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

C Programming for Embedded System


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久999| 日韩精品一区二区三区中文字幕 | 最新一级毛片 | 手机日韩看片 | 国产手机在线αⅴ片无码观看 | 亚洲午夜在线 | 久久亚洲精品玖玖玖玖 | 国内精品久久久久久久久久久久 | 亚洲 日本 欧美 中文幕 | 精品国产自在久久 | 激情婷婷小说 | 99re热精品视频 | 看个毛片 | 三级视频在线播放 | 99精品在线观看 | 国产精品成人va在线观看入口 | 亚洲精品国产综合一线久久 | 国内精品久久毛片一区二区 | 91久久青青草原免费 | 色综合久久天天综合绕观看 | 亚洲高清视频一区 | 日韩福利在线 | 男女在线免费视频 | 一区二区在线免费观看 | 亚洲女人天堂 | 欧美激情久久久久久久久 | 成人爽a毛片在线视频网站 婷婷色在线观看 | 亚洲国产精品一区二区第一页 | 99久久久无码国产精品 | 性欧美18一19sex性高清播放 | 欧美片网站免费 | 一级一级毛片看看 | 国产精品国产精品国产专区不卡 | 欧美黑人又粗又长 | 99影视在线视频免费观看 | 亚洲精品在线视频 | 波多野一区二区 | 污在线观看 | 538porm在线看国产亚洲 | 欧洲一区二区 | 日本高清免费网站 |