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

1488
rook 2016-04-25 09:09.

Chúng tôi đang biên dịch một ứng dụng C ++ nhúng được triển khai trong một thiết bị được che chắn trong môi trường bị bức xạ ion hóa bắn phá . 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 và sự cố thường xuyên hơn chúng tôi 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 mà chúng tôi có thể thực hiện đối với mã của mình hoặc các cải tiến về 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 đảo lộ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 hại của lỗi mềm đối với một ứng dụng chạy lâu dài không?

23 answers

828
Ian 2016-04-25 16:58.

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

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

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

Bây giờ, tình trạng này thường được xử lý ở cả cấp độ phần cứng và phần mềm. Ở đây, theo yêu cầu của bạn, 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 / làm mớ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ó đối với bất kỳ phần mềm / phần sụn 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 bao nhiêu tùy thích nhưng tại một thời điểm, tất cả chúng sẽ phát nổ. 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ó đáp ứng, nhiều bản sao, phiên bản tối thiểu của phần mềm / phần sụn trong mã của bạ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, hãy có nhiều bản sao của phiên bản phần mềm / phần sụn tối thiểu của bạn. 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 quản lý nhà của hoạt động cơ bản.
  3. ... sao chép ... ở đâu đó ... Có phần mềm / phần sụn dự phòng ở đâu đó.

    1. Bạn có thể, có hoặc không có phần cứng dư thừa, cố gắng có phần mềm / phần sụn dự phòng trong uC ARM của mình. Đ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 / phần sụn giống hệt nhau ở các địa chỉ riêng biệt gửi nhịp tim cho nhau - nhưng chỉ một phần mềm hoạt động tại một thời điểm. Nếu một hoặc nhiều phần mềm / phần sụn được xác định 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 lỗi xảy ra - mà không cần liên hệ với bất kỳ hệ thống / bên 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 Kiểm soát Sứ mệnh ( MCC)).

      Nói một cách chính xác, 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 lỗ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 lỗi đơn lẻ xuống một điểm mà không cần phần cứng bổ sung sẽ vẫn đáng được xem xét. Hơn nữa, đoạn mã cho việc chuyển đổi chắc chắn sẽ ít hơn nhiều so với đoạn mã cho toàn bộ chương trình - giảm đáng kể nguy cơ nhận được Sự kiện Đơn 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 / phần sụn (trong trường hợp vệ tinh, nó lại là trung tâm điều khiển sứ mệnh).

    3. Bạn cũng có thể có bản sao trong bộ nhớ vĩnh viễn trong thiết bị của mình. Bản sao này 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 sai sót có thể phát hiện được .. Lỗi phải có thể phát hiện được , thường là bằng mạch phát hiện / sửa lỗi phần cứng hoặc bằng một đoạn mã nhỏ để sửa / phát hiện lỗi. Tốt nhất là đặt mã như vậy 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ỉ là kiểm tra / sửa chữa. Nếu mạch / phần sụn phần cứng đáng tin cậy (chẳng hạn như nó cứng hơn bức xạ so với phần còn lại - hoặc có nhiều mạch / logic), thì bạn có thể cân nhắc sửa lỗi với nó. Nhưng nếu không, tốt hơn hết là bạn nên biến nó thành phát hiện lỗi. Việc hiệ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 của bạn. Để phát hiện lỗi, CRC thường được sử dụng.

  5. ... phần cứng hỗ trợ khôi phục Bây giờ, nói đến khía cạnh khó khăn nhất về vấn đề này. Cuối cùng, quá trình khôi phục yêu cầu phần cứng chịu trách nhiệm khôi phục ít nhất phải hoạt độ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ì (đáng buồn là) không có cách nào để phần mềm giúp khôi phục. Do đó, phần cứng đúng là mối quan tâm hàng đầu đối với một thiết bị tiếp xúc với mức bức xạ cao (chẳng hạn như vệ tinh).

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

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

  2. Lọc trong bài đọ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 vị, bộ lọc trung bình hoặc bất kỳ bộ lọc nào khác - không bao giờ tin tưởng vào giá trị đọc đơn lẻ. Mẫu nhiều hơn, không ít hơn - một cách hợp lý.

408
rsjaffe 2016-04-25 09:32.

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

  1. Thường xuyên theo dõi bộ nhớ để tìm lỗi sau đó loại bỏ những lỗi đó,
  2. cơ chế khôi phục lỗi mạnh mẽ và
  3. khả năng cấu hình lại nếu thứ 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 đa bit, vì hầu hết bộ nhớ ECC có thể phục hồi từ lỗi đơn bit chứ không phải lỗi đa bit.

