ตัวอย่าง project เพื่อการทำงาน Co-operative multitasking ด้วย State machine ในแบบ simple

Started by AppleIIe, August 22, 2013, 06:16:15 PM

Previous topic - Next topic

firmware.c

Quoteปล. ผมชอบ ARR ของท่านนะครับ มันใช้ง่ายดี แม้มันยังขาดอะไรอยู่บ้าง อย่างไรก็ตาม ผมชอบแบบง่ายๆนี่แหละครับ
ใช่ครับง่ายเพราะทุก task จะ share timing กันหมดแล้ว priority ก็เท่ากันหมดด้วยครับ แถมแต่ละ task มี stack เป็นของตัวเอง เอาไว้ใช้ save context และใช้สำหรับ local variable ของแต่ละ task ในกรณีที่มีการ switch task เกิดขึ้น  ซึ่งผมมองว่ามันคือ multitasking แบบจริงๆ
IAR Embedded Workbench for ARM
AVR-Studio + AVR-GCC
CodeBlocks + MinGw
CodeBlocks + Gtk+

AppleIIe

Quote from: firmware.c on August 24, 2013, 10:21:28 PM
Quoteปล. ผมชอบ ARR ของท่านนะครับ มันใช้ง่ายดี แม้มันยังขาดอะไรอยู่บ้าง อย่างไรก็ตาม ผมชอบแบบง่ายๆนี่แหละครับ
ใช่ครับง่ายเพราะทุก task จะ share timing กันหมดแล้ว priority ก็เท่ากันหมดด้วยครับ แถมแต่ละ task มี stack เป็นของตัวเอง เอาไว้ใช้ save context และใช้สำหรับ local variable ของแต่ละ task ในกรณีที่มีการ switch task เกิดขึ้น  ซึ่งผมมองว่ามันคือ multitasking แบบจริงๆ

เห็นด้วยครับผมก็เห็นเช่นนั้น ARR เป็นตัวอย่างหนึ่งที่ดี แอบไล่การทำงานแล้วชอบครับ เลยแอบมาบอกท่านต่อเลย
เสียดายที่ท่านไม่ได้ปรับปรุงมันต่อไป
ถ้าท่านมีเวลาก็อยากให้แนะนำเรื่องราวของ multitasking บ้างนะครับ วันละนิดวันละหน่อยก็ได้ (โดยไม่รบกวนเกินไป)
เพราะนับวันจะเริ่มมีบทบาท มากขึ้นเรื่อยๆ เลยอยากให้ผู้ชำนาญอย่างท่าน ช่วยพิจารณาเผื่อเป็นประโยชน์ต่อน้องๆ เพื่อนๆ ในอนาคตครับ
ผมเองรู้แค่งูๆปลาๆครับ เล่าได้ไม่เก่งไม่ประติดประต่อนัก ข้อมูลต่างๆ ก็ได้แต่จับโน่นต่อนี่ไม่ค่อยเป็นเรื่องเป็นราวอยากได้คนที่เป็น
และมีประสบการณ์มาให้ข้อมูลมากกว่า แค่ในหลักการก็พอแล้วครับ ไม่ต้องลงรายละเอียดก็ได้ หวังว่าท่านคงเมตตาต่อชาวโลกใบนี้ด้วย  ;)
"Stay Hungry, Stay Foolish"
จงกระหาย และ ทำตัวโง่ให้ตลอดเวลา
"Innovation distinguishes between a leader and a follower."
นวัตกรรมแยกผู้นำกับผู้ตามออกจากกัน

คนฉลาด...ต้องโง่เป็น คนโง่ไม่เป็น...จะไม่มีทางฉลาด

firmware.c

Quote from: AppleIIe on August 25, 2013, 07:15:41 AM
Quote from: firmware.c on August 24, 2013, 10:21:28 PM
Quoteปล. ผมชอบ ARR ของท่านนะครับ มันใช้ง่ายดี แม้มันยังขาดอะไรอยู่บ้าง อย่างไรก็ตาม ผมชอบแบบง่ายๆนี่แหละครับ
ใช่ครับง่ายเพราะทุก task จะ share timing กันหมดแล้ว priority ก็เท่ากันหมดด้วยครับ แถมแต่ละ task มี stack เป็นของตัวเอง เอาไว้ใช้ save context และใช้สำหรับ local variable ของแต่ละ task ในกรณีที่มีการ switch task เกิดขึ้น  ซึ่งผมมองว่ามันคือ multitasking แบบจริงๆ

