Thông báo

Collapse
No announcement yet.

hOS - Preemptive Multitasking RTOS by Bui Viet Hoang

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • #16
    cảm ơn anh. em sẽ học dần dần.
    độ này bọn e đang ôn thi cuối kỳ cũng không có nhiều thời gian.
    em sẽ học dần hy vọng anh và các cao nhân thảo luận nhiều giúp chúng em học hỏi thêm.
    cảm ơn anh.

    Comment


    • #17
      Hệ điều hành hOS này cho dù đóng hay mở mã thì vẫn phải có một nguồn lực nhất định để đảm bảo duy trì và phát triển nó trong dài hạn. Vì thế, chúng ta hãy nhìn về giá trị mà nó tạo ra và/ hoặc cả thêm kỳ vọng giá trị tương lai mà nó có thể tạo ra được. Thực tế những sản phẩm mã mở, mạch mở phi lợi nhuận ở VN đạt được thành công là rất hiếm nên cần một sự nỗ lực rất rất lớn của người phát triển. Vì thế, tỷ lệ thành công có lẽ sẽ cao hơn nếu phát triển hOS như một hệ điều hành thương mại có trả tiền không mở mã.

      Với đặc thù của hệ điều hành nhúng thì sự an toàn được đặt ra rất cao. Sự an toàn đó do chính người dùng chịu (hệ mã nguồn mở) hoặc do nhà phát triển chịu trách nhiệm (HĐH có trả phí bản quyền hoặc HĐH nguồn mở được thirt-parrty hiệu chỉnh theo yêu cầu).

      Comment


      • #18
        Chào bạn Hoàng, ý tưởng tạo ra RTOS cho VN rất hay, ngoài code demo cho AVR, bạn còn hỗ trợ cho một số CPU khác nữa không. Vì tốc độ AVR còn hạn chế, nếu chạy chương trình da nhiệm thì có lẽ chưa mang ý nghĩa nhiều về mặc hiệu quả. Nếu hOS được phát triển cho một số CPU có tốc độ cao hơn thì sẽ có nhiều tiềm năng trong tương lai hơn. Ủng hộ công việc bạn đang làm, chúc dự án thành công tốt đẹp.

        Comment


        • #19
          Nguyên văn bởi kernelpanic Xem bài viết
          Chào bạn Hoàng, ý tưởng tạo ra RTOS cho VN rất hay, ngoài code demo cho AVR, bạn còn hỗ trợ cho một số CPU khác nữa không. Vì tốc độ AVR còn hạn chế, nếu chạy chương trình da nhiệm thì có lẽ chưa mang ý nghĩa nhiều về mặc hiệu quả. Nếu hOS được phát triển cho một số CPU có tốc độ cao hơn thì sẽ có nhiều tiềm năng trong tương lai hơn. Ủng hộ công việc bạn đang làm, chúc dự án thành công tốt đẹp.
          Hi, cảm ơn bạn đã quan tâm. Hiện tại thì hOS mới hỗ trợ cho AVR và STM8.
          Căn bản là mình muốn mọi người quen với cái hOS này thông qua một số dòng MCU khá phổ biến trước đã.
          Mình cũng đang có kế hoạch port nó sang một số dòng CPU khác như PIC và một số dòng ARM. Mình sẽ update nếu có gì mới.

          Comment


          • #20
            Các dịch vụ hệ thống của hOS - Semaphore

            Hi All,

            Như mình nói, vấn đề đa nhiệm chỉ là 1 phần của Hệ điều hành. Để được gọi là tương đối hoàn chỉnh ở 1 mức độ nào đó, RTOS phải cung cấp thêm 1 số tiện ích cơ bản hỗ trợ việc quản lý và khai thác các tài nguyên của hệ thống.
            hOS hiện cung cấp cho chúng ta 3 dịch vụ hệ thống cơ bản nhất:

            1. Semaphore/Mutex: hỗ trợ việc quản lý tranh chấp tài nguyên giữa các tiến trình chạy song song
            2. Timer: hỗ trợ tạo ra các sự kiện theo từng khoảng thời gian với chu kì và chức năng cài đặt được
            3. Queue: hỗ trợ trao đổi thông tin giữa các tiến trình chạy song song


            Hôm nay chúng ta sẽ bắt đầu với Semaphore/Mutex.

            Trước khi đi vào khai thác các dịch vụ này trên hOS, mình sẽ nói một chút về lý thuyết thông qua một ví dụ cụ thể.

            Vấn đề đặt ra: Trong một hệ thống 8 bit, Có 2 tiến trình chạy song song. TaskA đọc giá trị ADC và lưu vào biến toàn cục u_adc 16 bit (2 byte). Và TaskB đọc giá trị u_adc này để hiển thị lên LCD. Khi TaskA đọc được một giá trị ADC mới, chẳng hạn 0090 (hexa), nó sẽ gán giá trị này cho u_adc, khi đó đang có giá trị là 0123 (hexa). Nhưng khi nó vừa gán xong byte thấp của u_adc (thay 23 bằng 90). thì TaskA bị tạm dừng và TaskB được chạy. TaskB khi đó sẽ hiển thị kết quả là 0190 (hexa). Kết quả này sai.

            Hậu quả sẽ còn tệ hơn nếu có thêm 1 TaskC nào đó kích hoạt các thiết bị quân sự dựa vào giá trị u_adc này. Bạn thử tưởng tượng xem sẽ có những hậu quả gì nếu TaskC quản lý một khẩu súng và tự động bắn khi u_adc lớn hơn 0150. Thay vì không bắn (với giá trị 0090 nhỏ hơn 0150) thì nó lại bắn (với giá trị 0190 lớn hơn 0150)

            Minh họa quá trình thay đổi 2 byte của u_adc:

            Thời điểm 1, RTOS chạy TaskA: Giá trị cũ u_adc == 01 50
            Thời điểm 2, RTOS chạy TaskA: Giá trị mới đo được == 00 90
            Thời điểm 3, RTOS chạy TaskA: Cập nhật byte thấp u_adc == 01 90

            Thời điểm 4, RTOS chạy TaskB: Hiển thị lên LCD giá trị u_adc == 01 90
            Thời điểm 5, RTOS chạy TaskC: Kích hoạt thiết bị quân sự với u_adc == 01 90

            Thời điểm 6, RTOS chạy TaskA: Cập nhật byte cao u_adc == 00 90



            Sẽ có người đặt ra câu hỏi đại loại:
            "Tại sao phải dùng RTOS trong trường hợp này?"
            Rõ ràng trong trường hợp này, một hệ thống xử lý thông tin đơn luồng (đơn nhiêm) sẽ hoạt động hiệu quả và nhẹ nhàng hơn. Tuy nhiên, nếu bạn không dùng hệ điều hành mà sử dụng các ngắt thì vấn đề tương tự cũng có thể xảy ra, khi chương trình chính (main) là TaskA, còn TaskB và TaskC chính là các hàm ngắt Timer.

            Vậy, vấn đề chúng ta cần giải quyết là phải có 1 cơ chế nào đó để TaskA làm xong việc gán 2 byte của u_adc trước khi nó bị hệ thống tạm dừng để chạy các task khác.

            Trong các giáo trình về công nghệ thông tin ở Việt Nam, người ta gọi vấn đề này là điều độ tiến trình. Còn các biến như u_adc được gọi là tài nguyên dùng chung hay tài nguyên găng (Critical Resource). Đoạn mã mà các tiến trình cùng có nhu cầu sử dụng biến u_adc kiểu này gọi là đoạn găng hay miền găng (Critical Section).

            Để điều độ tiến trình, các hệ điều hành nói chung phải cung cấp một số kiểu dữ liệu gọi là semaphore hoặc mutex. Semaphore hoặc mutex chính là các biến đếm hoặc cờ báo để các tiến trình biết xem, tại đoạn găng, nó có được sử dụng tài nguyên dùng chung hay không.

            Khi vào đoạn găng, các tiến trình sẽ ứng xử theo cùng một cách thức chuẩn với thứ tự sau:

            Bước 1. Kiểm tra và đánh dấu sự có mặt của mình tại đoạn găng.
            Bước 2. Sử dụng tài nguyên găng
            Bước 3. Xóa sự có mặt của mình ở tài nguyên găng
            Khi lập trình song song trên hOS hay tất cả các hệ điều hành khác, các lập trình viên cần thực hiện đúng thứ tự này.


            Với hOS, mình sẽ lấy một ví dụ khác về cổng truyền thông UART để minh họa trực quan hơn:

            Cả hai tiến trình TaskA và TaskB đều sử dụng cổng UART và hàm printf để truyền các dòng thông tin lên máy tính.
            TaskA truyền dòng chữ "Hello World!" và TaskA truyền dòng chữ "0123456789". Nếu như không có sự điều độ của hệ điều hành. Các dòng chữ rất có thể sẽ bị cắt ra và xen lẫn vào nhau, chẳng hạn "Hell0123o Wor345ld...". Điều tồi tệ hơn sẽ xảy ra nếu các hàm printf không được viết để chạy trong môi trường đa nhiệm (Vấn đề này mình sẽ trình bày ở các bài viết sau)

            Mình sẽ dùng một biến kiểu hosSemphore có tên là SemSerial để điều độ việc các tiến trình sử dụng cổng UART.
            Để sử dụng được các biến Semaphore trong hOS, các bạn cần phải khởi tạo chúng thông qua hàm hosSemInit().
            - Tham số thứ nhất là con trỏ đến biến Semaphore.
            - Tham số thứ hai là số lượng tối đa các tiến trình được phục vụ song song bởi tài nguyên mà nó quản lý.
            - Tham số thứ ba là giá trị khởi tạo, là số lượng các tiến trình đang được phục vụ, thường là 0 khi bắt đầu.

            Ở ví dụ với cổng UART này, số lượng tiến trình được cùng phục vụ tại 1 thời điểm là 1, giá trị khởi tạo là 0.
            Bước 1 được thực hiện bởi hàm hosSemTake().
            Bước 3 được thực hiện bởi hàm hosSemRelease().

            Code:
            ....
            hosSemaphore SemSerial;
            ....
            
            int main()
            {
            	....
            	hosSemInit(&SemSerial, 1, 0);
            	....
            }
            
            void TaskA()
            {
            	while(1)
            	{
            		hosSemTake(&SemSerial); // Bạn thử bỏ đoạn này
            		printf("Hello World!\r\n");
            		hosSemRelease(&SemSerial); // Bạn thử bỏ đoạn này
            	}
            }
            
            
            void TaskB()
            {
            	while(1)
            	{
            		hosSemTake(&SemSerial); // Bạn thử bỏ đoạn này
            		printf("0123456789\r\n");
            		hosSemRelease(&SemSerial); // Bạn thử bỏ đoạn này
            	}
            }
            Các bạn hãy tải về và chạy ví dụ đính kèm. Nếu bạn xóa các hàm hosSemTake() và hosSemRelease() ở TaskA và TaskB rồi dịch lại, bạn sẽ thấy rõ sự cần thiết của semaphore/mutex trong việc điều độ tiến trình.

            Đây là kết quả khi dùng Semaphore:

            0123456789
            0123456789
            0123456789
            Hello World!
            0123456789
            0123456789
            0123456789
            0123456789
            0123456789
            Hello World!
            ....
            Còn đây là khi không dùng Semaphore:

            012345ello World!
            0123456789
            0123456789
            HelloHello World!
            æ01234Hello World!
            æ01234Hello World!
            æ01234Hello World!
            ...

            Bây giờ các bạn đã có khái niệm về semaphore/mutex. Để phân biệt chúng, các ban có thể tìm hiểu thêm các tài liệu khác trên mạng. hOS chỉ cung cấp dịch vụ semaphore vì thực chất mutex chính là semaphore dùng để quản lý tài nguyên găng với khả năng phục vụ tối đa cùng 1 tiến trình tại một thời điểm. Ở ví dụ trên, semaphore không khác gì một mutex.


            (To be Continued...)
            Attached Files
            Last edited by bvhoang; 21-05-2011, 15:07.

            Comment


            • #21
              E trước giờ lạp trình theo kểu logic muốn tìm hiểu rtos nhưng chưa hiểu rõ 1 điểm mong moi nguoi trả lời giúp.

              - Các hàm xử lý Semaphore/Mutex, Queue... trong thời điểm nào trong hệ thống, e chỉ thấy đề cập tơi thời gian xử lý các Task.

              Thân.

              Comment


              • #22
                Chào bạn,

                Thực ra bài viết vừa rồi đề cập rất kĩ đến việc sử dụng Semaphore/Mutex trong hoàn cảnh nào thông qua 2 trường hợp cụ thể. Bạn chịu khó đọc kĩ và tải ví dụ về test để hiểu rõ hơn.

                Comment


                • #23
                  Anh bvhoang cho e hởi: TaskI trong chương trình có ý nghĩa gì, khi không có hoặc có điêu không anh hưởng tới 4 xung xuất ra.

                  Comment


                  • #24
                    Nguyên văn bởi eunix Xem bài viết
                    Anh bvhoang cho e hởi: TaskI trong chương trình có ý nghĩa gì, khi không có hoặc có điêu không anh hưởng tới 4 xung xuất ra.
                    Hi bạn eunix,

                    TaskI ở đây là Idle Task, tức là task chạy ngầm trong hệ thống. Nó chỉ tiếp tục chạy khi không có Task bình thường nào khác đang chạy.
                    Mình phải tạo ra TaskI ở đây vì trong chương trình ví dụ trên, đôi khi mình có cho các task khác ngủ bằng cách gọi hàm hosTaskSleep(). Và để tránh trường hợp CPU không được kiểm soát, mình phải tạo ra task chạy ngầm để kiểm soát CPU đề phòng trường hợp tất cả các task kia đều ngủ.

                    Diễn giải chi tiết về việc tạo Task chạy ngầm:
                    Ở ví dụ trên, TaskI này được khởi tạo bởi hàm hosTaskCreate() với mức độ ưu tiên (priority) thấp nhất (tham số thứ 2 bằng 0). Với mức độ ưu tiên thấp như thế, TaskI chỉ chạy khi mà không có task nào khác sử dụng CPU. Ví dụ, trong trường hợp bạn cho tất cả các task khác ngủ bằng cách gọi hàm hosTaskSleep(), hoặc tất cả các Task đều bị dừng lại bằng hàm hosTaskStop() hoặc hosTaskExit(), thì khi đó TaskI sẽ chạy. Nếu trong TaskI bạn vô tình kích hoạt một task nào đó chạy bằng cách gọi hàm hosTaskCreate() hoặc hosTaskRestart() hoặc hosTaskContinue(), khi đó hOS sẽ lập tức treo TaskI lại, và nhường quyền kiểm soát CPU cho task vừa mới được tạo ra.

                    Như vậy, TaskI không tham gia vào nhiều vào ứng dụng, vì đơn giản nó chẳng làm gì hết. Nhưng lại có ý nghĩa với hệ thống mà trong đó có khả năng, tại một thời điểm nào đó, tất cả các task bình thường khác đều không dùng CPU. Và nhìn chung, khi viết ứng dụng với hOS, bạn cứ nên tạo ra một task chạy ngầm như TaskI ở ví dụ trên.

                    Comment


                    • #25
                      anh hoàng có thể hướng dẫn cách xây dựng các hàm tạo nên hos không ? nếu đây là sản phẩm thương mại thì cho em xin lỗi còn nếu không anh có thể hướng dẫn không ạ?
                      sale of Gobal Automation Solution Company Limited

                      Comment


                      • #26
                        Nguyên văn bởi dangtuandat Xem bài viết
                        anh hoàng có thể hướng dẫn cách xây dựng các hàm tạo nên hos không ? nếu đây là sản phẩm thương mại thì cho em xin lỗi còn nếu không anh có thể hướng dẫn không ạ?
                        Bạn ạ,

                        Tôi muốn nói với bạn một điều. Phát triển một RTOS là một việc khó! Vì đây là việc thiết kế ra một nền tảng để người khác sử dụng. Với suy nghĩ này, nếu muốn làm RTOS, trước tiên bạn phải có tinh thần tự tìm tòi, tự nghiên cứu, phải có đam mê và kiên trì trong một khoảng thời gian rất dài.

                        Bản thân việc hướng dẫn người khác hiểu và sử dụng được một RTOS đã khó và mất rất nhiều thời gian rồi. Việc hướng dẫn người khác tự viết ra một RTOS cho riêng họ lại là một việc quá xa xôi, và phụ thuộc vào khả năng và thái độ của cả người truyền đạt và người tiếp nhận kiến thức đó. Tôi xin phép không làm việc đó ở đây.

                        Theo mình hiểu 1 cách thô thiển thì có 3 mức độ hiểu biết về RTOS, và nó quyết định cách đặt câu hỏi của bạn:
                        1. Không biết gì về RTOS
                        2. Biết sử dụng RTOS
                        3. Biết tự phát triển RTOS

                        Bạn có thể cho mình biết bạn đang đứng ở đâu không?
                        Last edited by bvhoang; 02-08-2011, 12:17.

                        Comment


                        • #27
                          Anh bvhoang có thể port hos cho pic up lên cho mọi người sử dụng được không? E cũng đang cần cho pic, công cụ cho pic thì e có nhiều còn AVR thì e không có.

                          Thân.

                          Comment


                          • #28
                            Nguyên văn bởi bvhoang Xem bài viết
                            Bạn ạ,

                            Tôi muốn nói với bạn một điều. Phát triển một RTOS là một việc khó! Vì đây là việc thiết kế ra một nền tảng để người khác sử dụng. Với suy nghĩ này, nếu muốn làm RTOS, trước tiên bạn phải có tinh thần tự tìm tòi, tự nghiên cứu, phải có đam mê và kiên trì trong một khoảng thời gian rất dài.

                            Bản thân việc hướng dẫn người khác hiểu và sử dụng được một RTOS đã khó và mất rất nhiều thời gian rồi. Việc hướng dẫn người khác tự viết ra một RTOS cho riêng họ lại là một việc quá xa xôi, và phụ thuộc vào khả năng và thái độ của cả người truyền đạt và người tiếp nhận kiến thức đó. Tôi xin phép không làm việc đó ở đây.

                            Theo mình hiểu 1 cách thô thiển thì có 3 mức độ hiểu biết về RTOS, và nó quyết định cách đặt câu hỏi của bạn:
                            1. Không biết gì về RTOS
                            2. Biết sử dụng RTOS
                            3. Biết tự phát triển RTOS

                            Bạn có thể cho mình biết bạn đang đứng ở đâu không?
                            em mới chỉ có một số kiến thức cơ bản về RTOS, đã từng nghiên cứu viết code để xây dựng một RTOS chạy hai tác vụ song song trong 8051 nhưng thất bại.
                            sale of Gobal Automation Solution Company Limited

                            Comment


                            • #29
                              Chao bạn,

                              Mình muốn học hỏi về hOS này trên STM8, bạn có project mẫu nào cho mình xin để tìm hiểu.

                              tks bạn

                              Comment


                              • #30
                                Cám ơn Bùi Việt Hoàng rất nhiều. Thời gian tới mình sẽ port lại để thử với PIC18 xem sao. Cho mình hỏi điều này nhé, để áp dụng được hOS này thì yêu cầu cấu hình tối thiểu với MCU như thế nào? Giả sử bây giờ mình chạy với PIC18 chế độ tối đa 40MHz tức là 10MIPS, thời gian đáp ứng nhanh nhất có thể của 1 task hay một sự kiện là bao nhiêu? có thể tính được đặc tính này không? Tuy nói là Realtime nhưng ở mức độ nào, các dòng chip 8bit với tốc độ thấp không thể đáp ứng Realtime cao được, nhưng cỡ 50ms trở lại thì liệu có thể đạt được ở 10MIPS không? Mình rất thích thú điều này bởi nếu áp dụng được thì với những ứng dụng đơn giản và không yêu cầu quá cao về Realtime thì đây là một giải pháp rất hay để thay đổi cách triển khai firmware cho một ứng dụng, tiết kiệm khối thời gian đấy.

                                Comment

                                Về tác giả

                                Collapse

                                bvhoang Tìm hiểu thêm về bvhoang

                                Bài viết mới nhất

                                Collapse

                                Đang tải...
                                X