Khôi phục lỗi mạnh mẽ bao gồm chuyển luồng điều khiển (thường khởi động lại 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 nghị chính của họ đối với việc khôi phục 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, để việc khởi động lại trước khi xảy ra lỗi cũng khôi phục dữ liệu về trạng thái đáng tin cậy. Điều này nghe tương tự với 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 thích hợp cho 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 điều kiện trước và điều kiện sau, 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 đúng như vậy, NASA đã sử dụng C ++ cho các dự án lớn như Mars Rover .

Tính trừu tượng và đóng gói của 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 ++ nhất định có thể tạo ra sự cố:

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

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

Sử dụng ROM một cách sáng tạo hơn.

Lưu trữ bất cứ thứ gì bạn có thể vào ROM. Thay vì tính toán mọi thứ, hãy lưu trữ các bảng tra cứu trong ROM. (Đảm bảo 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 địa chỉ bộ nhớ trong thời gian chạy để kiểm tra!) Lưu trữ bảng vectơ ngắt của bạn trong ROM. Tất nhiên, hãy chạy một số bài kiểm tra để 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ì nó là nơi những thứ như biến chỉ mục, biến trạng thái, địa chỉ trả về và con trỏ thuộc nhiều loại khác nhau thường tồn tại.

Thực hiện các quy trình hẹn giờ đánh dấu và bộ đếm thời gian của cơ quan giám sát.

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

Triển khai mã sửa lỗi 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ẽ làm tăng 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, vì vậy bạn phải cân nhắc đánh đổi.

Ghi nhớ các bộ nhớ đệm.

Kiểm tra kích thước của bộ đệm 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ộ nhớ cache. Tôi tin rằng bạn có thể vô hiệu hóa ít nhất một số bộ nhớ đệm (với chi phí hiệu suất lớn); bạn nên thử điều này để xem mức độ nhạy cảm của bộ nhớ cache với SEU. Nếu bộ nhớ đệm 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ó vẫn ở trong bộ nhớ cache và đưa RAM trở lại dòng.

Sử dụng trình 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ó, CPU sẽ gây ra lỗi trang khi bạn cố gắng truy cập trang đó. 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 xử lý yêu cầu đọc. (Hệ điều hành PC sử dụng điều này để tải một cách rõ ràng các trang đã được hoán đổi sang đĩa.)

Sử dụng hợp ngữ cho những thứ quan trọng (có thể là mọi thứ).

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

Sử dụng objdumpđể thực sự xem xét hợp ngữ đã tạo và tìm ra lượng mã mà mỗi quy trình 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 đang gặp rắc rối; chỉ có quá nhiều phức tạp và quá nhiều điều sai sót.

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

Một người bình luận cho biết

Mọi quy trình bạn viết để bắt lỗi sẽ có thể bị lỗi do cùng một nguyên nhân.

Mặc dù điều này đúng, nhưng khả năng xảy ra lỗi trong (giả sử) 100 byte mã và dữ liệu cần thiết để quy trình kiểm tra hoạt động chính xác nhỏ hơn nhiều so với khả năng xảy ra lỗi ở những nơi khác. Nếu ROM của bạn khá đáng tin cậy và hầu 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 các kết quả khác nhau, một thiết lập lại sẽ được kích hoạt. Với 3 thiết bị trở lên, bạn có thể sử dụng hệ thống "bỏ phiếu" để cố gắng xác định thiết bị nào đã bị xâm phạm.

108
Eric Towers 2016-04-25 11:13.

Bạn cũng có thể quan tâm đến tài liệu phong phú về chủ đề khả năng chịu lỗi thuật toán. Điều này bao gồm bài tập cũ: Viết một kiểu sắp xếp chính xác đầu vào của nó khi một số lượng so sánh không đổi sẽ không thành công (hoặc, phiên bản xấu hơn một chút, khi số tiệm cận của các phép so sánh không thành công chia tỷ lệ như log(n)đối với các phép nso sánh).

Một nơi để bắt đầu đọc là bài báo năm 1984 của Huang và Abraham " Khả năng chịu lỗi dựa trên thuật toán cho các phép toán ma trận ". Ý tưởng của họ gần giống với tính toán mã hóa đồng hình (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 hơn của bài báo đó là Bosilca, Delmas, Dongarra, và "Khả năng chịu lỗi dựa trên thuật toán áp dụng cho máy tính hiệu suất cao " của Bosilca, Delmas, Dongarra .

44
Lundin 2016-04-28 04:11.

Viết mã cho môi trường phóng xạ thực sự không khác gì 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 cần có trên bất kỳ hệ thống nhúng bán chuyên nghiệp nào: cơ quan 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 đề cập đến vào năm 2016 và chúng là tiêu chuẩn trên hầu hết mọi bộ 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 của cơ quan giám sát, chẳng hạn như cửa sổ thời gian nhất định, bên trong đó bạn cần phải làm mới cơ quan giám sát. Điều này được ưu tiên nếu bạn có một hệ thống thời gian thực quan trọng.

  • Nói chung, hãy sử dụng MCU phù hợp với những loại hệ thống này, chứ không phải một số loại lông tơ chính thống chung chung mà bạn nhận được trong một gói bột ngô. Hầu hết các nhà sản xuất MCU ngày nay đều có cá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 được tích hợp sẵn, bao gồm cả lõi khóa bướ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 & trạng thái của thiết bị ngoại vi phần cứng có thể ghi được có thể nằm trong bộ nhớ RAM, do đó dễ bị tấn công.

    Để bảo vệ bạn khỏi lỗi thanh ghi, tốt nhất nên chọn một bộ vi điều khiển có tích hợp tính năng "ghi một lần" của 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 thanh ghi của bạn theo các khoảng thời gian đều đặn. 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 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 đăng ký trong MCU chứ không chỉ những đăng ký được ứng dụng sử 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, "mô hình đi bộ", phần mềm ECC, 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, mà sử dụng MCU có ECC tích hợp và kiểm tra tương tự. Bởi vì thực hiện đ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à các 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 "nhân bản" giống hệt nhau, phải luôn tương đương nhau. Mỗi phân đoạn có thể có một tổng kiểm tra CRC được đính kèm.

  • Tránh sử dụng các bộ nhớ bên ngoài bên ngoài MCU.

  • Triển khai một quy trình dịch vụ ngắt mặc định / trình xử lý ngoại lệ mặc định cho tất cả các ngắt / ngoại lệ có thể có. Ngay cả những cái bạn không sử dụng. Quy trình mặc định không nên làm gì ngoại trừ việc tắt nguồn ngắt của chính nó.

  • Hiểu và nắm bắt khái niệm về 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 phải 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 trên lý thuyết. Các ví dụ .

    Phần sụn quan trọng có chất lượng cao phát hiện càng nhiều lỗi càng tốt, sau đó xử lý hoặc 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 đáng kể 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ó những thứ vớ vẩn 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ỏ 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 triển khai bất kỳ sự phụ thuộc nào vào các giá trị mặc định của các biến thời lượng lưu trữ tĩnh. Đó là, không tin tưởng 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ừ thời điểm khởi tạo đến thời điểm biến thực sự được sử dụng, có thể có rất nhiều thời gian để RAM bị hỏng. Thay vào đó, hãy viết chương trình để 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 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ó vô nghĩa, vì dù sao thì 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ự trong C ++, khô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) hàm tạo gọi một quy trình "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, ngay từ ứng dụng trình gọi.

    Nếu có thể, hãy xóa hoàn toàn mã khởi động "copy-down" khởi tạo .data.bss(và gọi các hàm tạo C ++), để bạn nhận được lỗi trình 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à mọi thư viện bên ngoài phải được kiểm tra để chúng không chứa bất kỳ sự phụ thuộc nào như vậy.

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

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

34
supercat 2016-04-26 06:14.

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. Việc 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ư thừa bằng những mẫu mã "hiệu quả hơn" và có thể không có manh mối nào cho thấy lý do mà lập trình viên đang kiểm tra x==42khi trình biên dịch biết rằng không có cách nào xcó thể giữ bất kỳ điều gì khác là vì lập trình viên muốn ngă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ị đó là nếu hệ thống nhận được một số loại trục trặc điện.

Khai báo các biến 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, hãy 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 cách sử dụ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 trạng thái hệ thống được lặp lại sau đó prepare_for_activation(), hệ thống có thể mạnh mẽ chống lại hầu hết mọi sự kiện trục trặc đơn lẻ hợp lý, ngay cả những sự kiện có thể tự ý 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 cuộc gọi đến prepare_for_activation(), điều đó có nghĩa là việc 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ã truy cập prepare_for_activation()không phù hợp, nhưng không có sự kiện trục trặc nào tiếp theo, sẽ không có cách nào để mã tiếp cận sau đó trigger_activation()mà không cần vượt qua kiểm tra xác thực hoặc gọi lệnh hủy_trước_thước [nếu ngăn xếp trục trặc, quá trình thực thi có thể tiếp tục diễn ra tại chỗ ngay trước trigger_activation()khi ngữ cảnh được gọi prepare_for_activation()trả về, nhưng lệnh gọi đến cancel_preparations()sẽ xảy ra giữa các lệnh gọi đến prepare_for_activation()trigger_activation(), do đó làm cho lệnh 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 an toàn 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 đó vì chúng cố gắng chỉ bao gồm mã 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õ ràng và hậu quả của nó cũng sẽ được xác định rõ. Mã có mục đích phát hiện và làm sạch sau khi lỗi, trong một số trường hợp, có thể khiến mọi thứ trở nên tồi tệ hơn. Nếu trình biên dịch xác định rằng việc khôi phục đã cố gắng trong một số trường hợp sẽ gọi hành vi không xác định, thì nó có thể suy ra rằng các điều kiện cần khôi phục như vậy trong những trường hợp đó không thể xảy ra, do đó loại bỏ mã đã kiểm tra chúng.

30
Dmitry Grigoryev 2016-04-26 07:05.

Đâ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 sửa lỗi kịp thời . Dưới đây là một số kỹ thuật bạn có thể sử dụng:

  • dữ liệu hằng số kiểm tra . 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ả thanh ghi phần cứng mà 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 không khớp, đã đến lúc khởi tạo lại hoặc đặt lại.

  • lưu trữ các biến có dư thừa . 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 giám sát luồng chương trình . XOR một cờ toàn cục có giá trị duy nhất trong các chức năng / 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 độ phủ kiểm tra gần 100% sẽ cung cấp cho bạn danh sách các giá trị có thể chấp nhận được của cờ ở cuối chu kỳ. Đặt lại nếu bạn thấy sai lệch.

  • giám sát con trỏ ngăn xếp . Trong phần đầu của 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
OldFrank 2016-04-27 12:41.

Những gì có thể giúp bạn là một cơ quan giám sát . Cơ quan giám sát được sử dụng rộng rãi trong máy tính công nghiệp vào những năm 1980. Lỗi phần cứng 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ỳ đó.

Cơ quan giám sát 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) đến không. TTL hoặc logic khác có thể được sử dụng.

Phần mềm đã được thiết kế để theo dõi thường xuyên hoạt động chính xác của tất cả các hệ thống thiết yếu. Nếu quy 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à sao cho trong các trường hợp bình thường, phần mềm ngăn không cho bộ đếm phần cứng đạt đến 0. Trong trường hợp bộ đếm về 0, phần cứng của bộ đếm sẽ thực hiện nhiệm vụ một và mộ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 một lần nữa.

Cơ quan giám sát này đảm bảo rằng máy tính kèm theo được khởi động lại trong rất nhiều trường hợp bị lỗ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 một chức năng như vậy trên các máy tính hiện nay. Giao diện với phần cứng bên ngoài bây giờ phức tạp hơn rất 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 khả dụng từ khi nó bị lỗi cho đến khi bộ đếm cơ quan giám sát đạt 0 + 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, nhưng thiết bị được hỗ trợ sẽ cần có thể tiến hành mà không cần máy tính điều khiển trong khung thời gian đó.

24
abligh 2016-04-28 05:41.

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 nữa 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ạ coi trọng tính đúng đắn / an toàn hơn tốc độ / chi phí

Một số người đã đề xuất những thay đổi phần cứng mà bạn có thể thực hiện (tốt thôi - có rất nhiều thứ hay ho ở đây trong các 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 là rất tốt), nhưng tôi không nghĩ bất cứ ai đã đề xuất cách dự phòng đó có thể hoạt động trong thực tế. Làm thế nào để bạn thất bại? Làm thế nào để bạn biết khi nào đó đã xảy ra sự cố? 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ó giải quyết. Tuy nhiên, một số công nghệ tính toán phân tán được thiết kế cho quy mô sẽ thất bại (xét cho cùng với quy mô đủ lớn, việc hỏng 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 duy nhấ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 sao chép nlần (trong đó nlớn hơn 2, và tốt hơn là lẻ) và mỗi phần tử phần cứng có thể giao tiếp với nhau 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 khác đơ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 thông thường (ngay cả bộ nguồ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ột 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ừ khả năng lưu trữ ổn định. Do đó, nó sẽ được lưu trữ ở một số nơi.

  • Áp dụng một giao thức số đạ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 cho việc này. Các 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 số đại biểu thay vì tự mình triển khai, nếu không 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 số đại biểu bị treo.

  • Đảm bảo bạn tổng kiểm tra (ví dụ: CRC / SHA) FSM của mình và lưu trữ CRC / SHA trong chính FSM (cũng như truyền trong thông báo và tự kiểm tra tổng thông báo). Yêu cầu 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, các thông báo đến của tổng kiểm tra 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, làm cho các nút tự phát hiện lỗi khởi động lại (điều này tốt hơn là tiếp tục hoạt động một nửa miễn là bạn có đủ nút). Cố gắng để họ tự xóa mình khỏi túc số trong khi khởi động lại trong trường hợp họ không xuất hiện lại. Khi khởi động lại, yêu cầu họ kiểm tra tổng số hình ảnh phần mềm (và bất kỳ 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 mình với túc số.

  • Sử dụng phần cứng để hỗ trợ bạn, nhưng hãy làm như vậy cẩn thận. Chẳng hạn, bạn có thể lấy RAM ECC và thường xuyên đọc / ghi qua nó để sửa lỗi ECC (và hoảng sợ 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 tốt hơn nhiều so với DRAM ngay từ đầu, vì vậy thể tốt hơn là sử dụng DRAM tĩnh để thay thế. Xem điểm đầu tiên trong 'những điều tôi sẽ không làm'.

Giả sử bạn có 1% khả năng thất bại của bất kỳ nút nhất định nào trong vòng một ngày và giả sử bạn có thể thực hiện thất bại hoàn toàn độc lập. Với 5 nút, bạn sẽ cần ba nút để thất bại trong vòng một ngày, đó là 0,00001% cơ hội. Với nhiều hơn nữa, bạn sẽ 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. Trừ khi trọng lượng là vấn đề đáng lo ngại, nếu không, 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 những gì một nhóm lập trình viên có thể nghĩ ra. Khớp nối quang học Ditto của các đầu vào của EMI là một vấn đề, v.v. Dù gì đi nữa, hãy cố gắng tìm nguồn cung cấp các thành phần của bạn để cung cấp nguồn được đánh giá là tốt nhất chống lại bức xạ ion hóa.

  • Lă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ọ. Khả năng chịu lỗi và các thuật toán phân tán rất khó. Sử dụng công việc của người khá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 ngây thơ rằ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 hơn. Nhiều khả năng bạn sẽ sử dụng một đường dẫn mã trong trình biên dịch mà ít được thử nghiệm 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 những người viết phần mềm có tính khả dụng cao phải mô phỏng các chế độ lỗ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ế độ lỗi. Bạn đang ở vị trí 'may mắn' khi thường xuyên gặp 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 rằng ứng dụng của nó thực sự cải thiện MTBF với số lượng vượt quá mức độ phức tạp để giới thiệu nó (với sự phức tạp đi kèm với lỗi). Đặc biệt là áp dụng điều này cho lời khuyên của tôi về thuật toán túc số, v.v.

23
jkflying 2016-04-28 05:32.

Since you specifically ask for software solutions, and you are using C++, why not use operator overloading to make your own, safe datatypes? For example:

Instead of using uint32_t (and double, int64_t etc), make your own SAFE_uint32_t which contains a multiple (minimum of 3) of uint32_t. Overload all of the operations you want (* + - / << >> = == != etc) to perform, and make the overloaded operations perform independently on each internal value, ie don't do it once and copy the result. Both before and after, check that all of the internal values match. If values don't match, you can update the wrong one to the value with the most common one. If there is no most-common value, you can safely notify that there is an error.

This way it doesn't matter if corruption occurs in the ALU, registers, RAM, or on a bus, you will still have multiple attempts and a very good chance of catching errors. Note however though that this only works for the variables you can replace - your stack pointer for example will still be susceptible.

A side story: I ran into a similar issue, also on an old ARM chip. It turned out to be a toolchain which used an old version of GCC that, together with the specific chip we used, triggered a bug in certain edge cases that would (sometimes) corrupt values being passed into functions. Make sure your device doesn't have any problems before blaming it on radio-activity, and yes, sometimes it is a compiler bug =)

16
gaborous 2016-05-02 08:56.

Disclaimer: I'm not a radioactivity professional nor worked for this kind of application. But I worked on soft errors and redundancy for long term archival of critical data, which is somewhat linked (same problem, different goals).

The main problem with radioactivity in my opinion is that radioactivity can switch bits, thus radioactivity can/will tamper any digital memory. These errors are usually called soft errors, bit rot, etc.

The question is then: how to compute reliably when your memory is unreliable?

To significantly reduce the rate of soft errors (at the expense of computational overhead since it will mostly be software-based solutions), you can either:

  • rely on the good old redundancy scheme, and more specifically the more efficient error correcting codes (same purpose, but cleverer algorithms so that you can recover more bits with less redundancy). This is sometimes (wrongly) also called checksumming. With this kind of solution, you will have to store the full state of your program at any moment in a master variable/class (or a struct?), compute an ECC, and check that the ECC is correct before doing anything, and if not, repair the fields. This solution however does not guarantee that your software can work (simply that it will work correctly when it can, or stops working if not, because ECC can tell you if something is wrong, and in this case you can stop your software so that you don't get fake results).

  • or you can use resilient algorithmic data structures, which guarantee, up to a some bound, that your program will still give correct results even in the presence of soft errors. These algorithms can be seen as a mix of common algorithmic structures with ECC schemes natively mixed in, but this is much more resilient than that, because the resiliency scheme is tightly bounded to the structure, so that you don't need to encode additional procedures to check the ECC, and usually they are a lot faster. These structures provide a way to ensure that your program will work under any condition, up to the theoretical bound of soft errors. You can also mix these resilient structures with the redundancy/ECC scheme for additional security (or encode your most important data structures as resilient, and the rest, the expendable data that you can recompute from the main data structures, as normal data structures with a bit of ECC or a parity check which is very fast to compute).

If you are interested in resilient data structures (which is a recent, but exciting, new field in algorithmics and redundancy engineering), I advise you to read the following documents:

  • Resilient algorithms data structures intro by Giuseppe F.Italiano, Universita di Roma "Tor Vergata"

  • Christiano, P., Demaine, E. D., & Kishore, S. (2011). Lossless fault-tolerant data structures with additive overhead. In Algorithms and Data Structures (pp. 243-254). Springer Berlin Heidelberg.

  • Ferraro-Petrillo, U., Grandoni, F., & Italiano, G. F. (2013). Data structures resilient to memory faults: an experimental study of dictionaries. Journal of Experimental Algorithmics (JEA), 18, 1-6.

  • Italiano, G. F. (2010). Resilient algorithms and data structures. In Algorithms and Complexity (pp. 13-24). Springer Berlin Heidelberg.

If you are interested in knowing more about the field of resilient data structures, you can checkout the works of Giuseppe F. Italiano (and work your way through the refs) and the Faulty-RAM model (introduced in Finocchi et al. 2005; Finocchi and Italiano 2008).

/EDIT: I illustrated the prevention/recovery from soft-errors mainly for RAM memory and data storage, but I didn't talk about computation (CPU) errors. Other answers already pointed at using atomic transactions like in databases, so I will propose another, simpler scheme: redundancy and majority vote.

The idea is that you simply do x times the same computation for each computation you need to do, and store the result in x different variables (with x >= 3). You can then compare your x variables:

  • if they all agree, then there's no computation error at all.
  • if they disagree, then you can use a majority vote to get the correct value, and since this means the computation was partially corrupted, you can also trigger a system/program state scan to check that the rest is ok.
  • if the majority vote cannot determine a winner (all x values are different), then it's a perfect signal for you to trigger the failsafe procedure (reboot, raise an alert to user, etc.).

This redundancy scheme is very fast compared to ECC (practically O(1)) and it provides you with a clear signal when you need to failsafe. The majority vote is also (almost) guaranteed to never produce corrupted output and also to recover from minor computation errors, because the probability that x computations give the same output is infinitesimal (because there is a huge amount of possible outputs, it's almost impossible to randomly get 3 times the same, even less chances if x > 3).

So with majority vote you are safe from corrupted output, and with redundancy x == 3, you can recover 1 error (with x == 4 it will be 2 errors recoverable, etc. -- the exact equation is nb_error_recoverable == (x-2) where x is the number of calculation repetitions because you need at least 2 agreeing calculations to recover using the majority vote).

The drawback is that you need to compute x times instead of once, so you have an additional computation cost, but's linear complexity so asymptotically you don't lose much for the benefits you gain. A fast way to do a majority vote is to compute the mode on an array, but you can also use a median filter.

Also, if you want to make extra sure the calculations are conducted correctly, if you can make your own hardware you can construct your device with x CPUs, and wire the system so that calculations are automatically duplicated across the x CPUs with a majority vote done mechanically at the end (using AND/OR gates for example). This is often implemented in airplanes and mission-critical devices (see triple modular redundancy). This way, you would not have any computational overhead (since the additional calculations will be done in parallel), and you have another layer of protection from soft errors (since the calculation duplication and majority vote will be managed directly by the hardware and not by software -- which can more easily get corrupted since a program is simply bits stored in memory...).

9
Graham 2016-04-28 06:09.

One point no-one seems to have mentioned. You say you're developing in GCC and cross-compiling onto ARM. How do you know that you don't have code which makes assumptions about free RAM, integer size, pointer size, how long it takes to do a certain operation, how long the system will run for continuously, or various stuff like that? This is a very common problem.

The answer is usually automated unit testing. Write test harnesses which exercise the code on the development system, then run the same test harnesses on the target system. Look for differences!

Also check for errata on your embedded device. You may find there's something about "don't do this because it'll crash, so enable that compiler option and the compiler will work around it".

In short, your most likely source of crashes is bugs in your code. Until you've made pretty damn sure this isn't the case, don't worry (yet) about more esoteric failure modes.

9
Jonas Byström 2016-04-28 04:16.

You want 3+ slave machines with a master outside the radiation environment. All I/O passes through the master which contains a vote and/or retry mechanism. The slaves must have a hardware watchdog each and the call to bump them should be surrounded by CRCs or the like to reduce the probability of involuntary bumping. Bumping should be controlled by the master, so lost connection with master equals reboot within a few seconds.

One advantage of this solution is that you can use the same API to the master as to the slaves, so redundancy becomes a transparent feature.

Edit: From the comments I feel the need to clarify the "CRC idea." The possibilty of the slave bumping it's own watchdog is close to zero if you surround the bump with CRC or digest checks on random data from the master. That random data is only sent from master when the slave under scrutiny is aligned with the others. The random data and CRC/digest are immediately cleared after each bump. The master-slave bump frequency should be more than double the watchdog timeout. The data sent from the master is uniquely generated every time.

7
ren 2016-04-26 06:40.

How about running many instances of your application. If crashes are due to random memory bit changes, chances are some of your app instances will make it through and produce accurate results. It's probably quite easy (for someone with statistical background) to calculate how many instances do you need given bit flop probability to achieve as tiny overall error as you wish.

7
BЈовић 2016-04-27 02:03.

What you ask is quite complex topic - not easily answerable. Other answers are ok, but they covered just a small part of all the things you need to do.

Biên dịch một ứng dụng để sử dụng trong môi trường phóng xạ cao, it is not possible to fix hardware problems 100%, however it is possible with high probabily to reduce or catch them using various techniques.

If I was you, I would create the software of the highest Safety integrity level level (SIL-4). Get the IEC 61513 document (for the nuclear industry) and follow it.

7
Alex C 2016-04-28 17:34.

Someone mentioned using slower chips to prevent ions from flipping bits as easily. In a similar fashion perhaps use a specialized cpu/ram that actually uses multiple bits to store a single bit. Thus providing a hardware fault tolerance because it would be very unlikely that all of the bits would get flipped. So 1 = 1111 but would need to get hit 4 times to actually flipped. (4 might be a bad number since if 2 bits get flipped its already ambiguous). So if you go with 8, you get 8 times less ram and some fraction slower access time but a much more reliable data representation. You could probably do this both on the software level with a specialized compiler(allocate x amount more space for everything) or language implementation (write wrappers for data structures that allocate things this way). Or specialized hardware that has the same logical structure but does this in the firmware.

7
chill 2016-04-28 21:42.

Perhaps it would help to know does it mean for the hardware to be "designed for this environment". How does it correct and/or indicates the presence of SEU errors ?

At one space exploration related project, we had a custom MCU, which would raise an exception/interrupt on SEU errors, but with some delay, i.e. some cycles may pass/instructions be executed after the one insn which caused the SEU exception.

Particularly vulnerable was the data cache, so a handler would invalidate the offending cache line and restart the program. Only that, due to the imprecise nature of the exception, the sequence of insns headed by the exception raising insn may not be restartable.

We identified the hazardous (not restartable) sequences (like lw $3, 0x0($2), followed by an insn, which modifies $2 and is not data-dependent on $3), and I made modifications to GCC, so such sequences do not occur (e.g. as a last resort, separating the two insns by a nop).

Just something to consider ...

7
Hitul 2016-04-28 04:24.

If your hardware fails then you can use mechanical storage to recover it. If your code base is small and have some physical space then you can use a mechanical data store.

There will be a surface of material which will not be affected by radiation. Multiple gears will be there. A mechanical reader will run on all the gears and will be flexible to move up and down. Down means it is 0 and up means it is 1. From 0 and 1 you can generate your code base.

5
Gerhard 2016-09-23 21:07.

Use a cyclic scheduler. This gives you the ability to add regular maintenance times to check the correctness of critical data. The problem most often encountered is corruption of the stack. If your software is cyclical you can reinitialise the stack between cycles. Do not reuse the stacks for interrupt calls, setup a separate stack of each important interrupt call.

Similar to the Watchdog concept is deadline timers. Start a hardware timer before calling a function. If the function does not return before the deadline timer interrupts then reload the stack and try again. If it still fails after 3/5 tries you need reload from ROM.

Split your software into parts and isolate these parts to use separate memory areas and execution times (Especially in a control environment). Example: signal acquisition, prepossessing data, main algorithm and result implementation/transmission. This means a failure in one part will not cause failures through the rest of the program. So while we are repairing the signal acquisition the rest of tasks continues on stale data.

Everything needs CRCs. If you execute out of RAM even your .text needs a CRC. Check the CRCs regularly if you using a cyclical scheduler. Some compilers (not GCC) can generate CRCs for each section and some processors have dedicated hardware to do CRC calculations, but I guess that would fall out side of the scope of your question. Checking CRCs also prompts the ECC controller on the memory to repair single bit errors before it becomes a problem.

4
MrBigglesworth 2016-05-03 00:47.

Firstly, design your application around failure. Ensure that as part of normal flow operation, it expects to reset (depending on your application and the type of failure either soft or hard). This is hard to get perfect: critical operations that require some degree of transactionality may need to be checked and tweaked at an assembly level so that an interruption at a key point cannot result in inconsistent external commands. Fail fast as soon as any unrecoverable memory corruption or control flow deviation is detected. Log failures if possible.

Secondly, where possible, correct corruption and continue. This means checksumming and fixing constant tables (and program code if you can) often; perhaps before each major operation or on a timed interrupt, and storing variables in structures that autocorrect (again before each major op or on a timed interrupt take a majority vote from 3 and correct if is a single deviation). Log corrections if possible.

Thirdly, test failure. Set up a repeatable test environment that flips bits in memory psuedo-randomly. This will allow you to replicate corruption situations and help design your application around them.

3
Joshua 2016-04-28 08:40.

Given supercat's comments, the tendencies of modern compilers, and other things, I'd be tempted to go back to the ancient days and write the whole code in assembly and static memory allocations everywhere. For this kind of utter reliability I think assembly no longer incurs a large percentage difference of the cost.

1
TarmoPikaro 2016-04-28 21:06.

Here are huge amount of replies, but I'll try to sum up my ideas about this.

Something crashes or does not work correctly could be result of your own mistakes - then it should be easily to fix when you locate the problem. But there is also possibility of hardware failures - and that's difficult if not impossible to fix in overall.

I would recommend first to try to catch the problematic situation by logging (stack, registers, function calls) - either by logging them somewhere into file, or transmitting them somehow directly ("oh no - I'm crashing").

Recovery from such error situation is either reboot (if software is still alive and kicking) or hardware reset (e.g. hw watchdogs). Easier to start from first one.

If problem is hardware related - then logging should help you to identify in which function call problem occurs and that can give you inside knowledge of what is not working and where.

Also if code is relatively complex - it makes sense to "divide and conquer" it - meaning you remove / disable some function calls where you suspect problem is - typically disabling half of code and enabling another half - you can get "does work" / "does not work" kind of decision after which you can focus into another half of code. (Where problem is)

If problem occurs after some time - then stack overflow can be suspected - then it's better to monitor stack point registers - if they constantly grows.

And if you manage to fully minimize your code until "hello world" kind of application - and it's still failing randomly - then hardware problems are expected - and there needs to be "hardware upgrade" - meaning invent such cpu / ram / ... -hardware combination which would tolerate radiation better.

Most important thing is probably how you get your logs back if machine fully stopped / resetted / does not work - probably first thing bootstap should do - is a head back home if problematic situation is entcovered.

If it's possible in your environment also to transmit a signal and receive response - you could try out to construct some sort of online remote debugging environment, but then you must have at least of communication media working and some processor/ some ram in working state. And by remote debugging I mean either GDB / gdb stub kind of approach or your own implementation of what you need to get back from your application (e.g. download log files, download call stack, download ram, restart)

0
Noname 2018-03-08 08:41.

I've really read a lot of great answers!

Here is my 2 cent: build a statistical model of the memory/register abnormality, by writing a software to check the memory or to perform frequent register comparisons. Further, create an emulator, in the style of a virtual machine where you can experiment with the issue. I guess if you vary junction size, clock frequency, vendor, casing, etc would observe a different behavior.

Even our desktop PC memory has a certain rate of failure, which however doesn't impair the day to day work.

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Thời gian, sự kiên nhẫn, thời gian, sự cống hiến và thời gian chỉ là một vài trong số những thứ mà Peter Bellerby cần để thành lập và sau đó điều hành Bellerby & Co. Globemakers, một trong những công ty duy nhất trên Trái đất vẫn sản xuất các quả địa cầu bằng tay.

Năm giai đoạn đau buồn sau khi mất việc làm

Năm giai đoạn đau buồn sau khi mất việc làm

Đó là một ngày thứ Bảy, máy bay của tôi hạ cánh, và tôi đã sẵn sàng để thư giãn trong một kỳ nghỉ cuối tuần ngắn ngủi, khi một email đến trên điện thoại của tôi. Tôi đã mất việc.

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Nếu bạn đã từng bị đánh cắp danh tính của mình, bạn biết đó là một trải nghiệm đáng sợ và căng thẳng. Một cách không phổ biến để ngăn chặn nó? Tín dụng bị đóng băng.

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Eleanor (Kristen Bell) dường như đã tình nguyện cho chúng tôi làm vật tưởng nhớ. NBC's The Good Place là một chương trình thích thử thách tốt.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language