เห็นด้วยครับผมก็เห็นเช่นนั้น ARR เป็นตัวอย่างหนึ่งที่ดี แอบไล่การทำงานแล้วชอบครับ เลยแอบมาบอกท่านต่อเลย
เสียดายที่ท่านไม่ได้ปรับปรุงมันต่อไป
ถ้าท่านมีเวลาก็อยากให้แนะนำเรื่องราวของ multitasking บ้างนะครับ วันละนิดวันละหน่อยก็ได้ (โดยไม่รบกวนเกินไป)
เพราะนับวันจะเริ่มมีบทบาท มากขึ้นเรื่อยๆ เลยอยากให้ผู้ชำนาญอย่างท่าน ช่วยพิจารณาเผื่อเป็นประโยชน์ต่อน้องๆ เพื่อนๆ ในอนาคตครับ
ผมเองรู้แค่งูๆปลาๆครับ เล่าได้ไม่เก่งไม่ประติดประต่อนัก ข้อมูลต่างๆ ก็ได้แต่จับโน่นต่อนี่ไม่ค่อยเป็นเรื่องเป็นราวอยากได้คนที่เป็น
และมีประสบการณ์มาให้ข้อมูลมากกว่า แค่ในหลักการก็พอแล้วครับ ไม่ต้องลงรายละเอียดก็ได้ หวังว่าท่านคงเมตตาต่อชาวโลกใบนี้ด้วย  ;)
ด้วยความยินดีครับผม
IAR Embedded Workbench for ARM
AVR-Studio + AVR-GCC
CodeBlocks + MinGw
CodeBlocks + Gtk+


AppleIIe

Quote from: firmware.c on August 25, 2013, 09:53:21 AM
Quote from: AppleIIe on August 25, 2013, 07:15:41 AM

เห็นด้วยครับผมก็เห็นเช่นนั้น ARR เป็นตัวอย่างหนึ่งที่ดีแอบไล่การทำงานแล้วชอบครับ เลยแอบมาบอกท่านต่อเลย
เสียดายที่ท่านไม่ได้ปรับปรุงมันต่อไป
ถ้าท่านมีเวลาก็อยากให้แนะนำเรื่องราวของ multitasking บ้างนะครับ วันละนิดวันละหน่อยก็ได้ (โดยไม่รบกวนเกินไป)
เพราะนับวันจะเริ่มมีบทบาท มากขึ้นเรื่อยๆ เลยอยากให้ผู้ชำนาญอย่างท่าน ช่วยพิจารณาเผื่อเป็นประโยชน์ต่อน้องๆ เพื่อนๆ ในอนาคตครับ
ผมเองรู้แค่งูๆปลาๆครับ เล่าได้ไม่เก่งไม่ประติดประต่อนัก ข้อมูลต่างๆ ก็ได้แต่จับโน่นต่อนี่ไม่ค่อยเป็นเรื่องเป็นราวอยากได้คนที่เป็น
และมีประสบการณ์มาให้ข้อมูลมากกว่า แค่ในหลักการก็พอแล้วครับ ไม่ต้องลงรายละเอียดก็ได้ หวังว่าท่านคงเมตตาต่อชาวโลกใบนี้ด้วย  ;)
ด้วยความยินดีครับผม

ท่าาน firmware.c ช่างมีน้ำใจยิ่งนัก ขอบคุณล่วงหน้ามากๆครับ  :)
"Stay Hungry, Stay Foolish"
จงกระหาย และ ทำตัวโง่ให้ตลอดเวลา
"Innovation distinguishes between a leader and a follower."
นวัตกรรมแยกผู้นำกับผู้ตามออกจากกัน

คนฉลาด...ต้องโง่เป็น คนโง่ไม่เป็น...จะไม่มีทางฉลาด

ROM

ได้ลองทดสอบแล้วทำงานได้ดีมากครับ Code แค่นี้ทำให้ ทำไฟกระพริบหลายดวงได้อย่างนี้เลย ดีจัง
แต่จะถามว่าถ้าจะทำให้ LED1 กระพริบ 3 ครั้งสั้นๆ แล้วดับ และวนไปเรื่อยๆ จะแก้ใน co_state_timer_task_led1 ยังไงครับ
ยังมือใหม่หัดคิดครับ  ::)
ท่านใดพอจะทราบขอคำแนะนำด้วยครับ


AppleIIe

Quote from: ROM on August 27, 2013, 11:28:03 AM
ได้ลองทดสอบแล้วทำงานได้ดีมากครับ Code แค่นี้ทำให้ ทำไฟกระพริบหลายดวงได้อย่างนี้เลย ดีจัง
แต่จะถามว่าถ้าจะทำให้ LED1 กระพริบ 3 ครั้งสั้นๆ แล้วดับ และวนไปเรื่อยๆ จะแก้ใน co_state_timer_task_led1 ยังไงครับ
ยังมือใหม่หัดคิดครับ  ::)
ท่านใดพอจะทราบขอคำแนะนำด้วยครับ


