Biên dịch một ứng dụng để sử dụng trong môi trường phóng xạ cao


1456

Chúng tôi đang biên dịch một ứng dụng C / C ++ nhúng được triển khai trong một thiết bị được bảo vệ trong môi trường bị bắn phá bởi bức xạ ion hóa . Chúng tôi đang sử dụng GCC và biên dịch chéo cho ARM. Khi được triển khai, ứng dụng của chúng tôi tạo ra một số dữ liệu sai sót và sự cố thường xuyên hơn chúng ta muốn. Phần cứng được thiết kế cho môi trường này và ứng dụng của chúng tôi đã chạy trên nền tảng này trong vài năm.

Có những thay đổi nào chúng ta có thể thực hiện đối với mã của mình hoặc cải tiến thời gian biên dịch có thể được thực hiện để xác định / sửa lỗi mềmhỏng bộ nhớ do các sự kiện đơn lẻ gây ra không? Có nhà phát triển nào khác đã thành công trong việc giảm tác động có hại của lỗi mềm đối với ứng dụng chạy dài không?


186
Là các giá trị trong bộ nhớ thay đổi hay là các giá trị trong bộ xử lý thay đổi? Nếu phần cứng được thiết kế cho môi trường, phần mềm sẽ chạy như thể chạy trên môi trường không phóng xạ.
Thomas Matthews

3
Nếu có thể, bạn nên thiết lập một hệ thống ghi nhật ký lưu trữ các sự kiện trong bộ nhớ không bay hơi có khả năng chống bức xạ. Lưu trữ đủ thông tin để bạn có thể theo dõi sự kiện và dễ dàng tìm ra nguyên nhân gốc.
Thomas Matthews

2
@Thomas Matthews Tất cả bộ nhớ có tỷ lệ lỗi FIT và các nhà sản xuất phần cứng đưa ra nhiều lời hứa. Hầu hết các vấn đề có thể do SEU sửa đổi ram khi chạy.
rook

9
Đây là một giải pháp phần cứng / phần mềm kết hợp, nhưng tôi biết Texas Cụ (và có thể là các công cụ khác) tạo ra các chip nhúng cho các ứng dụng quan trọng an toàn bao gồm hai lõi trùng lặp, chạy theo bước khóa, nửa chu kỳ lệch pha. Có các ngắt đặc biệt và các hành động thiết lập lại được thực hiện khi phần cứng phát hiện ra điều gì đó khác biệt giữa các lõi, do đó bạn có thể khôi phục từ các lỗi. Tôi tin rằng TI gọi họ là bộ xử lý an toàn "Hercules".
mbrig

5
Động cơ gồ ghề dư thừa, một số bánh răng, trục và bánh xe! Thay thế hàng năm hoặc thường xuyên hơn như tỷ lệ liều yêu cầu. Không thực sự, câu hỏi đầu tiên của tôi với các loại vấn đề này luôn luôn là, bạn có thực sự cần nhiều phần mềm trong đó không? Hãy là tương tự như bạn có thể có thể đi với.
jwdonahue

Câu trả lời:


814

Làm việc khoảng 4-5 năm với phát triển phần mềm / phần sụn và kiểm tra môi trường của các vệ tinh thu nhỏ *, tôi muốn chia sẻ kinh nghiệm của tôi ở đây.

* ( các vệ tinh thu nhỏ thường dễ bị đảo lộn sự kiện hơn các vệ tinh lớn hơn do kích thước tương đối nhỏ, giới hạn cho các thành phần điện tử của nó )

Rất ngắn gọn và trực tiếp: không có cơ chế phục hồi từ tình huống có thể phát hiện, có lỗi do chính phần mềm / phần sụn mà không có , ít nhất, một bản sao của phần mềm / phần sụn hoạt động tối thiểu ở đâu đó cho mục đích khôi phục - và với phần cứng hỗ trợ sự phục hồi (chức năng).

Bây giờ, tình huống này thường được xử lý cả ở cấp độ phần cứng và phần mềm. Ở đây, khi bạn yêu cầu, tôi sẽ chia sẻ những gì chúng ta có thể làm ở cấp độ phần mềm.

  1. ... mục đích phục hồi ... . Cung cấp khả năng cập nhật / biên dịch lại / khởi động lại phần mềm / chương trình cơ sở của bạn trong môi trường thực. Đây là một tính năng gần như phải có cho bất kỳ phần mềm / chương trình cơ sở nào trong môi trường bị ion hóa cao. Nếu không có điều này, bạn có thể có phần mềm / phần cứng dư thừa như bạn muốn nhưng đến một lúc, tất cả chúng sẽ nổ tung. Vì vậy, hãy chuẩn bị tính năng này!

  2. ... phiên bản làm việc tối thiểu ... Có phản hồi, nhiều bản sao, phiên bản tối thiểu của phần mềm / chương trình cơ sở trong mã của bạn. Điều này giống như chế độ An toàn trong Windows. Thay vì chỉ có một, phiên bản đầy đủ chức năng của phần mềm của bạn, có nhiều bản sao của phiên bản phần mềm / phần sụn tối thiểu. Bản sao tối thiểu thường sẽ có kích thước nhỏ hơn nhiều so với bản sao đầy đủ và hầu như luôn chỉ có hai hoặc ba tính năng sau:

    1. có khả năng nghe lệnh từ hệ thống bên ngoài,
    2. có khả năng cập nhật phần mềm / phần sụn hiện tại,
    3. có khả năng giám sát dữ liệu vệ sinh của hoạt động cơ bản.
  3. ... sao chép ... ở đâu đó ... Có phần mềm / phần mềm dự phòng ở đâu đó.

    1. Bạn có thể, có hoặc không có phần cứng dự phòng, cố gắng có phần mềm / phần mềm dự phòng trong ARM uC của bạn. Điều này thường được thực hiện bằng cách có hai hoặc nhiều phần mềm / chương trình cơ sở giống hệt nhau ở các địa chỉ riêng biệt gửi nhịp tim cho nhau - nhưng mỗi lần chỉ có một phần mềm sẽ hoạt động. Nếu một hoặc nhiều phần mềm / phần sụn được biết là không phản hồi, hãy chuyển sang phần mềm / phần sụn khác. Lợi ích của việc sử dụng phương pháp này là chúng tôi có thể thay thế chức năng ngay lập tức sau khi xảy ra lỗi - không có bất kỳ liên hệ nào với bất kỳ hệ thống / bên ngoài nào chịu trách nhiệm phát hiện và sửa chữa lỗi (trong trường hợp vệ tinh, thường là Trung tâm điều khiển nhiệm vụ ( MCC)).

      Nói đúng ra, không có phần cứng dư thừa, nhược điểm của việc này là bạn thực sự không thể loại bỏ tất cả các điểm thất bại duy nhất. Ít nhất, bạn vẫn sẽ có một điểm thất bại duy nhất, đó là chính công tắc (hoặc thường là phần đầu của mã). Tuy nhiên, đối với một thiết bị bị giới hạn bởi kích thước trong môi trường bị ion hóa cao (chẳng hạn như vệ tinh pico / femto), việc giảm điểm hỏng duy nhất xuống một điểm mà không cần phần cứng bổ sung sẽ vẫn đáng xem xét. Ở đâu đó, đoạn mã cho việc chuyển đổi chắc chắn sẽ ít hơn nhiều so với mã cho toàn bộ chương trình - giảm đáng kể rủi ro nhận được Sự kiện Đơn lẻ trong đó.

    2. Nhưng nếu bạn không làm điều này, bạn nên có ít nhất một bản sao trong hệ thống bên ngoài có thể tiếp xúc với thiết bị và cập nhật phần mềm / chương trình cơ sở (trong trường hợp vệ tinh, lại là trung tâm điều khiển nhiệm vụ).

    3. Bạn cũng có thể có bản sao trong bộ nhớ lưu trữ vĩnh viễn trong thiết bị của mình, có thể được kích hoạt để khôi phục phần mềm / chương trình cơ sở của hệ thống đang chạy
  4. ... tình huống có thể phát hiện lỗi .. Lỗi phải được phát hiện , thường là do mạch phát hiện / sửa lỗi lỗi phần cứng hoặc bởi một đoạn mã nhỏ để sửa / phát hiện lỗi. Tốt nhất là đặt mã nhỏ, nhiều và độc lập với phần mềm / phần sụn chính. Nhiệm vụ chính của nó chỉ để kiểm tra / sửa chữa. Nếu mạch / phần cứng là đáng tin cậy(chẳng hạn như bức xạ được làm cứng nhiều hơn so với phần còn lại - hoặc có nhiều mạch / logic), sau đó bạn có thể xem xét thực hiện sửa lỗi với nó. Nhưng nếu không, tốt hơn là làm cho nó phát hiện lỗi. Việc điều chỉnh có thể bằng hệ thống / thiết bị bên ngoài. Để sửa lỗi, bạn có thể xem xét sử dụng thuật toán sửa lỗi cơ bản như Hamming / Golay23, vì chúng có thể được thực hiện dễ dàng hơn cả trong mạch / phần mềm. Nhưng cuối cùng nó phụ thuộc vào khả năng của nhóm bạn. Để phát hiện lỗi, thông thường CRC được sử dụng.

  5. ... phần cứng hỗ trợ phục hồi Bây giờ, đến khía cạnh khó khăn nhất về vấn đề này. Cuối cùng, việc khôi phục đòi hỏi phần cứng chịu trách nhiệm cho việc khôi phục ít nhất là có chức năng. Nếu phần cứng bị hỏng vĩnh viễn (thường xảy ra sau khi tổng liều ion hóa của nó đạt đến mức nhất định), thì thật đáng buồn là phần mềm này không thể giúp phục hồi. Do đó, phần cứng đúng là mối quan tâm tối đa đối với một thiết bị tiếp xúc với mức bức xạ cao (như vệ tinh).

Ngoài đề xuất về lỗi dự đoán phần sụn ở trên do sự cố đơn lẻ, tôi cũng muốn đề nghị bạn có:

  1. Phát hiện lỗi và / hoặc thuật toán sửa lỗi trong giao thức truyền thông giữa các hệ thống con. Đây là một thứ khác gần như phải có để tránh các tín hiệu không đầy đủ / sai nhận được từ hệ thống khác

  2. Lọc trong đọc ADC của bạn. Đừng không sử dụng ADC đọc trực tiếp. Lọc nó bằng bộ lọc trung bình, bộ lọc trung bình hoặc bất kỳ bộ lọc nào khác - không bao giờ tin vào giá trị đọc đơn lẻ. Mẫu nhiều hơn, không ít - hợp lý.


401

NASA có một bài viết về phần mềm làm cứng bức xạ . Nó mô tả ba nhiệm vụ chính:

  1. Theo dõi thường xuyên bộ nhớ cho các lỗi sau đó loại bỏ các lỗi đó,
  2. cơ chế phục hồi lỗi mạnh mẽ và
  3. khả năng cấu hình lại nếu một cái gì đó không còn hoạt động.

