[Tự Học FreeRTOS] Chapter 1: Task Management (Phần 4)

1.10 Xoá Task (Deleting a Task)

1.10.1 Hàm API vTaskDelete()

Hàm API vTaskDelete() dùng để xóa một task. Hàm này chỉ có thể xài khi INCLUDE_vTaskDelete được đặt bằng 1 trong FreeRTOSConfig.h. Thực tế thì không nên tạo và xóa task liên tục trong lúc chạy, hãy cân nhắc những thiết kế khác như là xài lại các task, nếu bạn thấy phù hợp. Task đã xóa thì sẽ không tồn tại nữa và không thể vô trạng thái Running nữa.

Nếu một task đã tạo xài bộ nhớ cấp phát động (dynamic memory allocation) và sa đó cần tự xóa chính nó, thì Idle task sẽ có trách nhiệm giải phóng bộ nhớ đã cấp phát, như là stack và data structure, để xài cho việc khác. Cho nên ứng dụng không được giành thời gian xử lý của Idle task trong trường hợp này là quan trọng.

Chú ý: Khi một task bị xóa, chỉ có bộ nhớ đã cấp phát cho task bởi chính kernel được giải phóng tự động. Bất kỳ bộ nhớ hay tài nguyên nào đã được cấp phát trong lúc implement task PHẢI được free một cách tường minh nếu không cần xài nữa.

void vTaskDelete( TaskHandle_t xTaskToDelete );
C

Code Block 1.26. Prototype của hàm API vTaskDelete()

Các tham số của vTaskDelete()

  • pxTaskToDelete

Handle của task bị xóa (task chủ thể). Xem tham số pxCreatedTask của hàm API xTaskCreate() để có thông tin về cách lấy handle của task.

Một task có thể xóa chính nó bằng cách truyền NULL thay cho task handle của nó.

Ví dụ 1.9 Xóa task

Đây là một ví dụ rất đơn giản, hành vi của nó như sau.

  1. Task 1 được hàm main() tạo với độ ưu tiên 1. Khi Task 1 chạy, nó tạo Task 2 với độ ưu tiên 2. Task 2 bây giờ là task có độ ưu tiên cao nhất, nên bắt đầu ngay tức thì. Code Block 1.27 là mã nguồn của main(). Code Block 1.28 là mã nguồn của Task 1.
  2. Task 2 không làm gì ngoài tự xóa chính nó. Nó có thể xóa chính nó bằng cách truyền NULL vô hàm API vTaskDelete(). Nhưng vì mục đích mô phỏng, chúng ta sẽ truyền vô task handle của chính nó. Code Block 1.29 là mã nguồn của Task 2.
  3. Khi Task 2 đã bị xóa, Task 1 lại là task có độ ưu tiên cao nhất, nên nó tiếp tục thực thi tại vị trí đã gọi vTaskDelay() để block trong một khoảng thời gian ngắn.
  4. Idle task thực thi trong khi Task 1 đang ở trong trạng thái Blocked và free bộ nhớ đã được cấp phát cho Task 2 mà bây giờ bị xóa.
  5. Khi Task 1 rời khỏi trạng thái Blocked, nó lại trở thành task có độ ưu tiên cao nhất và chiếm quyền (pre-empt) của Idle task. Khi đi vô trạng thái Running, nó sẽ tạo Task 2 một lần nữa, và mọi chuyện lặp lại tiếp diễn.
int main( void )
{
    /* Create the first task at priority 1. */
    xTaskCreate( vTask1, "Task 1", 1000, NULL, 1, NULL );

    /* Start the scheduler so the task starts executing. */
    vTaskStartScheduler();

    /* main() should never reach here as the scheduler has been started. */
    for( ;; )
    {
    }
}
C

Code Block 1.27. Hàm main() trong Ví dụ 1.9

TaskHandle_t xTask2Handle = NULL;

void vTask1( void * pvParameters )
{
    const TickType_t xDelay100ms = pdMS_TO_TICKS( 100UL );

    for( ;; )
    {
        /* Print out the name of this task. */
        vPrintLine( "Task 1 is running" );

        /*
        * Create task 2 at a higher priority.
        * Pass the address of xTask2Handle as the pxCreatedTask parameter so
        * that xTaskCreate write the resulting task handle to that variable.
        */
        xTaskCreate( vTask2, "Task 2", 1000, NULL, 2, &xTask2Handle );

        /*
        * Task 2 has/had the higher priority. For Task 1 to reach here, Task 2
        * must have already executed and deleted itself.
        */
        vTaskDelay( xDelay100ms );
    }
}
C

Code Block 1.28. Hàm thực hiện Task 1 trong Ví dụ 1.9

void vTask2( void * pvParameters )
{
    /*
    * Task 2 immediately deletes itself upon starting.
    * To do this it could call vTaskDelete() using NULL as the parameter.
    * For demonstration purposes, it instead calls vTaskDelete() with its own
    * task handle.
    */
    vPrintLine( "Task 2 is running and about to delete itself" );
    vTaskDelete( xTask2Handle );
}
C

Code Block 1.29. Hàm thực hiện Task 2 trong Ví dụ 1.9

C:\Temp>rtosdemo
Task1 is running
Task2 is running and about to delete itself
Task1 is running
Task2 is running and about to delete itself
Task1 is running
Task2 is running and about to delete itself
Task1 is running
Task2 is running and about to delete itself
Task1 is running
Task2 is running and about to delete itself
Task1 is running
Task2 is running and about to delete itself
Task1 is running
Task2 is running and about to delete itself
Task1 is running
Task2 is running and about to delete itself
Plaintext

Hình 1.16. Kết quả thực thi của Ví dụ 1.9

(Đang viết tiếp)