ท่าน ROM มีอยู่หลายๆวิธีนะครับ โดยมีข้อดีและัไม่ดี แตกต่างกันไป
แต่้เพื่อให้ง่ายกับการเริ่มต้นแบบนี้ ขอแนะนำเป็นแบบตรงไปตรงมานะครับ
สมมติให้ LED กระพริบสั้นๆ ในช่วง ON 250 ms./OFF 200 ms. และ ดับยาวในเวลา 800 ms.
กำหนดค่าได้ดังนี้ ( กำหนดค่าเวลาที่คำนวณได้จาก T1SEC )

#define     T1_LED_ON       ( T1SEC * 250 / 1000 )
#define     T1_LED_OFF      ( T1SEC * 200 / 1000 )
#define     T2_LED             ( T1SEC * 800 / 1000 )

โดยกำหนด state ที่จะใช้ขึ้นมาจาก enum ได้ดังนี้ (ใช้จำนวน 7 state) ท่านลองค่อยๆวิเคราะห์ดูครับได้ตามนี้ไหม ( รวม state เริ่มต้น ด้วยครับ ) ก็จะได้

    enum {  LED_STATE_BEGIN, LED_STATE_1, LED_STATE_2 ,
            LED_STATE_3 , LED_STATE_4 , LED_STATE_5 , LED_STATE_6 };

โดย LED_STATE_6 จะเป็น state สุดท้ายที่ดับ โดยใช้เวลา T1_LED_OFF รวมกับ T2_LED
ดังนั้น สรุปจะได้ Code ส่วนนี้จะเป็นได้ประมาณดังนี้ครับ


...
/*************************************************************************
                           Co-state task LED1
*************************************************************************/
#define T1_LED_ON       ( T1SEC * 250 / 1000 )
#define T1_LED_OFF      ( T1SEC * 200 / 1000 )
#define T2_LED          ( T1SEC * 800 / 1000 )

void co_state_timer_task_led1(void)
{
    enum {  LED_STATE_BEGIN, LED_STATE_1, LED_STATE_2 ,
            LED_STATE_3 , LED_STATE_4 , LED_STATE_5 , LED_STATE_6 };

    co_state_timer {
    case LED_STATE_BEGIN:
        // initial co-state at here
        state_jump(LED_STATE_1);        // jump to next state
        return;
    case LED_STATE_1:
        ON_LED1;
        state_delay(T1_LED_ON, LED_STATE_2);    // delay by T1_LED_ON
        return;
    case LED_STATE_2:
        OFF_LED1;
        state_delay(T1_LED_OFF, LED_STATE_3);   // delay by T1_LED_OFF
        return;
    case LED_STATE_3:
        ON_LED1;
        state_delay(T1_LED_ON, LED_STATE_4);    // delay by T1_LED_ON
        return;
    case LED_STATE_4:
        OFF_LED1;
        state_delay(T1_LED_OFF, LED_STATE_5);   // delay by T1_LED_OFF
        return;
    case LED_STATE_5:
        ON_LED1;
        state_delay(T1_LED_ON, LED_STATE_6);    // delay by T1_LED_ON
        return;
    case LED_STATE_6:
        OFF_LED1;
        state_delay(T1_LED_OFF + T2_LED, LED_STATE_1);   // delay by T1_LED_OFF , T2_LED
        return;
    }
}

#undef  T1_LED_ON
#undef  T1_LED_OFF
#undef  T2_LED

...


หวังว่าท่านคงเข้าใจมากขึ้น ลองค่อยๆพิจารณาดูครับ
ซึ่งวิธีนี้เป็นวิธีแบบตรงไปตรงมา อาจมีข้อเสียคือใช้ state ค่อนข้างมาก หากให้ LED กระพริบมากๆกว่านี้ Code จะมากตามไปด้วย
โดยจะเห็นว่าัี Code ที่ซ้ำๆคือช่วงที่ LED ติดโดย T1_LED_ON และ T1_LED_OFF ครับ
แต่เพื่อเป็น Guideline และง่ายต่อการให้เกิดความเข้าใจ ก็ใชัวิธีแบบนี้ไปก่อน

นอกจากนี้ยังมีวิธีอื่นๆอีกครับ เอาไว้มีโอกาศจะเล่าต่อในภายหลังครับ
"Stay Hungry, Stay Foolish"
จงกระหาย และ ทำตัวโง่ให้ตลอดเวลา
"Innovation distinguishes between a leader and a follower."
นวัตกรรมแยกผู้นำกับผู้ตามออกจากกัน

คนฉลาด...ต้องโง่เป็น คนโง่ไม่เป็น...จะไม่มีทางฉลาด

ROM

ขอบคุณท่าน AppleIIe มากครับ เข้าใจแล้วครับ
เป็นการเขียนโปรแกรมที่ แหวกแนวดีครับ  :D