Lưu ý rằng tốc độ quét bộ nhớ phải đủ thường xuyên để hiếm khi xảy ra lỗi nhiều bit, vì hầu hết bộ nhớ ECC có thể phục hồi từ các lỗi một bit, không phải lỗi nhiều bit.

Phục hồi lỗi mạnh mẽ bao gồm chuyển luồng điều khiển (thường khởi động lại một quy trình tại một điểm trước khi xảy ra lỗi), giải phóng tài nguyên và khôi phục dữ liệu.

Khuyến cáo chính của họ về phục hồi dữ liệu là tránh sự cần thiết của nó, thông qua việc dữ liệu trung gian được coi là tạm thời, do đó, việc khởi động lại trước khi lỗi cũng khiến dữ liệu trở về trạng thái đáng tin cậy. Điều này nghe có vẻ tương tự như khái niệm "giao dịch" trong cơ sở dữ liệu.

Họ thảo luận về các kỹ thuật đặc biệt phù hợp với các ngôn ngữ hướng đối tượng như C ++. Ví dụ

  1. ECC dựa trên phần mềm cho các đối tượng bộ nhớ liền kề
  2. Lập trình theo hợp đồng : xác minh các điều kiện tiên quyết và hậu điều kiện, sau đó kiểm tra đối tượng để xác minh nó vẫn ở trạng thái hợp lệ.

Và, điều đó đã xảy ra, NASA đã sử dụng C ++ cho các dự án lớn như Mars Rover .

Sự trừu tượng hóa và đóng gói lớp C ++ cho phép phát triển và thử nghiệm nhanh chóng giữa nhiều dự án và nhà phát triển.

Họ đã tránh một số tính năng C ++ có thể gây ra sự cố:

  1. Ngoại lệ
  2. Mẫu
  3. Iostream (không có bàn điều khiển)
  4. Đa thừa kế
  5. Quá tải toán tử (khác newdelete)
  6. Phân bổ động (được sử dụng nhóm bộ nhớ chuyên dụng và vị trí newđể tránh khả năng tham nhũng heap hệ thống).

28
Điều này thực sự nghe giống như một ngôn ngữ thuần túy sẽ giỏi. Vì các giá trị không bao giờ thay đổi, nếu chúng bị hỏng, bạn có thể quay lại định nghĩa ban đầu (đó là giá trị của nó) và bạn sẽ không vô tình làm điều tương tự hai lần (vì thiếu tác dụng phụ).
PyRulez

20
RAII là một ý tưởng tồi, bởi vì bạn không thể phụ thuộc vào nó thực hiện chính xác hoặc thậm chí cả. Nó có thể ngẫu nhiên làm hỏng dữ liệu của bạn, v.v. Bạn thực sự muốn có nhiều bất biến như bạn có thể nhận được, và các cơ chế sửa lỗi trên đó. Việc vứt bỏ những thứ bị hỏng dễ dàng hơn nhiều so với việc thử và sửa chữa chúng bằng cách nào đó (chính xác thì bạn biết đủ để quay lại trạng thái cũ đúng không?). Bạn có thể muốn sử dụng một ngôn ngữ khá ngu ngốc cho việc này, mặc dù vậy - tối ưu hóa có thể làm tổn thương nhiều hơn những gì chúng giúp.
Luaan

67
@PyRulez: Ngôn ngữ thuần túy là một sự trừu tượng, phần cứng không thuần túy. Trình biên dịch khá tốt trong việc che giấu sự khác biệt. Nếu chương trình của bạn có giá trị, nó không nên sử dụng nữa sau bước X, trình biên dịch có thể ghi đè lên nó bằng một giá trị được tính trong bước X + 1. Nhưng điều này có nghĩa là bạn không thể quay lại. Chính thức hơn, các trạng thái có thể có của một chương trình trong một ngôn ngữ thuần túy tạo thành một biểu đồ tuần hoàn, có nghĩa là hai trạng thái tương đương và có thể được hợp nhất khi các trạng thái có thể đạt được từ cả hai tương đương. Sự hợp nhất này phá hủy sự khác biệt trong các con đường dẫn đến các trạng thái đó.
MSalters

2
@Vorac - Theo cách trình bày, mối quan tâm với các mẫu C ++ là sự phình to mã.
jww

3
@DeerSpotter Vấn đề chính xác còn lớn hơn thế nhiều. Ion hóa có thể làm hỏng bit của chương trình theo dõi đang chạy của bạn. Sau đó, bạn sẽ cần một người theo dõi của một người theo dõi, sau đó - người theo dõi của một người theo dõi của một người theo dõi và như vậy ...
Ag tích Vasiliauskas

116

Dưới đây là một số suy nghĩ và ý tưởng:

Sử dụng ROM sáng tạo hơn.

Lưu trữ bất cứ điều gì bạn có thể trong ROM. Thay vì tính toán mọi thứ, hãy lưu trữ các bảng tra cứu trong ROM. (Hãy chắc chắn rằng trình biên dịch của bạn đang xuất các bảng tra cứu của bạn sang phần chỉ đọc! In ra các địa chỉ bộ nhớ trong thời gian chạy để kiểm tra!) Lưu bảng vectơ ngắt của bạn vào ROM. Tất nhiên, hãy chạy một số thử nghiệm để xem ROM của bạn đáng tin cậy như thế nào so với RAM của bạn.

Sử dụng RAM tốt nhất của bạn cho ngăn xếp.

Các SEU trong ngăn xếp có lẽ là nguồn có khả năng xảy ra sự cố nhất, bởi vì đó là nơi những thứ như biến chỉ số, biến trạng thái, địa chỉ trả về và con trỏ thuộc nhiều loại khác nhau thường sống.

Thực hiện thói quen hẹn giờ tick-tick và watchdog.

Bạn có thể chạy thói quen "kiểm tra vệ sinh" mỗi lần bấm giờ, cũng như thói quen theo dõi để xử lý việc khóa hệ thống. Mã chính của bạn cũng có thể tăng định kỳ một bộ đếm để chỉ ra tiến trình và thói quen kiểm tra độ tỉnh táo có thể đảm bảo điều này đã xảy ra.

Thực hiện sửa lỗi mã trong phần mềm.

Bạn có thể thêm dự phòng vào dữ liệu của mình để có thể phát hiện và / hoặc sửa lỗi. Điều này sẽ thêm thời gian xử lý, có khả năng khiến bộ xử lý tiếp xúc với bức xạ trong thời gian dài hơn, do đó làm tăng khả năng xảy ra lỗi, do đó bạn phải xem xét đánh đổi.

Nhớ bộ nhớ cache.

Kiểm tra kích thước bộ nhớ CPU của bạn. Dữ liệu mà bạn đã truy cập hoặc sửa đổi gần đây có thể sẽ nằm trong bộ đệm. Tôi tin rằng bạn có thể vô hiệu hóa ít nhất một số bộ nhớ cache (với chi phí hiệu năng lớn); bạn nên thử điều này để xem mức độ nhạy cảm của bộ nhớ cache đối với SEU. Nếu bộ nhớ cache cứng hơn RAM thì bạn có thể thường xuyên đọc và ghi lại dữ liệu quan trọng để đảm bảo nó lưu trong bộ nhớ cache và đưa RAM trở lại hàng.

Sử dụng xử lý lỗi trang một cách khéo léo.

Nếu bạn đánh dấu một trang bộ nhớ là không có mặt, CPU sẽ phát sinh lỗi trang khi bạn cố truy cập nó. Bạn có thể tạo một trình xử lý lỗi trang để thực hiện một số kiểm tra trước khi phục vụ yêu cầu đọc. (Hệ điều hành PC sử dụng điều này để tải trong suốt các trang đã được hoán đổi vào đĩa.)

Sử dụng ngôn ngữ lắp ráp cho những thứ quan trọng (có thể là tất cả mọi thứ).

Với ngôn ngữ lắp ráp, bạn biết những gì trong thanh ghi và những gì trong RAM; bạn biết CPU nào đang sử dụng các bảng RAM đặc biệt và bạn có thể thiết kế mọi thứ theo cách vòng để giảm rủi ro.

Sử dụng objdumpđể thực sự nhìn vào ngôn ngữ lắp ráp được tạo và tìm ra bao nhiêu mã mỗi thói quen của bạn chiếm.

Nếu bạn đang sử dụng một hệ điều hành lớn như Linux thì bạn sẽ gặp rắc rối; có quá nhiều phức tạp và rất nhiều điều sai lầm.

Hãy nhớ rằng nó là một trò chơi của xác suất.

Một bình luận nói

Mỗi thói quen bạn viết để bắt lỗi sẽ phải chịu lỗi từ cùng một nguyên nhân.

Mặc dù điều này là đúng, nhưng khả năng xảy ra lỗi trong (nói) 100 byte mã và dữ liệu cần thiết cho một thói quen kiểm tra để hoạt động chính xác là nhỏ hơn nhiều so với khả năng xảy ra lỗi ở nơi khác. Nếu ROM của bạn khá đáng tin cậy và gần như tất cả mã / dữ liệu thực sự nằm trong ROM thì tỷ lệ cược của bạn thậm chí còn tốt hơn.

Sử dụng phần cứng dự phòng.

Sử dụng 2 hoặc nhiều thiết lập phần cứng giống hệt nhau với mã giống hệt nhau. Nếu kết quả khác nhau, thiết lập lại nên được kích hoạt. Với 3 thiết bị trở lên, bạn có thể sử dụng hệ thống "biểu quyết" để cố gắng xác định thiết bị nào đã bị xâm phạm.


14
Ngày nay, có ECC có sẵn thông qua phần cứng, giúp tiết kiệm thời gian xử lý. Bước một sẽ là chọn một vi điều khiển có ECC tích hợp.
Lundin

23
Ở đâu đó trong tâm trí tôi là một tài liệu tham khảo về phần cứng máy bay (có lẽ là tàu con thoi?) Trong đó kiến ​​trúc dự phòng được thiết kế rõ ràng không giống hệt nhau (và bởi các đội khác nhau). Làm như vậy sẽ giảm thiểu khả năng xảy ra lỗi hệ thống trong thiết kế phần cứng / phần mềm, giảm khả năng tất cả các hệ thống bỏ phiếu bị sập cùng một lúc khi phải đối mặt với cùng một đầu vào.
Peter M

8
@PeterM: AFAIK cũng được yêu cầu cho phần mềm máy bay cho Boeing 777: Ba phiên bản của ba đội trong ba ngôn ngữ lập trình.
Phục hồi Monica - M. Schröder

7
RAM @DanEsparza thường có tụ điện (DRAM) hoặc một vài bóng bán dẫn trong phản hồi (SRAM) lưu trữ dữ liệu. Một sự kiện bức xạ có thể sạc / xả tụ điện, hoặc thay đổi tín hiệu trong vòng phản hồi. ROM thường không cần khả năng ghi (ít nhất là không có trường hợp đặc biệt và / hoặc điện áp cao hơn) và do đó có thể ổn định hơn ở cấp độ vật lý.
nanofarad

