2013-02-07 26 views
14

Sau khi di chuyển một số mã nhúng sang FreeRTOS, tôi bị bỏ lại với một tình huống khó xử thú vị về cơ quan giám sát. Các bộ đếm thời gian watchdog là phải cho ứng dụng của chúng tôi. Sử dụng FreeRTOS cũng là một lợi ích lớn đối với chúng tôi. Khi ứng dụng đơn giản hơn, nó cho phép cơ quan giám sát tại các điểm kịp thời trong luồng logic của nó để chúng ta có thể đảm bảo nhiệm vụ đang tiến hành hợp lý một cách kịp thời.Chiến lược cho ăn một cơ quan giám sát trong môi trường đa nhiệm

Với nhiều tác vụ, điều đó không hề dễ dàng. Một nhiệm vụ có thể bị ràng buộc vì một lý do nào đó, không tiến bộ, nhưng một công việc khác đang làm tốt và có đủ tiến bộ để giữ cho cơ quan giám sát được nuôi dưỡng một cách vui vẻ. Một ý nghĩ là khởi chạy một nhiệm vụ riêng biệt chỉ để nuôi cơ quan giám sát, và sau đó sử dụng một số quầy mà các nhiệm vụ khác tăng thường xuyên, khi nhiệm vụ watchdog đánh dấu, nó sẽ đảm bảo rằng tất cả các quầy trông giống như tiến trình đang được thực hiện trên tất cả các nhiệm vụ khác, và nếu có, hãy tiếp tục và nuôi cơ quan giám sát.

Tôi tò mò những gì người khác đã làm trong các tình huống như thế này?

+4

Chúng tôi đã thực hiện khá nhiều những gì bạn đã nói. Có một kicker, và nhiệm vụ với thời gian đã biết kiểm tra với kicker. Nếu những nhiệm vụ đó không chạy đúng lúc, kicker cũng không chạy. Các kicker nên là chủ đề ưu tiên thấp nhất trong hệ thống, vì vậy nếu hệ thống không có thời gian để có được kicker, sau đó thiết bị sẽ thiết lập lại. (Điều đó cũng cho phép bạn bảo vệ bản thân kicker.) Tôi đang bận, nhưng sẽ cố gắng đưa ra một câu trả lời dài hơn với nhau sau này. – Ross

+0

Tôi dường như nhớ một câu hỏi tương tự trong vòng một tháng qua, chắc chắn với thẻ nhúng. – Dan

Trả lời

7

Nhiệm vụ giám sát giám sát trạng thái của tất cả các tác vụ khác là giải pháp tốt. Nhưng thay vì truy cập, hãy xem xét sử dụng cờ trạng thái cho mỗi tác vụ. Cờ trạng thái phải có ba giá trị có thể: UNKNOWN, ALIVE và ASLEEP. Khi một tác vụ định kỳ chạy, nó sẽ đặt cờ thành ALIVE. Các tác vụ chặn trên một sự kiện không đồng bộ nên đặt cờ của họ thành ASLEEP trước khi chúng chặn và ALIVE khi chạy. Khi nhiệm vụ giám sát giám sát chạy nó sẽ kick cơ quan giám sát nếu mọi công việc là ALIVE hoặc ASLEEP. Sau đó, nhiệm vụ giám sát cơ quan giám sát nên đặt tất cả các cờ ALIVE thành UNKNOWN. (Cờ ASLEEP nên vẫn còn ASLEEP.) Các nhiệm vụ với cờ UNKNOWN phải chạy và thiết lập cờ của họ để ALIVE hoặc ASLEEP một lần nữa trước khi nhiệm vụ giám sát sẽ kick cơ quan giám sát một lần nữa.

Hãy xem phần "đa nhiệm" của bài viết này để biết thêm chi tiết: http://www.embedded.com/design/debug-and-optimization/4402288/Watchdog-Timers

2

Đây thực sự là một nỗi đau lớn với bộ đếm thời gian giám sát.

Bảng của tôi có đèn LED trên đường GPIO, vì vậy tôi nháy đèn trong một khoảng thời gian/ngủ, (750 mili giây, 250 micrô tắt), trong chuỗi ưu tiên tiếp theo đến thấp nhất, (thấp nhất là chuỗi nhàn rỗi chỉ chuyển sang chế độ công suất thấp trong vòng lặp). Tôi đã đặt một nguồn cấp dữ liệu wdog trong chủ đề đèn flash LED.

Điều này giúp khắc phục sự cố hoàn toàn và các chuỗi có mức ưu tiên cao hơn mà vòng lặp CPU, nhưng không giúp ích nếu hệ thống bị khóa. May mắn thay, thiết kế thông điệp của tôi không bế tắc, (tốt, không thường xuyên, anyway :).

2

Đừng quên để xử lý tình huống tốt nơi công việc được xóa, hoặc không hoạt động cho thời gian dài hơn. Nếu những nhiệm vụ trước đây đã được kiểm tra với nhiệm vụ của cơ quan giám sát, họ cũng cần có cơ chế 'kiểm tra'.

Nói cách khác, danh sách nhiệm vụ mà tác vụ giám sát chịu trách nhiệm phải linh hoạt và cần được tổ chức để một số mã hoang dã không thể dễ dàng xóa tác vụ khỏi danh sách.

tôi biết, dễ dàng hơn sau đó nói làm ...

0

Tôi đã thiết kế các giải pháp sử dụng các tính giờ FreeRTOS:

  1. SystemSupervisor SW hẹn giờ mà nuôi HW WD. Lỗi FreeRTOS gây ra đặt lại.
  2. Mỗi tác vụ tạo "bộ hẹn giờ SW" riêng với chức năng SystemReset.
  3. Mỗi tác vụ chịu trách nhiệm "theo cách thủ công" tải lại bộ hẹn giờ trước khi hết hạn.
  4. SystemReset chức năng lưu dữ liệu trước khi cam kết một suiside

Dưới đây là một số mã giả niêm yết:

//--------------------------------- 
// 
// System WD 
// 
void WD_init(void) 
{ 
HW_WD_Init(); 
    // Read Saved Failure data, Send to Monitor 
    // Create Monitor timer 
    xTimerCreate( "System WD",  // Name 
        HW_WD_INTERVAL/2, // Reload value 
        TRUE,    // Auto Reload 
        0,     // Timed ID (Data per timer) 
        SYS_WD_Feed); 
} 
void SYS_WD_Feed(void) 
{ 
    HW_WD_Feed(); 
} 

//------------------------- 
// Tasks WD 
// 
WD_Handler WD_Create() 
{ 
    return xTimerCreate( "",     // Name 
          100,    // Dummy Reload value 
          FALSE,    // Auto Reload 
          pxCurrentTCB,  // Timed ID (Data per timer) 
          Task_WD_Reset); 
} 

Task_WD_Reset(pxTimer) 
{ 
    TaskHandler_t th = pvTimerGetTimerID(pxTimer) 
    // Save Task Name and Status 
    // Reset 
} 

Task_WD_Feed(WD_Handler, ms) 
{ 
    xTimerChangePeriod(WD_Handler, ms/portTICK_PERIOD_MS, 100); 
} 
Các vấn đề liên quan