7
@DanEsparza: Có nhiều loại bộ nhớ ROM. Nếu "ROM" được mô phỏng theo tức là eeprom hoặc flash readonly-at-5v nhưng có thể lập trình ở mức 10v, thì thực sự "ROM" vẫn dễ bị ion hóa. Có lẽ chỉ ít hơn những người khác. Tuy nhiên, có những thứ khó tin như Mặt nạ ROM hoặc PROM dựa trên cầu chì mà tôi nghĩ sẽ cần một lượng phóng xạ thực sự nghiêm trọng để bắt đầu thất bại. Tôi không biết tuy nhiên nếu vẫn còn sản xuất.
quetzalcoatl

105

Bạn cũng có thể quan tâm đến các tài liệu phong phú về chủ đề dung sai lỗi thuật toán. Điều này bao gồm việc chuyển nhượng cũ: Viết một loại mà sắp xếp một cách chính xác đầu vào của nó khi một hằng số so sánh sẽ thất bại (hoặc, phiên bản hơi ác hơn, khi số tiệm cận của thất bại so sánh quy mô như log(n)cho nsự so sánh).

Một nơi để bắt đầu đọc là bài viết " Dung sai lỗi dựa trên thuật toán " của Huang và Abraham năm 1984 . Ý tưởng của họ gần giống với tính toán mã hóa đồng cấu (nhưng nó không thực sự giống nhau, vì họ đang cố gắng phát hiện / sửa lỗi ở cấp độ hoạt động).

Một hậu duệ gần đây của bài báo đó là "Khả năng chịu lỗi dựa trên thuật toán được áp dụng cho điện toán hiệu năng cao " của Bosilca, Delmas, Dongarra và Langou .


5
Tôi thực sự thích phản ứng của bạn. Đây là một cách tiếp cận phần mềm chung hơn cho tính toàn vẹn dữ liệu và giải pháp chống lỗi dựa trên thuật toán sẽ được sử dụng trong sản phẩm cuối cùng của chúng tôi. Cảm ơn!
rook

41

Viết mã cho môi trường phóng xạ không thực sự khác biệt so với viết mã cho bất kỳ ứng dụng quan trọng nào.

Ngoài những gì đã được đề cập, đây là một số mẹo linh tinh:

  • Sử dụng các biện pháp an toàn "bánh mì & bơ" hàng ngày nên có trên bất kỳ hệ thống nhúng bán chuyên nghiệp nào: giám sát nội bộ, phát hiện điện áp thấp bên trong, giám sát đồng hồ bên trong. Những điều này thậm chí không cần phải đề cập trong năm 2016 và chúng là tiêu chuẩn cho hầu hết mọi vi điều khiển hiện đại.
  • Nếu bạn có MCU an toàn và / hoặc định hướng ô tô, nó sẽ có một số tính năng nhất định của cơ quan giám sát, như cửa sổ thời gian nhất định, bên trong bạn cần làm mới cơ quan giám sát. Điều này được ưa thích nếu bạn có một hệ thống thời gian thực quan trọng.
  • Nói chung, sử dụng MCU phù hợp với các loại hệ thống này, và không phải một số lông tơ chính chung chung mà bạn nhận được trong một gói bột ngô. Hầu như mọi nhà sản xuất MCU hiện nay đều có MCU chuyên dụng được thiết kế cho các ứng dụng an toàn (TI, Freescale, Renesas, ST, Infineon, v.v.). Chúng có rất nhiều tính năng an toàn tích hợp, bao gồm các lõi bước khóa: có nghĩa là có 2 lõi CPU thực thi cùng một mã và chúng phải đồng ý với nhau.
  • QUAN TRỌNG: Bạn phải đảm bảo tính toàn vẹn của các thanh ghi MCU nội bộ. Tất cả các thanh ghi điều khiển và trạng thái của các thiết bị ngoại vi phần cứng có thể ghi có thể được đặt trong bộ nhớ RAM và do đó dễ bị tổn thương.

    Để bảo vệ bạn trước các lỗi đăng ký, tốt nhất là chọn một vi điều khiển có các tính năng "ghi một lần" tích hợp của các thanh ghi. Ngoài ra, bạn cần lưu trữ các giá trị mặc định của tất cả các thanh ghi phần cứng trong NVM và sao chép các giá trị đó vào các thanh ghi của bạn theo định kỳ. Bạn có thể đảm bảo tính toàn vẹn của các biến quan trọng theo cách tương tự.

    Lưu ý: luôn luôn sử dụng lập trình phòng thủ. Có nghĩa là bạn phải thiết lập tất cả các thanh ghi trong MCU chứ không chỉ các thanh ghi được sử dụng bởi ứng dụng. Bạn không muốn một số thiết bị ngoại vi phần cứng ngẫu nhiên đột nhiên thức dậy.

  • Có tất cả các loại phương pháp để kiểm tra lỗi trong RAM hoặc NVM: tổng kiểm tra, "kiểu đi bộ", ECC phần mềm, v.v. Giải pháp tốt nhất hiện nay là không sử dụng bất kỳ phương pháp nào trong số này, nhưng sử dụng MCU với ECC tích hợp và kiểm tra tương tự. Bởi vì làm điều này trong phần mềm rất phức tạp và bản thân việc kiểm tra lỗi có thể gây ra lỗi và sự cố không mong muốn.

  • Sử dụng dự phòng. Bạn có thể lưu trữ cả bộ nhớ dễ bay hơi và không bay hơi trong hai phân đoạn "gương" giống nhau, luôn phải tương đương nhau. Mỗi phân khúc có thể có một tổng kiểm tra CRC kèm theo.
  • Tránh sử dụng các bộ nhớ ngoài bên ngoài MCU.
  • Thực hiện một trình xử lý ngoại lệ / trình xử lý ngoại lệ mặc định cho tất cả các ngắt / ngoại lệ có thể xảy ra. Ngay cả những người bạn không sử dụng. Thói quen mặc định sẽ không làm gì ngoài việc tắt nguồn ngắt của chính nó.
  • Hiểu và nắm lấy khái niệm lập trình phòng thủ. Điều này có nghĩa là chương trình của bạn cần xử lý tất cả các trường hợp có thể xảy ra, ngay cả những trường hợp không thể xảy ra trong lý thuyết. Ví dụ .

    Phần mềm quan trọng cho nhiệm vụ chất lượng cao phát hiện càng nhiều lỗi càng tốt, và sau đó bỏ qua chúng một cách an toàn.

  • Không bao giờ viết các chương trình dựa trên hành vi được chỉ định kém. Có khả năng hành vi đó có thể thay đổi mạnh mẽ với những thay đổi phần cứng không mong muốn do bức xạ hoặc EMI gây ra. Cách tốt nhất để đảm bảo rằng chương trình của bạn không có lỗi như vậy là sử dụng một tiêu chuẩn mã hóa như MISRA, cùng với một công cụ phân tích tĩnh. Điều này cũng sẽ giúp lập trình phòng thủ và loại bỏ các lỗi (tại sao bạn không muốn phát hiện lỗi trong bất kỳ loại ứng dụng nào?).
  • QUAN TRỌNG: Không thực hiện bất kỳ sự phụ thuộc nào của các giá trị mặc định của các biến thời lượng lưu trữ tĩnh. Đó là, đừng tin vào nội dung mặc định của .datahoặc .bss. Có thể có bất kỳ khoảng thời gian nào từ điểm khởi tạo đến điểm thực sự sử dụng biến, có thể có nhiều thời gian để RAM bị hỏng. Thay vào đó, hãy viết chương trình sao cho tất cả các biến như vậy được đặt từ NVM trong thời gian chạy, ngay trước thời điểm một biến như vậy được sử dụng lần đầu tiên.

    Trong thực tế, điều này có nghĩa là nếu một biến được khai báo ở phạm vi tệp hoặc như static, bạn không bao giờ nên sử dụng =để khởi tạo nó (hoặc bạn có thể, nhưng nó là vô nghĩa, vì dù sao bạn cũng không thể dựa vào giá trị). Luôn đặt nó trong thời gian chạy, ngay trước khi sử dụng. Nếu có thể cập nhật liên tục các biến như vậy từ NVM, thì hãy làm như vậy.

    Tương tự như vậy trong C ++, đừng dựa vào các hàm tạo cho các biến thời lượng lưu trữ tĩnh. Yêu cầu (các) nhà xây dựng gọi một thói quen "thiết lập" công khai, mà bạn cũng có thể gọi sau này trong thời gian chạy, trực tiếp từ ứng dụng người gọi.

    Nếu có thể, hãy xóa mã khởi động "sao chép xuống" khởi tạo .data.bss(và gọi các hàm tạo C ++) hoàn toàn, để bạn nhận được các lỗi liên kết nếu bạn viết mã dựa vào đó. Nhiều trình biên dịch có tùy chọn bỏ qua điều này, thường được gọi là "khởi động tối thiểu / nhanh" hoặc tương tự.

    Điều này có nghĩa là bất kỳ thư viện bên ngoài nào cũng phải được kiểm tra để chúng không chứa bất kỳ sự phụ thuộc nào như vậy.

  • Thực hiện và xác định trạng thái an toàn cho chương trình, đến nơi bạn sẽ hoàn nguyên trong trường hợp có lỗi nghiêm trọng.

  • Việc thực hiện một báo cáo lỗi / hệ thống nhật ký lỗi luôn hữu ích.

Một cách để đối phó với các booleans bị hỏng (như trong liên kết ví dụ của bạn) có thể là làm cho TRUEbằng với 0xffffffffsau đó sử dụng POPCNTvới một ngưỡng.
wizzwizz4

@ wizzwizz4 Cho rằng giá trị 0xff là giá trị mặc định của ô flash không được lập trình, nghe có vẻ là một ý tưởng tồi.
Lundin

%01010101010101010101010101010101, XOR rồi POPCNT?
wizzwizz4

1
@ wizzwizz4 Hoặc chỉ là giá trị 0x1, theo yêu cầu của tiêu chuẩn C.
Lundin

1
@ wizzwizz4 Tại sao bạn sử dụng một số hoặc tất cả các phương pháp được đề cập ở trên (ECC, CRC, v.v.). Mặt khác, tia vũ trụ cũng có thể lật một bit trong .textphần của bạn , thay đổi mã op hoặc tương tự.
Lundin

34

Có thể sử dụng C để viết các chương trình hoạt động mạnh mẽ trong các môi trường như vậy, nhưng chỉ khi hầu hết các hình thức tối ưu hóa trình biên dịch bị vô hiệu hóa. Tối ưu hóa trình biên dịch được thiết kế để thay thế nhiều mẫu mã dường như dư thừa bằng các mẫu "hiệu quả hơn" và có thể không biết lý do mà lập trình viên đang kiểm tra x==42khi trình biên dịch biết không có cách nào xcó thể giữ bất cứ điều gì khác là vì lập trình viên muốn ngăn chặn việc thực thi một số mã nhất định với xviệc giữ một số giá trị khác - ngay cả trong trường hợp cách duy nhất nó có thể giữ giá trị đó sẽ là nếu hệ thống nhận được một số trục trặc điện.

Khai báo các biến như volatilethường hữu ích, nhưng có thể không phải là thuốc chữa bách bệnh. Đặc biệt quan trọng, lưu ý rằng mã hóa an toàn thường yêu cầu các hoạt động nguy hiểm có khóa liên động phần cứng yêu cầu nhiều bước để kích hoạt và mã đó được viết bằng mẫu:

... code that checks system state
if (system_state_favors_activation)
{
  prepare_for_activation();
  ... code that checks system state again
  if (system_state_is_valid)
  {
    if (system_state_favors_activation)
      trigger_activation();
  }
  else
    perform_safety_shutdown_and_restart();
}
cancel_preparations();

Nếu một trình biên dịch dịch mã theo kiểu tương đối theo nghĩa đen và nếu tất cả các kiểm tra về trạng thái hệ thống được lặp lại sau đó prepare_for_activation(), thì hệ thống có thể mạnh mẽ chống lại hầu hết mọi sự cố trục trặc đơn lẻ, ngay cả những sự cố sẽ làm hỏng bộ đếm và ngăn xếp chương trình. Nếu trục trặc xảy ra ngay sau khi gọi đến prepare_for_activation(), điều đó có nghĩa là kích hoạt sẽ phù hợp (vì không có lý do nào khác prepare_for_activation()được gọi trước khi trục trặc). Nếu trục trặc khiến mã tiếp cận prepare_for_activation()không phù hợp, nhưng không có sự kiện trục trặc tiếp theo, sẽ không có cách nào để mã tiếp cận trigger_activation()mà không vượt qua kiểm tra xác thực hoặc gọi hủy_preparations trước [nếu ngăn xếp bị trục trặc, việc thực thi có thể tiến hành tại chỗ ngay trước đótrigger_activation()sau bối cảnh được gọi là prepare_for_activation()trả về, nhưng cuộc gọi đến cancel_preparations()sẽ xảy ra giữa các cuộc gọi đến prepare_for_activation()trigger_activation()do đó khiến cuộc gọi sau trở nên vô hại.

Mã như vậy có thể an toàn trong C truyền thống, nhưng không phải với trình biên dịch C hiện đại. Các trình biên dịch như vậy có thể rất nguy hiểm trong loại môi trường đó bởi vì chúng tích cực cố gắng chỉ bao gồm mã sẽ có liên quan trong các tình huống có thể xảy ra thông qua một số cơ chế được xác định rõ và hậu quả cũng sẽ được xác định rõ. Mã có mục đích sẽ là phát hiện và dọn dẹp sau khi thất bại, trong một số trường hợp, cuối cùng có thể làm cho mọi thứ tồi tệ hơn. Nếu trình biên dịch xác định rằng sự phục hồi đã cố gắng trong một số trường hợp sẽ gọi hành vi không xác định, nó có thể suy ra rằng các điều kiện bắt buộc phải phục hồi như vậy trong các trường hợp đó có thể xảy ra, do đó loại bỏ mã đã kiểm tra chúng.


6
Nói một cách thực tế, có bao nhiêu trình biên dịch hiện đại không cung cấp -O0hoặc chuyển đổi tương đương? GCC sẽ làm rất nhiều điều kỳ lạ nếu bạn cho phép , nhưng nếu bạn yêu cầu nó không làm điều đó, thì nói chung nó cũng có thể được hiểu theo nghĩa đen.
Leushenko

24
Xin lỗi, nhưng ý tưởng này về cơ bản là nguy hiểm. Vô hiệu hóa tối ưu hóa tạo ra một chương trình chậm hơn. Hay nói cách khác, bạn cần CPU nhanh hơn. Khi điều đó xảy ra, CPU nhanh hơn nhanh hơn vì phí trên cổng bóng bán dẫn của chúng nhỏ hơn. Điều này làm cho chúng dễ bị nhiễm phóng xạ hơn. Chiến lược tốt hơn là sử dụng một con chip lớn, chậm, trong đó một photon đơn lẻ ít có khả năng vượt qua một chút và lấy lại tốc độ -O2.
MSalters

27
Một lý do thứ hai tại sao -O0một ý tưởng tồi là bởi vì nó phát ra các hướng dẫn vô dụng hơn nhiều. Ví dụ: một cuộc gọi không nội tuyến chứa các hướng dẫn để lưu các thanh ghi, thực hiện cuộc gọi, khôi phục các thanh ghi. Tất cả những điều này có thể thất bại. Một hướng dẫn không có ở đó không thể thất bại.
MSalters

15
Một lý do khác tại sao -O0là một ý tưởng tồi: nó có xu hướng lưu trữ các biến trong bộ nhớ thay vì trong một thanh ghi. Bây giờ không chắc chắn rằng bộ nhớ dễ bị SEU hơn, nhưng dữ liệu trong chuyến bay dễ bị ảnh hưởng hơn dữ liệu khi nghỉ ngơi. Di chuyển dữ liệu vô dụng nên tránh, và -O2giúp đỡ ở đó.
MSalters

9
@MSalters: Điều quan trọng không phải là dữ liệu có thể tránh khỏi sự gián đoạn, mà là hệ thống có thể xử lý các gián đoạn theo cách đáp ứng các yêu cầu. Trên nhiều trình biên dịch, vô hiệu hóa tất cả các tối ưu hóa mang lại mã thực hiện quá nhiều động thái đăng ký để đăng ký, điều này là xấu, nhưng lưu trữ các biến trong bộ nhớ sẽ an toàn hơn từ quan điểm phục hồi so với việc giữ chúng trong các thanh ghi. Nếu một người có hai biến trong bộ nhớ được cho là tuân theo một số điều kiện (ví dụ: v1=v2+0xCAFEBABEvà tất cả các cập nhật cho hai biến được thực hiện ...
supercat

28

Đây là một chủ đề cực kỳ rộng. Về cơ bản, bạn không thể thực sự phục hồi sau khi bị hỏng bộ nhớ, nhưng ít nhất bạn có thể cố gắng thất bại kịp thời . Dưới đây là một vài kỹ thuật bạn có thể sử dụng:

  • tổng kiểm tra dữ liệu không đổi . Nếu bạn có bất kỳ dữ liệu cấu hình nào không đổi trong một thời gian dài (bao gồm các thanh ghi phần cứng bạn đã cấu hình), hãy tính toán tổng kiểm tra của nó khi khởi tạo và xác minh định kỳ. Khi bạn thấy sự không phù hợp, đã đến lúc khởi tạo lại hoặc đặt lại.

  • lưu trữ các biến có dự phòng . Nếu bạn có một biến quan trọng x, hãy viết giá trị của nó trong x1, x2x3và đọc nó như là (x1 == x2) ? x2 : x3.

  • thực hiện chương trình giám sát dòng chảy . XOR một cờ toàn cầu với một giá trị duy nhất trong các hàm / nhánh quan trọng được gọi từ vòng lặp chính. Chạy chương trình trong môi trường không có bức xạ với độ bao phủ thử nghiệm gần 100% sẽ cung cấp cho bạn danh sách các giá trị có thể chấp nhận của cờ ở cuối chu kỳ. Đặt lại nếu bạn thấy độ lệch.

  • theo dõi con trỏ ngăn xếp . Khi bắt đầu vòng lặp chính, hãy so sánh con trỏ ngăn xếp với giá trị mong đợi của nó. Đặt lại về độ lệch.


27

Những gì có thể giúp bạn là một cơ quan giám sát . Watchdogs đã được sử dụng rộng rãi trong điện toán công nghiệp trong những năm 1980. Lỗi phần cứng là phổ biến hơn nhiều sau đó - một câu trả lời khác cũng đề cập đến thời kỳ đó.

Watchdog là một tính năng phần cứng / phần mềm kết hợp. Phần cứng là một bộ đếm đơn giản đếm ngược từ một số (giả sử 1023) về không. TTL hoặc logic khác có thể được sử dụng.

Phần mềm đã được thiết kế sao cho một thói quen giám sát hoạt động chính xác của tất cả các hệ thống thiết yếu. Nếu thường trình này hoàn thành chính xác = thấy máy tính chạy tốt, nó sẽ đặt bộ đếm trở lại 1023.

Thiết kế tổng thể là để trong các trường hợp thông thường, phần mềm ngăn chặn bộ đếm phần cứng sẽ về không. Trong trường hợp bộ đếm đạt đến 0, phần cứng của bộ đếm thực hiện nhiệm vụ một và duy nhất của nó và đặt lại toàn bộ hệ thống. Từ góc độ bộ đếm, số không bằng 1024 và bộ đếm tiếp tục đếm ngược lần nữa.

Cơ quan giám sát này đảm bảo rằng máy tính đính kèm được khởi động lại trong rất nhiều trường hợp thất bại. Tôi phải thừa nhận rằng tôi không quen thuộc với phần cứng có thể thực hiện chức năng như vậy trên các máy tính ngày nay. Các giao diện với phần cứng bên ngoài bây giờ phức tạp hơn nhiều so với trước đây.

Một nhược điểm cố hữu của cơ quan giám sát là hệ thống không có sẵn kể từ khi nó bị lỗi cho đến khi bộ đếm của cơ quan giám sát đạt đến không + thời gian khởi động lại. Mặc dù thời gian đó thường ngắn hơn nhiều so với bất kỳ sự can thiệp nào từ bên ngoài hoặc con người, thiết bị được hỗ trợ sẽ cần có thể tiến hành mà không cần điều khiển máy tính cho khung thời gian đó.


9
Cơ quan giám sát truy cập nhị phân với IC tiêu chuẩn TTL thực sự là một giải pháp của thập niên 1980. Đừng làm vậy. Ngày nay, không tồn tại một MCU nào trên thị trường mà không có mạch theo dõi tích hợp. Tất cả những gì bạn cần kiểm tra là nếu đồng hồ đeo tay tích hợp có nguồn đồng hồ riêng (tốt, rất có thể là vỏ máy) hoặc nếu nó thừa hưởng đồng hồ của nó từ đồng hồ hệ thống (xấu).
Lundin

1
Hoặc triển khai cơ quan giám sát trong một đồ họa: ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20130013486.pdf
nos

2
Vẫn được sử dụng rộng rãi trong các bộ xử lý nhúng, tình cờ.
Graham

5
@Peter Mortensen Vui lòng dừng việc chỉnh sửa của bạn trên mỗi câu trả lời cho câu hỏi này. Đây không phải là Wikipedia và những liên kết đó không hữu ích (và tôi chắc rằng mọi người đều biết cách tìm Wikipedia bằng mọi cách ...). Nhiều chỉnh sửa của bạn không chính xác vì bạn không biết chủ đề. Tôi đang quay lại các chỉnh sửa không chính xác của bạn khi tôi bắt gặp chúng. Bạn không chuyển chủ đề này tốt hơn, nhưng tồi tệ hơn. Dừng chỉnh sửa.
Lundin

Jack Ganssle có một bài viết hay về các cơ quan giám sát: ganssle.com/watchdogs.htmlm
Igor Skochinsky

23

Câu trả lời này giả định rằng bạn quan tâm đến việc có một hệ thống hoạt động chính xác, hơn và hơn là có một hệ thống có chi phí tối thiểu hoặc nhanh chóng; hầu hết mọi người chơi với những thứ phóng xạ đều coi trọng tính chính xác / an toàn hơn tốc độ / chi phí

Một số người đã đề xuất thay đổi phần cứng mà bạn có thể thực hiện (tốt - có rất nhiều nội dung hay trong câu trả lời và tôi không có ý định lặp lại tất cả), và những người khác đã đề xuất dự phòng (về nguyên tắc tuyệt vời), nhưng tôi không nghĩ bất cứ ai đã đề nghị làm thế nào sự dư thừa đó có thể hoạt động trong thực tế. Làm thế nào để bạn thất bại hơn? Làm thế nào để bạn biết khi một cái gì đó đã 'đi sai'? Nhiều công nghệ hoạt động trên cơ sở mọi thứ sẽ hoạt động, và do đó thất bại là một điều khó khăn để giải quyết. Tuy nhiên, một số công nghệ điện toán phân tán được thiết kế cho quy mô dự kiến ​​sẽ thất bại (xét cho cùng với quy mô đủ, thất bại của một nút trong số nhiều nút là không thể tránh khỏi với bất kỳ MTBF nào cho một nút); bạn có thể khai thác điều này cho môi trường của bạn.

Đây là một số ý tưởng:

  • Đảm bảo rằng toàn bộ phần cứng của bạn được nhân rộng nlần (trong đó nlớn hơn 2 và tốt nhất là lẻ) và mỗi phần tử phần cứng có thể giao tiếp với nhau với phần tử phần cứng khác. Ethernet là một cách rõ ràng để làm điều đó, nhưng có nhiều tuyến đường đơn giản hơn nhiều sẽ bảo vệ tốt hơn (ví dụ CAN). Giảm thiểu các thành phần phổ biến (thậm chí cả nguồn điện). Điều này có thể có nghĩa là lấy mẫu đầu vào ADC ở nhiều nơi chẳng hạn.

  • Đảm bảo trạng thái ứng dụng của bạn ở một nơi duy nhất, ví dụ như trong máy trạng thái hữu hạn. Điều này có thể hoàn toàn dựa trên RAM, mặc dù không loại trừ lưu trữ ổn định. Do đó, nó sẽ được lưu trữ ở một số nơi.

  • Thông qua một giao thức đại biểu cho những thay đổi của trạng thái. Xem RAFT chẳng hạn. Khi bạn đang làm việc trong C ++, có những thư viện nổi tiếng về việc này. Thay đổi đối với FSM sẽ chỉ được thực hiện khi đa số các nút đồng ý. Sử dụng một thư viện tốt đã biết cho ngăn xếp giao thức và giao thức đại biểu thay vì tự mình thực hiện, hoặc tất cả công việc tốt của bạn về dự phòng sẽ bị lãng phí khi giao thức đại biểu bị treo.

  • Đảm bảo bạn kiểm tra (ví dụ CRC / SHA) FSM của bạn và lưu CRC / SHA trong chính FSM (cũng như truyền trong tin nhắn và tự kiểm tra tin nhắn). Nhận các nút để kiểm tra FSM của họ thường xuyên đối với các tổng kiểm tra này, tổng kiểm tra các tin nhắn đến và kiểm tra tổng kiểm tra của chúng có khớp với tổng kiểm tra của đại biểu hay không.

  • Xây dựng càng nhiều kiểm tra nội bộ khác vào hệ thống của bạn càng tốt, tạo các nút phát hiện khởi động lại lỗi của riêng chúng (điều này tốt hơn là thực hiện một nửa hoạt động với điều kiện bạn có đủ các nút). Cố gắng để cho họ loại bỏ sạch khỏi đại biểu trong khi khởi động lại trong trường hợp họ không xuất hiện trở lại. Khi khởi động lại, họ kiểm tra hình ảnh phần mềm (và bất cứ thứ gì khác mà họ tải) và thực hiện kiểm tra RAM đầy đủ trước khi giới thiệu lại bản đại biểu.

  • Sử dụng phần cứng để hỗ trợ bạn, nhưng làm như vậy một cách cẩn thận. Chẳng hạn, bạn có thể lấy RAM ECC và thường xuyên đọc / ghi thông qua nó để sửa lỗi ECC (và hoảng loạn nếu lỗi không thể sửa được). Tuy nhiên (từ bộ nhớ) RAM tĩnh có khả năng chịu bức xạ ion hóa cao hơn nhiều so với DRAM ở nơi đầu tiên, vì vậy thể tốt hơn khi sử dụng DRAM tĩnh thay thế. Xem điểm đầu tiên bên dưới 'những điều tôi sẽ không làm' là tốt.

Giả sử bạn có 1% khả năng thất bại của bất kỳ nút nào trong vòng một ngày và giả sử bạn có thể khiến các thất bại hoàn toàn độc lập. Với 5 nút, bạn sẽ cần ba lần thất bại trong vòng một ngày, đó là cơ hội 0,00001%. Với nhiều hơn, tốt, bạn có được ý tưởng.

Những điều tôi sẽ không làm:

  • Đánh giá thấp giá trị của việc không có vấn đề để bắt đầu với. Trừ khi trọng lượng là một mối quan tâm, một khối kim loại lớn xung quanh thiết bị của bạn sẽ là một giải pháp rẻ hơn và đáng tin cậy hơn nhiều so với một nhóm lập trình viên có thể đưa ra. Khớp nối quang Ditto của các đầu vào của EMI là một vấn đề, v.v. Dù thế nào đi nữa, hãy cố gắng tìm nguồn cung ứng các thành phần của bạn để tìm ra các thành phần được xếp hạng tốt nhất chống lại bức xạ ion hóa.

  • Cuộn các thuật toán của riêng bạn . Mọi người đã làm công cụ này trước đây. Sử dụng công việc của họ. Dung sai lỗi và thuật toán phân tán là khó. Sử dụng người khác làm việc nếu có thể.

  • Sử dụng các cài đặt trình biên dịch phức tạp với hy vọng bạn sẽ phát hiện ra nhiều lỗi hơn. Nếu bạn may mắn, bạn có thể phát hiện ra nhiều thất bại. Nhiều khả năng, bạn sẽ sử dụng một đường dẫn mã trong trình biên dịch đã được kiểm tra ít hơn, đặc biệt nếu bạn tự cuộn nó.

  • Sử dụng các kỹ thuật chưa được kiểm tra trong môi trường của bạn. Hầu hết mọi người viết phần mềm có tính sẵn sàng cao phải mô phỏng các chế độ thất bại để kiểm tra HA của họ hoạt động chính xác và kết quả là bỏ lỡ nhiều chế độ thất bại. Bạn đang ở vị trí 'may mắn' khi thường xuyên gặp phải những thất bại theo yêu cầu. Vì vậy, hãy kiểm tra từng kỹ thuật và đảm bảo ứng dụng của nó thực sự cải thiện MTBF một lượng vượt quá độ phức tạp để giới thiệu nó (với sự phức tạp đi kèm với các lỗi). Đặc biệt áp dụng điều này cho lời khuyên của tôi thuật toán đại biểu v.v.


2
Ethernet có lẽ không phải là một ý tưởng tuyệt vời để sử dụng trong các ứng dụng quan trọng. I2C cũng vậy, bên ngoài PCB. Một cái gì đó chắc chắn như CAN sẽ phù hợp hơn nhiều.
Lundin

1
@Lundin Điểm công bằng, mặc dù mọi thứ được kết nối quang học (bao gồm ethernet) đều ổn.
abligh

1
Các phương tiện truyền thông vật lý không phải là lý do tại sao Ethernet không phù hợp, nhưng thiếu hành vi thời gian thực xác định. Mặc dù tôi cho rằng ngày nay cũng có cách cung cấp Ethernet đáng tin cậy, tôi chỉ nhóm nó cùng với các thiết bị điện tử thương mại / đồ chơi theo thói quen cũ.
Lundin

1
@Lundin đó là một điểm công bằng, nhưng như tôi đang đề xuất sử dụng nó để chạy RAFT, sẽ có (về mặt lý thuyết) hành vi thời gian thực không xác định trong thuật toán (ví dụ: bầu cử lãnh đạo đồng thời dẫn đến một cuộc bầu cử chạy lại tương tự như CSMA / CD). Nếu hành vi thời gian thực nghiêm ngặt là cần thiết, có thể cho rằng câu trả lời của tôi có nhiều vấn đề hơn ethernet (và lưu ý ở phần đầu câu trả lời của tôi, tôi đã nói 'chính xác' có thể phải trả giá là 'nhanh' thường xuyên). Tôi kết hợp quan điểm của bạn lại CÓ THỂ mặc dù.
abligh

1
@Lundin: Không có hệ thống nào liên quan đến các khía cạnh không đồng bộ có thể hoàn toàn không mang tính quyết định. Tôi nghĩ rằng hành vi xấu nhất của Ethernet có thể bị hạn chế trong trường hợp không bị gián đoạn phần cứng nếu các giao thức phần mềm được thiết lập theo kiểu phù hợp và các thiết bị có ID duy nhất và có giới hạn về số lượng thiết bị (càng nhiều thiết bị, càng lớn số trường hợp xấu nhất của thử lại).
supercat

23

Vì bạn đặc biệt yêu cầu các giải pháp phần mềm và bạn đang sử dụng C ++, tại sao không sử dụng quá tải toán tử để tạo các kiểu dữ liệu an toàn của riêng bạn? Ví dụ:

Thay vì sử dụng uint32_t(và double, int64_tv.v.), hãy tạo riêng của bạn SAFE_uint32_tcó chứa nhiều (tối thiểu 3) uint32_t. Quá tải tất cả các hoạt động bạn muốn (* + - / << >> = ==! = Vv) để thực hiện và làm cho các hoạt động quá tải thực hiện độc lập trên mỗi giá trị nội bộ, tức là không thực hiện một lần và sao chép kết quả. Cả trước và sau, hãy kiểm tra xem tất cả các giá trị bên trong có khớp không. Nếu các giá trị không khớp, bạn có thể cập nhật giá trị sai thành giá trị phổ biến nhất. Nếu không có giá trị phổ biến nhất, bạn có thể thông báo một cách an toàn rằng có lỗi.

Bằng cách này, không có vấn đề gì nếu tham nhũng xảy ra trong ALU, thanh ghi, RAM hoặc trên xe buýt, bạn vẫn sẽ có nhiều lần thử và rất có khả năng bắt lỗi. Tuy nhiên, xin lưu ý rằng điều này chỉ hoạt động đối với các biến bạn có thể thay thế - ví dụ con trỏ ngăn xếp của bạn sẽ vẫn dễ bị ảnh hưởng.

Một câu chuyện bên lề: Tôi gặp phải một vấn đề tương tự, cũng trên một con chip ARM cũ. Hóa ra đó là một chuỗi công cụ sử dụng một phiên bản GCC cũ, cùng với chip cụ thể mà chúng tôi đã sử dụng, đã gây ra lỗi trong một số trường hợp cạnh nhất định (đôi khi) các giá trị bị hỏng được truyền vào các chức năng. Đảm bảo thiết bị của bạn không có bất kỳ sự cố nào trước khi đổ lỗi cho hoạt động radio và vâng, đôi khi, đó là lỗi trình biên dịch =)


1
Một vài trong số những gợi ý này có một cái gì đó cùng với suy nghĩ 'kiểm tra vệ sinh nhiều bit' tương tự để phát hiện tham nhũng, tôi thực sự thích đề xuất này với đề xuất về các kiểu dữ liệu tùy chỉnh quan trọng về an toàn nhất
WearyWanderer

2
Có những hệ thống trên thế giới nơi mỗi nút dự phòng được thiết kế và phát triển bởi các nhóm khác nhau, với một trọng tài để đảm bảo rằng họ không vô tình giải quyết trên cùng một giải pháp. Bằng cách đó, bạn sẽ không gặp phải tất cả các lỗi tương tự và các quá độ tương tự không biểu hiện các chế độ thất bại tương tự.
jwdonahue

16

Tuyên bố miễn trừ trách nhiệm: Tôi không phải là chuyên gia phóng xạ cũng không làm việc cho loại ứng dụng này. Nhưng tôi đã nghiên cứu các lỗi mềm và dự phòng để lưu trữ dữ liệu quan trọng trong thời gian dài, có liên quan phần nào (cùng một vấn đề, các mục tiêu khác nhau).

Vấn đề chính với phóng xạ theo ý kiến ​​của tôi là phóng xạ có thể chuyển đổi bit, do đó phóng xạ có thể / sẽ làm xáo trộn bất kỳ bộ nhớ kỹ thuật số nào . Những lỗi này thường được gọi là lỗi mềm , thối bit, v.v.

Câu hỏi là: làm thế nào để tính toán đáng tin cậy khi bộ nhớ của bạn không đáng tin cậy?

Để giảm đáng kể tỷ lệ lỗi mềm (với chi phí là chi phí tính toán vì phần lớn sẽ là các giải pháp dựa trên phần mềm), bạn có thể:

  • dựa vào sơ đồ dự phòng cũ tốt và cụ thể hơn là các mã sửa lỗi hiệu quả hơn (cùng mục đích, nhưng thuật toán thông minh hơn để bạn có thể phục hồi nhiều bit hơn với ít dự phòng hơn). Điều này đôi khi (sai) cũng được gọi là kiểm tra. Với loại giải pháp này, bạn sẽ phải lưu trữ toàn bộ trạng thái chương trình của mình bất kỳ lúc nào trong một biến / lớp chủ (hoặc một cấu trúc?), Tính toán một ECC và kiểm tra xem ECC có đúng không trước khi làm bất cứ điều gì, và nếu không, sửa chữa các lĩnh vực. Tuy nhiên, giải pháp này không đảm bảo rằng phần mềm của bạn có thể hoạt động (đơn giản là phần mềm sẽ hoạt động chính xác khi có thể hoặc ngừng hoạt động nếu không, vì ECC có thể cho bạn biết nếu có gì đó không ổn và trong trường hợp này bạn có thể dừng phần mềm của mình để bạn không nhận được kết quả giả).

  • hoặc bạn có thể sử dụng các cấu trúc dữ liệu thuật toán linh hoạt, đảm bảo, đến một số ràng buộc, chương trình của bạn vẫn sẽ cho kết quả chính xác ngay cả khi có lỗi mềm. Các thuật toán này có thể được xem như là một hỗn hợp của các cấu trúc thuật toán phổ biến với các lược đồ ECC được trộn lẫn vào nhau, nhưng điều này có khả năng phục hồi tốt hơn nhiều, bởi vì sơ đồ khả năng phục hồi được liên kết chặt chẽ với cấu trúc, do đó bạn không cần phải mã hóa các thủ tục bổ sung để kiểm tra ECC, và thường thì chúng nhanh hơn rất nhiều. Các cấu trúc này cung cấp một cách để đảm bảo rằng chương trình của bạn sẽ hoạt động trong mọi điều kiện, cho đến giới hạn lý thuyết của các lỗi mềm. Bạn cũng có thể trộn các cấu trúc linh hoạt này với sơ đồ dự phòng / ECC để bảo mật bổ sung (hoặc mã hóa các cấu trúc dữ liệu quan trọng nhất của bạn là khả năng phục hồi và phần còn lại, dữ liệu có thể sử dụng mà bạn có thể tính toán lại từ các cấu trúc dữ liệu chính,

Nếu bạn quan tâm đến các cấu trúc dữ liệu linh hoạt (là một lĩnh vực mới, nhưng thú vị, mới trong thuật toán và kỹ thuật dự phòng), tôi khuyên bạn nên đọc các tài liệu sau:

  • Các thuật toán cấu trúc dữ liệu linh hoạt giới thiệu bởi Giuseppe F.Italiano, Universita di Roma "Tor Vergata"

  • Christiano, P., Demaine, ED, & Kishore, S. (2011). Cấu trúc dữ liệu chịu lỗi không mất dữ liệu với chi phí phụ gia. Trong thuật toán và cấu trúc dữ liệu (trang 243-254). Mùa xuân Berlin Heidelberg.

  • Ferraro-Petrillo, U., Grandoni, F., & Italiano, GF (2013). Cấu trúc dữ liệu có khả năng phục hồi các lỗi bộ nhớ: một nghiên cứu thực nghiệm về từ điển. Tạp chí thuật toán thực nghiệm (JEA), 18, 1-6.

  • Tiếng Ý, GF (2010). Các thuật toán đàn hồi và cấu trúc dữ liệu. Trong thuật toán và độ phức tạp (trang 13-24). Mùa xuân Berlin Heidelberg.

Nếu bạn muốn biết thêm về lĩnh vực cấu trúc dữ liệu linh hoạt, bạn có thể kiểm tra các tác phẩm của Giuseppe F. Italiano (và thực hiện theo cách của bạn thông qua các ref) và mô hình Faulty-RAM (được giới thiệu trong Finocchi et al. 2005; Finocchi và tiếng Ý 2008).

/ EDIT: Tôi đã minh họa việc ngăn chặn / phục hồi từ các lỗi mềm chủ yếu cho bộ nhớ RAM và lưu trữ dữ liệu, nhưng tôi không nói về lỗi tính toán (CPU) . Các câu trả lời khác đã chỉ vào việc sử dụng các giao dịch nguyên tử như trong cơ sở dữ liệu, vì vậy tôi sẽ đề xuất một kế hoạch khác đơn giản hơn: dự phòng và bỏ phiếu đa số .

Ý tưởng là bạn chỉ cần thực hiện x lần tính toán giống nhau cho mỗi lần tính toán bạn cần thực hiện và lưu trữ kết quả theo x các biến khác nhau (với x> = 3). Sau đó, bạn có thể so sánh các biến x của mình :

  • nếu tất cả họ đồng ý, thì không có lỗi tính toán nào cả.
  • nếu họ không đồng ý, thì bạn có thể sử dụng phiếu bầu đa số để có được giá trị chính xác và vì điều này có nghĩa là tính toán bị hỏng một phần, bạn cũng có thể kích hoạt quét trạng thái hệ thống / chương trình để kiểm tra xem phần còn lại có ổn không.
  • nếu phiếu bầu đa số không thể xác định người chiến thắng (tất cả các giá trị x là khác nhau), thì đó là một tín hiệu hoàn hảo để bạn kích hoạt quy trình không an toàn (khởi động lại, đưa ra cảnh báo cho người dùng, v.v.).

Sơ đồ dự phòng này rất nhanh so với ECC (thực tế là O (1)) và nó cung cấp cho bạn một tín hiệu rõ ràng khi bạn cần không an toàn . Đa số phiếu bầu cũng (hầu như) được đảm bảo không bao giờ tạo ra đầu ra bị hỏng và cũng để phục hồi từ các lỗi tính toán nhỏ , bởi vì xác suất x tính toán cho cùng một đầu ra là vô cùng lớn (vì có một lượng lớn đầu ra có thể xảy ra, gần như không thể ngẫu nhiên nhận được 3 lần như nhau, thậm chí ít cơ hội hơn nếu x> 3).

Vì vậy, với đa số phiếu bầu, bạn an toàn trước đầu ra bị hỏng và với dự phòng x == 3, bạn có thể khôi phục 1 lỗi (với x == 4, sẽ có 2 lỗi có thể phục hồi, v.v. - phương trình chính xác là nb_error_recoverable == (x-2)x là số của sự lặp lại tính toán vì bạn cần ít nhất 2 phép tính đồng ý để phục hồi bằng cách sử dụng phiếu bầu đa số).

Hạn chế là bạn cần tính x lần thay vì một lần, do đó bạn có thêm chi phí tính toán, nhưng độ phức tạp tuyến tính sao cho bạn không mất nhiều tiền cho những lợi ích bạn có được. Một cách nhanh chóng để thực hiện bỏ phiếu đa số là tính toán chế độ trên một mảng, nhưng bạn cũng có thể sử dụng bộ lọc trung bình.

Ngoài ra, nếu bạn muốn đảm bảo chắc chắn hơn các phép tính được tiến hành chính xác, nếu bạn có thể tự tạo phần cứng, bạn có thể xây dựng thiết bị của mình bằng x CPU và nối dây cho hệ thống để các phép tính được tự động sao chép trên các CPU x với đa số phiếu được thực hiện về mặt cơ học ở cuối (ví dụ sử dụng cổng AND / OR). Điều này thường được thực hiện trong máy bay và các thiết bị quan trọng cho nhiệm vụ (xem dự phòng ba mô-đun ). Bằng cách này, bạn sẽ không có bất kỳ chi phí tính toán nào (vì các phép tính bổ sung sẽ được thực hiện song song) và bạn có một lớp bảo vệ khác khỏi các lỗi mềm (vì việc sao chép tính toán và bỏ phiếu đa số sẽ được quản lý trực tiếp bởi phần cứng chứ không phải bởi phần cứng phần mềm - có thể dễ dàng bị hỏng hơn vì chương trình chỉ đơn giản là các bit được lưu trong bộ nhớ ...).


9

Một điểm không ai có vẻ đã đề cập. Bạn nói rằng bạn đang phát triển GCC và biên dịch chéo lên ARM. Làm thế nào để bạn biết rằng bạn không có mã đưa ra các giả định về RAM miễn phí, kích thước số nguyên, kích thước con trỏ, mất bao lâu để thực hiện một thao tác nhất định, hệ thống sẽ chạy liên tục trong bao lâu hoặc nhiều thứ khác như thế? Đây là một vấn đề rất phổ biến.

Câu trả lời thường là kiểm tra đơn vị tự động. Viết các khai thác thử nghiệm thực thi mã trên hệ thống phát triển, sau đó chạy các khai thác thử nghiệm tương tự trên hệ thống đích. Hãy tìm sự khác biệt!

Đồng thời kiểm tra errata trên thiết bị nhúng của bạn. Bạn có thể thấy có điều gì đó về "đừng làm điều này vì nó sẽ bị sập, vì vậy hãy bật tùy chọn trình biên dịch đó và trình biên dịch sẽ hoạt động xung quanh nó".

Nói tóm lại, nguồn sự cố rất có thể của bạn là lỗi trong mã của bạn. Cho đến khi bạn thực hiện khá chắc chắn rằng đây không phải là trường hợp, đừng lo lắng (chưa) về các chế độ thất bại bí truyền hơn.


1
Thật vậy, không ở đâu trong bài kiểm tra của câu hỏi, tác giả đề cập rằng ứng dụng được tìm thấy chỉ chạy tốt ngoài môi trường phóng xạ.
Marc.2377

9

Bạn muốn có hơn 3 máy nô lệ với chủ ngoài môi trường bức xạ. Tất cả I / O đều thông qua tổng thể chứa cơ chế bỏ phiếu và / hoặc thử lại. Các nô lệ phải có một cơ quan giám sát phần cứng và mỗi lần kêu gọi họ phải được bao quanh bởi CRC hoặc tương tự để giảm khả năng va chạm không tự nguyện. Bumps nên được kiểm soát bởi chủ, vì vậy mất kết nối với chủ tương đương với khởi động lại trong vòng vài giây.

Một lợi thế của giải pháp này là bạn có thể sử dụng cùng một API cho chủ nhân như với nô lệ, do đó, sự dư thừa trở thành một tính năng trong suốt.

Chỉnh sửa: Từ các ý kiến ​​tôi cảm thấy cần phải làm rõ "ý tưởng CRC." Khả năng của nô lệ va chạm với cơ quan giám sát riêng của nó gần bằng không nếu bạn bao quanh vết sưng với CRC hoặc kiểm tra tiêu hóa dữ liệu ngẫu nhiên từ chủ. Dữ liệu ngẫu nhiên đó chỉ được gửi từ chủ khi nô lệ được xem xét kỹ lưỡng với những người khác. Dữ liệu ngẫu nhiên và CRC / digest ngay lập tức bị xóa sau mỗi lần va chạm. Tần số va chạm chủ-nô nên nhiều hơn gấp đôi thời gian chờ của watchdog. Dữ liệu được gửi từ chủ được tạo ra duy nhất mỗi lần.


7
Tôi đang cố gắng tìm hiểu một kịch bản trong đó bạn có thể có một bậc thầy bên ngoài môi trường bức xạ, có thể giao tiếp đáng tin cậy với các nô lệ trong môi trường bức xạ, nơi bạn không thể đặt nô lệ ra ngoài môi trường bức xạ.
fostandy

1
@fostandy: Các nô lệ đang đo hoặc điều khiển bằng thiết bị cần bộ điều khiển. Nói một quầy geiger. Bậc thầy không cần giao tiếp đáng tin cậy do dư thừa nô lệ.
Jonas Byström

4
Giới thiệu một chủ sẽ không tự động có nghĩa là tăng cường bảo mật. Nếu nô lệ x phát điên do tham nhũng bộ nhớ, do đó, nó liên tục tự nói với mình rằng "chủ nhân ở đây, chủ nhân hạnh phúc", thì không có số lượng CRC hoặc lệnh sủa nào của chủ sẽ cứu nó. Bạn sẽ phải cung cấp cho chủ nhân khả năng cắt giảm sức mạnh của nô lệ đó. Và nếu bạn có một lỗi nguyên nhân chung, việc thêm nhiều nô lệ sẽ không tăng tính an toàn. Cũng nên nhớ rằng số lượng lỗi phần mềm và số lượng những thứ có thể phá vỡ tăng lên với độ phức tạp.
Lundin

5
Điều đó đang được nói, tất nhiên sẽ rất tốt khi "thuê ngoài" càng nhiều chương trình để một nơi nào đó ít bị lộ hơn, trong khi giữ cho các thiết bị điện tử trong môi trường phóng xạ càng đơn giản càng tốt, nếu bạn có tùy chọn đó.
Lundin

7

Làm thế nào về việc chạy nhiều phiên bản của ứng dụng của bạn. Nếu sự cố là do thay đổi bit bộ nhớ ngẫu nhiên, rất có thể một số trường hợp ứng dụng của bạn sẽ thực hiện và đưa ra kết quả chính xác. Có lẽ khá dễ dàng (đối với người có nền tảng thống kê) để tính toán có bao nhiêu trường hợp bạn cần xác suất flop bit để đạt được lỗi tổng thể nhỏ như bạn muốn.


2
Chắc chắn một hệ thống nhúng sẽ thích các biện pháp bắt an toàn trong một trường hợp của một ứng dụng mạnh mẽ hơn là chỉ bắn ra một số trường hợp, nâng cao các yêu cầu phần cứng và trong một chừng mực nào đó hy vọng vào sự may mắn mù quáng mà ít nhất một trường hợp có thể vượt qua? Tôi hiểu ý tưởng và nó hợp lệ, nhưng nghiêng về những gợi ý không dựa vào lực lượng vũ phu
WearyWanderer

7

Những gì bạn yêu cầu là chủ đề khá phức tạp - không dễ trả lời. Các câu trả lời khác là ok, nhưng chúng chỉ bao gồm một phần nhỏ của tất cả những điều bạn cần làm.

Như đã thấy trong các bình luận , không thể khắc phục các sự cố phần cứng 100%, tuy nhiên có thể rất cao để giảm hoặc bắt chúng bằng các kỹ thuật khác nhau.

Nếu tôi là bạn, tôi sẽ tạo ra phần mềm ở cấp độ toàn vẹn An toàn cao nhất (SIL-4). Lấy tài liệu IEC 61513 (cho ngành công nghiệp hạt nhân) và làm theo nó.


11
Hay đúng hơn, đọc qua các yêu cầu kỹ thuật và thực hiện những yêu cầu có ý nghĩa. Một phần lớn của các tiêu chuẩn SIL là vô nghĩa, nếu bạn tuân theo chúng một cách giáo điều, bạn sẽ kết thúc với các sản phẩm không an toàn và nguy hiểm. Chứng nhận SIL ngày nay chủ yếu là về việc sản xuất một tấn tài liệu và sau đó mua chuộc một nhà thử nghiệm. Cấp độ SIL không nói gì về sự an toàn thực tế của hệ thống. Thay vào đó, bạn sẽ muốn tập trung vào các biện pháp an toàn kỹ thuật thực tế. Có một số cái rất tốt trong các tài liệu SIL, và có một số thứ hoàn toàn vô nghĩa.
Lundin

7

Ai đó đã đề cập đến việc sử dụng chip chậm hơn để ngăn các ion lật bit dễ dàng. Theo cách tương tự có lẽ sử dụng một cpu / ram chuyên dụng thực sự sử dụng nhiều bit để lưu trữ một bit. Do đó, cung cấp khả năng chịu lỗi phần cứng bởi vì rất khó có khả năng tất cả các bit sẽ bị lật. Vì vậy, 1 = 1111 nhưng sẽ cần phải đạt 4 lần để thực sự lật. (4 có thể là một số xấu vì nếu 2 bit bị lật đã mơ hồ). Vì vậy, nếu bạn đi với 8, bạn nhận được ram ít hơn 8 lần và thời gian truy cập chậm hơn một phần nhưng biểu diễn dữ liệu đáng tin cậy hơn nhiều. Bạn có thể có thể làm điều này cả ở cấp độ phần mềm với trình biên dịch chuyên dụng (phân bổ x lượng không gian nhiều hơn cho mọi thứ) hoặc thực hiện ngôn ngữ (viết trình bao cho các cấu trúc dữ liệu phân bổ mọi thứ theo cách này).


7

Có lẽ nó sẽ giúp để biết điều đó có nghĩa là phần cứng được "thiết kế cho môi trường này". Làm thế nào để nó chính xác và / hoặc chỉ ra sự hiện diện của lỗi SEU?

Tại một dự án liên quan đến thăm dò không gian, chúng tôi đã có một MCU tùy chỉnh, sẽ đưa ra một ngoại lệ / ngắt đối với các lỗi SEU, nhưng với một số độ trễ, tức là một số chu trình có thể được thực hiện / hướng dẫn sau khi một trong đó gây ra ngoại lệ SEU.

Đặc biệt dễ bị tổn thương là bộ đệm dữ liệu, do đó, một trình xử lý sẽ làm mất hiệu lực dòng bộ đệm vi phạm và khởi động lại chương trình. Chỉ có điều, do tính chất không chính xác của ngoại lệ, chuỗi các nội dung đứng đầu bởi việc tăng ngoại lệ có thể không được khởi động lại.

Chúng tôi đã xác định các chuỗi nguy hiểm (không thể khởi động lại) (như lw $3, 0x0($2), theo sau là một insn, điều chỉnh $2và không phụ thuộc vào dữ liệu $3) và tôi đã thực hiện sửa đổi cho GCC, vì vậy các chuỗi như vậy không xảy ra (ví dụ như là phương sách cuối cùng, tách biệt hai insns bởi a nop).

Chỉ cần một cái gì đó để xem xét ...


7

Nếu phần cứng của bạn bị lỗi thì bạn có thể sử dụng bộ lưu trữ cơ học để khôi phục nó. Nếu cơ sở mã của bạn nhỏ và có một số không gian vật lý thì bạn có thể sử dụng kho lưu trữ dữ liệu cơ học.

Nhập mô tả hình ảnh ở đây

Sẽ có một bề mặt vật liệu sẽ không bị ảnh hưởng bởi bức xạ. Nhiều bánh răng sẽ ở đó. Một đầu đọc cơ học sẽ chạy trên tất cả các bánh răng và sẽ linh hoạt để di chuyển lên và xuống. Xuống có nghĩa là 0 và lên có nghĩa là 1. Từ 0 và 1 bạn có thể tạo cơ sở mã của mình.


2
Có lẽ một phương tiện quang học như CD-ROM sẽ đáp ứng định nghĩa này. Nó sẽ có thêm tiền thưởng của một công suất lớn.
Wossname

2
Có nó sẽ tương tự nhưng rom cd sẽ sử dụng ít hơn nhưng đây sẽ là hệ thống cơ học hoàn toàn.
Hitul

7
Tôi tự hỏi liệu có lý do tại sao họ không sử dụng đầu đọc thẻ đục lỗ trong không gian.
Soren

3
@Soren Tốc độ và không gian vật lý có thể là một lý do.
Hitul

5

Sử dụng một lịch trình tuần hoàn . Điều này cung cấp cho bạn khả năng thêm thời gian bảo trì thường xuyên để kiểm tra tính chính xác của dữ liệu quan trọng. Vấn đề thường gặp nhất là tham nhũng của ngăn xếp. Nếu phần mềm của bạn theo chu kỳ, bạn có thể xác định lại ngăn xếp giữa các chu kỳ. Không sử dụng lại ngăn xếp cho các cuộc gọi ngắt, thiết lập một ngăn xếp riêng cho mỗi cuộc gọi ngắt quan trọng.

Tương tự như khái niệm Watchdog là bộ định thời hạn. Bắt đầu một bộ đếm thời gian phần cứng trước khi gọi một chức năng. Nếu chức năng không trở lại trước khi bộ định thời hạn bị gián đoạn thì hãy tải lại ngăn xếp và thử lại. Nếu vẫn thất bại sau 3/5, bạn cần tải lại từ ROM.

Chia phần mềm của bạn thành các phần và cách ly các phần này để sử dụng các vùng nhớ và thời gian thực hiện riêng biệt (Đặc biệt là trong môi trường điều khiển). Ví dụ: thu nhận tín hiệu, dữ liệu chuẩn bị trước, thuật toán chính và thực hiện / truyền kết quả. Điều này có nghĩa là một thất bại trong một phần sẽ không gây ra thất bại thông qua phần còn lại của chương trình. Vì vậy, trong khi chúng tôi đang sửa chữa việc thu tín hiệu, các nhiệm vụ còn lại vẫn tiếp tục trên dữ liệu cũ.

Mọi thứ đều cần CRC. Nếu bạn thực hiện hết RAM, ngay cả .text của bạn cũng cần CRC. Kiểm tra CRC thường xuyên nếu bạn sử dụng một lịch trình theo chu kỳ. Một số trình biên dịch (không phải GCC) có thể tạo CRC cho từng phần và một số bộ xử lý có phần cứng chuyên dụng để thực hiện tính toán CRC, nhưng tôi đoán rằng điều đó sẽ nằm ngoài phạm vi câu hỏi của bạn. Kiểm tra CRC cũng nhắc bộ điều khiển ECC trên bộ nhớ để sửa các lỗi bit đơn trước khi nó trở thành vấn đề.


4

Thứ nhất, thiết kế ứng dụng của bạn xung quanh thất bại . Đảm bảo rằng là một phần của hoạt động dòng chảy thông thường, nó sẽ thiết lập lại (tùy thuộc vào ứng dụng của bạn và loại lỗi hoặc mềm hay cứng). Điều này thật khó để có được sự hoàn hảo: các hoạt động quan trọng đòi hỏi một mức độ giao dịch nào đó có thể cần phải được kiểm tra và điều chỉnh ở cấp độ lắp ráp để việc gián đoạn tại một điểm chính không thể dẫn đến các lệnh bên ngoài không nhất quán. Thất bại nhanh chóng ngay khi phát hiện bất kỳ lỗi bộ nhớ không thể phục hồi hoặc độ lệch dòng điều khiển. Đăng nhập thất bại nếu có thể.

Thứ hai, nếu có thể, sửa tham nhũng và tiếp tục . Điều này có nghĩa là kiểm tra và sửa các bảng không đổi (và mã chương trình nếu bạn có thể) thường xuyên; có lẽ trước mỗi hoạt động chính hoặc trên một ngắt thời gian và lưu trữ các biến trong các cấu trúc tự động sửa lỗi (một lần nữa trước mỗi op chính hoặc trên một ngắt thời gian lấy một đa số phiếu từ 3 và chính xác nếu là một độ lệch duy nhất). Đăng nhập sửa chữa nếu có thể.

Thứ ba, thử nghiệm thất bại . Thiết lập một môi trường kiểm tra có thể lặp lại , lật các bit trong bộ nhớ psuedo-ngẫu nhiên. Điều này sẽ cho phép bạn tái tạo các tình huống tham nhũng và giúp thiết kế ứng dụng của bạn xung quanh chúng.


3

Đưa ra nhận xét của supercat, xu hướng của trình biên dịch hiện đại và những thứ khác, tôi muốn quay trở lại thời cổ đại và viết toàn bộ mã trong tập hợp và phân bổ bộ nhớ tĩnh ở mọi nơi. Đối với loại độ tin cậy hoàn toàn này, tôi nghĩ rằng lắp ráp không còn phải chịu một sự khác biệt lớn về chi phí.


Tôi là một fan hâm mộ lớn của ngôn ngữ lắp ráp (như bạn có thể thấy từ câu trả lời của tôi cho các câu hỏi khác), nhưng tôi không nghĩ đây là một câu trả lời hay. Bạn hoàn toàn có thể biết những gì mong đợi từ trình biên dịch cho hầu hết mã C (về các giá trị sống trong sổ đăng ký so với bộ nhớ) và bạn luôn có thể kiểm tra xem đó có phải là điều bạn mong đợi không. Viết tay một dự án lớn trong asm chỉ là một tấn công việc phụ, ngay cả khi bạn có các nhà phát triển rất thoải mái khi viết ARM asm. Có thể nếu bạn muốn làm những thứ như tính toán kết quả tương tự 3 lần, viết một số hàm trong asm có ý nghĩa. (trình biên dịch sẽ CSE nó đi)
Peter Cordes

Nguy cơ cao hơn nếu không phải cân bằng với nó là nâng cấp trình biên dịch có thể khiến bạn có những thay đổi bất ngờ.
Joshua

1

Đây là số lượng lớn câu trả lời, nhưng tôi sẽ cố gắng tổng hợp ý tưởng của mình về điều này.

Một cái gì đó gặp sự cố hoặc không hoạt động chính xác có thể là kết quả của những sai lầm của chính bạn - sau đó nó có thể dễ dàng sửa chữa khi bạn xác định được vấn đề. Nhưng cũng có khả năng xảy ra lỗi phần cứng - và điều đó rất khó nếu không thể khắc phục nói chung.

Trước tiên, tôi khuyên bạn nên cố gắng nắm bắt tình huống có vấn đề bằng cách đăng nhập (ngăn xếp, đăng ký, gọi hàm) - bằng cách đăng nhập chúng ở đâu đó vào tệp hoặc truyền trực tiếp bằng cách nào đó ("ồ không - tôi gặp sự cố").

Phục hồi từ tình huống lỗi như vậy là khởi động lại (nếu phần mềm vẫn còn hoạt động và khởi động lại) hoặc thiết lập lại phần cứng (ví dụ: hw watchdogs). Dễ dàng hơn để bắt đầu từ cái đầu tiên.

Nếu sự cố liên quan đến phần cứng - thì việc ghi nhật ký sẽ giúp bạn xác định vấn đề gọi chức năng nào xảy ra và điều đó có thể cung cấp cho bạn kiến ​​thức bên trong về những gì không hoạt động và ở đâu.

Ngoài ra nếu mã tương đối phức tạp - sẽ rất hợp lý khi "phân chia và chinh phục" nó - nghĩa là bạn loại bỏ / vô hiệu hóa một số cuộc gọi chức năng mà bạn nghi ngờ là vấn đề - thường vô hiệu hóa một nửa mã và cho phép một nửa khác - bạn có thể nhận được "không hoạt động" / Loại quyết định "không hoạt động" sau đó bạn có thể tập trung vào một nửa mã khác. (Vấn đề là ở đâu)

Nếu sự cố xảy ra sau một thời gian - có thể nghi ngờ tràn ngăn xếp - thì tốt hơn là theo dõi các thanh ghi điểm ngăn xếp - nếu chúng liên tục phát triển.

Và nếu bạn quản lý để tối thiểu hóa hoàn toàn mã của mình cho đến khi loại ứng dụng "hello world" - và nó vẫn bị lỗi ngẫu nhiên - thì sẽ có vấn đề về phần cứng - và cần phải có "nâng cấp phần cứng" - nghĩa là phát minh ra cpu / ram / ... kết hợp phần mềm -hardware sẽ chịu được bức xạ tốt hơn.

Điều quan trọng nhất có lẽ là cách bạn lấy lại nhật ký của mình nếu máy dừng hoàn toàn / được đặt lại / không hoạt động - có lẽ điều đầu tiên là bootstap nên làm - là quay trở về nhà nếu tình huống có vấn đề xảy ra.

Nếu trong môi trường của bạn cũng có thể truyền tín hiệu và nhận phản hồi - bạn có thể thử xây dựng một loại môi trường gỡ lỗi từ xa trực tuyến, nhưng sau đó bạn phải có ít nhất phương tiện truyền thông làm việc và một số bộ xử lý / một số ram ở trạng thái làm việc. Và bằng cách gỡ lỗi từ xa, tôi có nghĩa là cách tiếp cận sơ khai GDB / gdb hoặc cách thực hiện của riêng bạn về những gì bạn cần lấy lại từ ứng dụng của mình (ví dụ: tải xuống tệp nhật ký, tải xuống ngăn xếp cuộc gọi, tải xuống ram, khởi động lại)


Xin lỗi, nhưng câu hỏi là về môi trường phóng xạ nơi mà các lỗi phần cứng sẽ xảy ra. Câu trả lời của bạn là về tối ưu hóa phần mềm nói chung và cách tìm lỗi. Nhưng trong tình huống này, các lỗi không được tạo ra bởi các lỗi
jeb

Có, bạn cũng có thể đổ lỗi cho lực hấp dẫn trái đất, tối ưu hóa trình biên dịch, thư viện bên thứ 3, môi trường phóng xạ, v.v. Nhưng bạn có chắc đó không phải là lỗi của riêng bạn? :-) Trừ khi được chứng minh - Tôi không tin như vậy. Tôi đã từng chạy một lần một số cập nhật chương trình cơ sở và kiểm tra tình huống tắt nguồn - phần mềm của tôi chỉ tồn tại trong mọi tình huống tắt nguồn sau khi tôi đã sửa tất cả các lỗi của mình. (Hơn 4000 lần tắt điện vào ban đêm) Nhưng thật khó để tin rằng có một số lỗi trong một số trường hợp. Đặc biệt là khi chúng ta đang nói về tham nhũng bộ nhớ.
TarmoPikaro

0

Tôi thực sự đã đọc rất nhiều câu trả lời tuyệt vời!

Đây là 2 xu của tôi: xây dựng một mô hình thống kê về sự bất thường của bộ nhớ / đăng ký, bằng cách viết một phần mềm để kiểm tra bộ nhớ hoặc để thực hiện so sánh đăng ký thường xuyên. Hơn nữa, tạo một trình giả lập, theo phong cách của một máy ảo nơi bạn có thể thử nghiệm vấn đề. Tôi đoán nếu bạn thay đổi kích thước đường giao nhau, tần số đồng hồ, nhà cung cấp, vỏ, vv sẽ quan sát một hành vi khác.

Ngay cả bộ nhớ máy tính để bàn của chúng tôi cũng có một tỷ lệ thất bại nhất định, tuy nhiên điều đó không làm suy yếu công việc hàng ngày.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.