etc./StackOverFlow

고방사성 환경에서 사용하기 위한 애플리케이션 컴파일

청렴결백한 만능 재주꾼 2022. 2. 27. 12:39
반응형

질문자 :rook


우리는 이온화 방사선에 노출 된 환경에서 차폐 장치에 배포되는 임베디드 C++ 응용 프로그램을 컴파일하고 있습니다. ARM용으로 GCC와 크로스 컴파일을 사용하고 있습니다. 배포될 때 애플리케이션은 일부 잘못된 데이터를 생성하고 우리가 원하는 것보다 더 자주 충돌합니다. 하드웨어는 이 환경을 위해 설계되었으며 우리 애플리케이션은 이 플랫폼에서 몇 년 동안 실행되었습니다.

단일 이벤트 업셋으로 인한 소프트 오류 및 메모리 손상을 식별/수정하기 위해 코드를 변경할 수 있거나 컴파일 시간을 개선할 수 있습니까? 장기 실행 애플리케이션에서 소프트 오류의 유해한 영향을 줄이는 데 성공한 다른 개발자가 있습니까?



약 4-5년 동안 소프트웨어/펌웨어 개발 및 소형 위성 의 환경 테스트를 수행한 * 경험을 여기에서 공유하고 싶습니다.

*( 소형 위성은 상대적으로 작고 제한된 전자 부품 크기로 인해 대형 위성보다 단일 이벤트 업셋에 훨씬 더 취약합니다 )

매우 간결하고 직접적으로: 복구 목적을 위해 어딘가에 최소 작동 버전 의 소프트웨어/펌웨어 사본 한 개 이상 없이 소프트웨어/펌웨어 자체에 의해 감지 가능한 오류 상황 에서 복구할 수 있는 메커니즘이 없습니다. 그리고 하드웨어 지원 회복 (기능).

이제 이 상황은 일반적으로 하드웨어 및 소프트웨어 수준에서 모두 처리됩니다. 여기에서 귀하의 요청에 따라 소프트웨어 수준에서 수행할 수 있는 작업을 공유하겠습니다.

  1. ...복구 목적... . 실제 환경에서 소프트웨어/펌웨어를 업데이트/재컴파일/다시 플래시하는 기능을 제공합니다. 이것은 고도로 이온화된 환경에서 모든 소프트웨어/펌웨어에 대해 거의 필수 기능입니다. 이것이 없으면 원하는 만큼 중복 소프트웨어/하드웨어를 가질 수 있지만 어느 시점에서 모두 폭발하게 될 것입니다. 따라서 이 기능을 준비하십시오!

  2. ...최소 작업 버전... 코드에 반응형, 다중 사본, 최소 버전의 소프트웨어/펌웨어가 있어야 합니다. 이것은 Windows의 안전 모드와 같습니다. 완전한 기능의 소프트웨어 버전을 하나만 보유하는 대신 소프트웨어/펌웨어의 최소 버전 사본을 여러 개 보유하십시오. 최소 사본은 일반적으로 전체 사본보다 크기가 훨씬 작으며 거의 항상 다음 두 가지 또는 세 가지 기능 만 있습니다.

    1. 외부 시스템의 명령을 들을 수 있는
    2. 현재 소프트웨어/펌웨어 업데이트 가능,
    3. 기본 작업의 하우스키핑 데이터를 모니터링할 수 있습니다.
  3. ...복사... 어딘가에... 중복 소프트웨어/펌웨어가 어딘가에 있습니다.

    1. 당신은, 또는 여분의 하드웨어없이, 당신의 ARM uc에에 중복 소프트웨어 / 펌웨어를 시도 할 수 있습니다. 이것은 일반적으로 서로에게 하트비트를 보내는 두 개 이상의 동일한 소프트웨어/펌웨어 를 별도의 주소 에 두어 수행되지만 한 번에 하나만 활성화됩니다. 하나 이상의 소프트웨어/펌웨어가 응답하지 않는 것으로 알려진 경우 다른 소프트웨어/펌웨어로 전환하십시오. 이 접근 방식을 사용하면 오류가 발생한 직후 기능을 교체할 수 있다는 이점이 있습니다. 오류를 감지하고 수리할 책임이 있는 외부 시스템/당사자와의 접촉 없이(위성의 경우 일반적으로 Mission Control Center( MCC)).

      엄밀히 말하면 중복 하드웨어가 없으면 이 작업의 단점은 실제로 모든 단일 실패 지점을 제거 할 수 없다는 것입니다. 최소한 스위치 자체 (또는 종종 코드의 시작 부분)인 단일 실패 지점 이 하나 남아 있습니다. 그럼에도 불구하고 고도로 이온화된 환경(예: 피코/펨토 위성)에서 크기가 제한된 장치의 경우 추가 하드웨어 없이 단일 장애 지점을 한 지점으로 줄이는 것은 여전히 고려할 가치가 있습니다. 또한 전환을 위한 코드 조각은 전체 프로그램에 대한 코드보다 확실히 훨씬 적어서 단일 이벤트가 발생할 위험이 크게 줄어듭니다.

    2. 그러나 이렇게 하지 않는 경우 외부 시스템에 장치와 접촉하여 소프트웨어/펌웨어를 업데이트할 수 있는 복사본이 하나 이상 있어야 합니다(위성의 경우 다시 임무 제어 센터임).

    3. 실행 중인 시스템의 소프트웨어/펌웨어를 복원하기 위해 트리거될 수 있는 장치의 영구 메모리 저장소에 복사본을 가질 수도 있습니다.
  4. ...검출 가능한 오류 상황.. 일반적으로 하드웨어 오류 수정/검출 회로 또는 오류 수정/검출을 위한 작은 코드 조각에 의해 오류를 감지할 수 있어야 합니다. 이러한 코드는 작고, 여러 개이며, 주요 소프트웨어/펌웨어 와 독립적으로 두는 것이 가장 좋습니다. 주요 업무는 확인/수정 뿐입니다. 하드웨어 회로/펌웨어가 신뢰할 수 있는 경우 (예: 나머지보다 방사선 경화가 더 심하거나 여러 회로/로직이 있는 경우) 이를 사용하여 오류 수정을 고려할 수 있습니다. 그러나 그렇지 않은 경우 오류 감지로 만드는 것이 좋습니다. 수정은 외부 시스템/장치에 의해 수행될 수 있습니다. 오류 정정을 위해 Hamming/Golay23과 같은 기본 오류 정정 알고리즘을 사용하는 것을 고려할 수 있습니다. 회로/소프트웨어 모두에서 더 쉽게 구현할 수 있기 때문입니다. 그러나 그것은 궁극적으로 팀의 능력에 달려 있습니다. 오류 감지를 위해 일반적으로 CRC가 사용됩니다.

  5. ...복구를 지원하는 하드웨어 이제 이 문제에서 가장 어려운 부분이 나옵니다. 궁극적으로 복구를 위해서는 복구를 담당하는 하드웨어가 최소한 작동해야 합니다. 하드웨어가 영구적으로 고장난 경우(일반적으로 총 이온화량이 특정 수준에 도달한 후에 발생) 소프트웨어가 복구를 도울 방법이 (슬프게도) 없습니다. 따라서 하드웨어는 높은 방사선 수준(예: 위성)에 노출되는 장치의 가장 중요한 관심사입니다.

위의 단일 이벤트 업셋으로 인한 펌웨어 오류 예상에 대한 제안 외에도 다음 사항을 제안하고 싶습니다.

  1. 하위 시스템 간 통신 프로토콜의 오류 감지 및/또는 오류 수정 알고리즘. 이것은 다른 시스템에서 수신된 불완전하거나 잘못된 신호를 피하기 위해 거의 있어야 하는 또 다른 것입니다.

  2. ADC 판독값을 필터링합니다. 직접 읽는 ADC를 사용하지 마십시오. 중앙값 필터, 평균 필터 또는 기타 필터로 필터링하십시오. 단일 판독 값을 절대 신뢰하지 마십시오. 합리적으로 더 많이, 더 적게 샘플링하십시오.


Ian

NASA는 방사선 경화 소프트웨어에 대한 논문을 가지고 있습니다. 여기에는 세 가지 주요 작업이 설명되어 있습니다.

  1. 오류가 있는지 메모리를 정기적으로 모니터링한 다음 해당 오류를 제거합니다.
  2. 강력한 오류 복구 메커니즘 및
  3. 더 이상 작동하지 않는 경우 재구성하는 기능.

대부분의 ECC 메모리는 다중 비트 오류가 아닌 단일 비트 오류에서 복구할 수 있으므로 메모리 스캔 속도는 다중 비트 오류가 거의 발생하지 않을 만큼 충분히 빈번해야 합니다.

강력한 오류 복구에는 제어 흐름 전송(일반적으로 오류 이전 지점에서 프로세스 다시 시작), 리소스 해제 및 데이터 복원이 포함됩니다.

데이터 복원에 대한 주요 권장 사항은 중간 데이터를 임시 데이터로 처리하여 오류가 발생하기 전에 다시 시작할 때 데이터가 신뢰할 수 있는 상태로 롤백되도록 하여 필요를 피하는 것입니다. 이것은 데이터베이스의 "트랜잭션" 개념과 유사하게 들립니다.

그들은 C++와 같은 객체 지향 언어에 특히 적합한 기술에 대해 논의합니다. 예를 들어

  1. 연속 메모리 개체를 위한 소프트웨어 기반 ECC
  2. 계약에 의한 프로그래밍 : 사전 조건과 사후 조건을 확인한 다음 객체를 확인하여 여전히 유효한 상태인지 확인합니다.

그리고 NASA는 Mars Rover 와 같은 주요 프로젝트에 C++를 사용했습니다.

C++ 클래스 추상화 및 캡슐화를 통해 여러 프로젝트와 개발자 간의 신속한 개발 및 테스트가 가능했습니다.

그들은 문제를 일으킬 수 있는 특정 C++ 기능을 피했습니다.

  1. 예외
  2. 템플릿
  3. Iostream(콘솔 없음)
  4. 다중 상속
  5. 연산자 오버로딩( newdelete 제외)
  6. 동적 할당(시스템 힙 손상 가능성을 피하기 위해 전용 메모리 풀 및 new

rsjaffe

다음은 몇 가지 생각과 아이디어입니다.

ROM을 더 창의적으로 사용하십시오.

ROM에 가능한 모든 것을 저장하십시오. 계산하는 대신 ROM에 조회 테이블을 저장하십시오. (컴파일러가 조회 테이블을 읽기 전용 섹션으로 출력하고 있는지 확인하십시오! 확인하려면 런타임에 메모리 주소를 인쇄하십시오!) 인터럽트 벡터 테이블을 ROM에 저장하십시오. 물론 ROM이 RAM과 비교하여 얼마나 안정적인지 확인하기 위해 몇 가지 테스트를 실행합니다.

스택에 가장 적합한 RAM을 사용하십시오.

스택의 SEU는 일반적으로 다양한 종류의 인덱스 변수, 상태 변수, 반환 주소 및 포인터와 같은 항목이 있는 곳이므로 충돌의 가장 가능성 있는 소스일 것입니다.

타이머 틱 및 워치독 타이머 루틴을 구현합니다.

타이머 틱마다 "온전성 검사" 루틴과 시스템 잠금을 처리하는 워치독 루틴을 실행할 수 있습니다. 메인 코드는 진행 상황을 나타내기 위해 주기적으로 카운터를 증가시킬 수 있으며 온전성 검사 루틴은 이것이 발생했는지 확인할 수 있습니다.

소프트웨어에서 오류 수정 코드 를 구현합니다.

데이터에 중복성을 추가하여 오류를 감지 및/또는 수정할 수 있습니다. 이렇게 하면 처리 시간이 추가되어 잠재적으로 프로세서가 더 오랜 시간 동안 방사선에 노출되어 오류 가능성이 증가하므로 절충안을 고려해야 합니다.

캐시를 기억하십시오.

CPU 캐시의 크기를 확인하십시오. 최근에 액세스하거나 수정한 데이터는 캐시에 있을 것입니다. 적어도 일부 캐시를 비활성화할 수 있다고 생각합니다(큰 성능 비용으로). 캐시가 SEU에 얼마나 민감한지 확인하려면 이것을 시도해야 합니다. 캐시가 RAM보다 하드한 경우 중요한 데이터를 정기적으로 읽고 다시 작성하여 캐시에 남아 있는지 확인하고 RAM을 다시 라인으로 가져올 수 있습니다.

페이지 폴트 핸들러를 현명하게 사용하십시오.

메모리 페이지를 존재하지 않는 것으로 표시하면 액세스를 시도할 때 CPU가 페이지 폴트를 발생시킵니다. 읽기 요청을 처리하기 전에 몇 가지 검사를 수행하는 페이지 오류 처리기를 만들 수 있습니다. (PC 운영 체제는 이것을 사용하여 디스크로 스왑된 페이지를 투명하게 로드합니다.)

중요한 것(모든 것이 될 수 있음)에 어셈블리 언어를 사용하십시오.

어셈블리 언어를 사용하면 레지스터에 무엇이 있고 RAM에 무엇이 있는지 알 수 있습니다. CPU가 사용하는 특수 RAM 테이블이 무엇인지 알고 있으며 위험을 줄이기 위해 우회적으로 설계할 수 있습니다.

objdump 를 사용하여 생성된 어셈블리 언어를 실제로 살펴보고 각 루틴이 차지하는 코드의 양을 계산하십시오.

Linux와 같은 큰 OS를 사용하는 경우 문제가 발생합니다. 너무 복잡하고 잘못될 일이 너무 많습니다.

확률 게임이라는 것을 기억하십시오.

한 댓글 작성자가 말했습니다.

오류를 잡기 위해 작성하는 모든 루틴은 동일한 원인으로 인해 자체적으로 실패할 수 있습니다.

이것이 사실이지만 검사 루틴이 올바르게 작동하는 데 필요한 100바이트 코드 및 데이터의 오류 가능성은 다른 곳의 오류 가능성보다 훨씬 적습니다. ROM이 매우 안정적이고 거의 모든 코드/데이터가 실제로 ROM에 있으면 확률이 훨씬 더 높아집니다.

중복 하드웨어를 사용합니다.

동일한 코드로 2개 이상의 동일한 하드웨어 설정을 사용합니다. 결과가 다르면 재설정이 트리거되어야 합니다. 3개 이상의 장치에서 "투표" 시스템을 사용하여 손상된 장치를 식별할 수 있습니다.


Artelius

알고리즘 내결함성 주제에 대한 풍부한 문헌에도 관심이 있을 수 있습니다. 여기에는 이전 할당이 포함됩니다. 일정한 수의 비교가 실패할 때 입력을 올바르게 정렬하는 정렬을 작성하십시오(또는 실패한 비교의 점근적 수가 n 비교에 대해 log(n)

읽기 시작하는 곳은 Huang과 Abraham의 1984년 논문 " Algorithm-Based Fault Tolerance for Matrix Operations "입니다. 그들의 아이디어는 동형 암호화된 계산과 모호하게 유사합니다(그러나 작업 수준에서 오류 감지/수정을 시도하기 때문에 실제로 동일하지는 않습니다).

그 논문의 더 최근의 후예는 Bosilca, Delmas, Dongarra 및 Langou의 " 고성능 컴퓨팅에 적용된 알고리즘 기반 내결함성 "입니다.


Eric Towers

방사능 환경에 대한 코드 작성은 업무상 중요한 응용 프로그램에 대한 코드 작성과 실제로 다르지 않습니다.

이미 언급한 것 외에도 다음은 몇 가지 기타 팁입니다.

  • 내부 감시, 내부 저전압 감지, 내부 클록 모니터와 같은 준전문가 임베디드 시스템에 있어야 하는 일상적인 "빵과 버터" 안전 조치를 사용합니다. 이러한 것들은 2016년에 언급할 필요도 없으며 거의 모든 최신 마이크로컨트롤러의 표준입니다.

  • 안전 및/또는 자동차 지향 MCU가 있는 경우 지정된 시간 창과 같은 특정 워치독 기능이 있으며 이 내부에서 워치독을 새로 고쳐야 합니다. 미션 크리티컬한 실시간 시스템이 있는 경우 선호됩니다.

  • 일반적으로 이러한 종류의 시스템에 적합한 MCU를 사용하고 콘플레이크 한 묶음에 들어 있는 일반적인 주류 플러프가 아닙니다. 오늘날 거의 모든 MCU 제조업체에는 안전 애플리케이션(TI, Freescale, Renesas, ST, Infineon 등)용으로 설계된 특수 MCU가 있습니다. 여기에는 잠금 단계 코어를 포함하여 내장된 많은 안전 기능이 있습니다. 즉, 동일한 코드를 실행하는 2개의 CPU 코어가 있으며 서로 동의해야 합니다.

  • 중요: 내부 MCU 레지스터의 무결성을 보장해야 합니다. 쓰기 가능한 하드웨어 주변 장치의 모든 제어 및 상태 레지스터는 RAM 메모리에 위치할 수 있으므로 취약합니다.

    레지스터 손상으로부터 자신을 보호하려면 레지스터의 "한 번 쓰기" 기능이 내장된 마이크로컨트롤러를 선택하는 것이 좋습니다. 또한 모든 하드웨어 레지스터의 기본값을 NVM에 저장하고 해당 값을 정기적으로 레지스터에 복사해야 합니다. 동일한 방식으로 중요한 변수의 무결성을 보장할 수 있습니다.

    참고: 항상 방어적 프로그래밍을 사용하십시오. 이는 애플리케이션에서 사용하는 레지스터뿐만 아니라 MCU의 모든 레지스터를 설정해야 함을 의미합니다. 임의의 하드웨어 주변 장치가 갑자기 깨어나는 것을 원하지 않습니다.

  • RAM 또는 NVM의 오류를 확인하는 모든 종류의 방법이 있습니다: 체크섬, "워킹 패턴", 소프트웨어 ECC 등. 오늘날 가장 좋은 솔루션은 이들 중 어느 것도 사용하지 않고 내장형 ECC 및 유사한 검사. 소프트웨어에서 이 작업을 수행하는 것은 복잡하고 오류 검사 자체가 버그와 예상치 못한 문제를 일으킬 수 있기 때문입니다.

  • 이중화를 사용합니다. 항상 동일해야 하는 두 개의 동일한 "미러" 세그먼트에 휘발성 및 비휘발성 메모리를 모두 저장할 수 있습니다. 각 세그먼트에는 CRC 체크섬이 첨부될 수 있습니다.

  • MCU 외부의 외부 메모리를 사용하지 마십시오.

  • 가능한 모든 인터럽트/예외에 대해 기본 인터럽트 서비스 루틴/기본 예외 핸들러를 구현합니다. 당신이 사용하지 않는 것들조차도. 기본 루틴은 자체 인터럽트 소스를 차단하는 것 외에는 아무 것도 하지 않아야 합니다.

  • 방어적 프로그래밍의 개념을 이해하고 수용합니다. 이것은 프로그램이 이론상 발생할 수 없는 경우를 포함하여 가능한 모든 경우를 처리해야 함을 의미합니다. .

    고품질 미션 크리티컬 펌웨어는 가능한 한 많은 오류를 감지한 다음 안전한 방식으로 처리하거나 무시합니다.

  • 잘못 지정된 동작에 의존하는 프로그램을 작성하지 마십시오. 이러한 동작은 방사 또는 EMI로 인한 예기치 않은 하드웨어 변경으로 인해 크게 변경될 수 있습니다. 프로그램에 이러한 쓰레기가 없는지 확인하는 가장 좋은 방법은 정적 분석 도구와 함께 MISRA와 같은 코딩 표준을 사용하는 것입니다. 이것은 또한 방어적인 프로그래밍과 버그 제거에 도움이 될 것입니다.

  • 중요: 정적 저장 기간 변수의 기본값에 의존하지 마십시오. .data 또는 .bss 의 기본 내용을 신뢰하지 마십시오. 초기화 시점과 변수가 실제로 사용되는 시점 사이에 시간이 얼마든지 있을 수 있으며 RAM이 손상될 수 있는 충분한 시간이 있을 수 있습니다. 대신, 그러한 변수가 처음으로 사용되기 직전인 런타임에 모든 변수가 NVM에서 설정되도록 프로그램을 작성하십시오.

    실제로 이것은 변수가 파일 범위에서 선언되거나 static = 를 사용해서는 안 된다는 것을 의미합니다(또는 초기화할 수는 있지만 값에 의존할 수 없기 때문에 의미가 없습니다). 항상 사용 직전에 런타임에 설정하십시오. NVM에서 이러한 변수를 반복적으로 업데이트할 수 있다면 그렇게 하십시오.

    마찬가지로 C++에서 정적 저장 기간 변수에 대해 생성자에 의존하지 마십시오. 생성자가 공개 "설정" 루틴을 호출하도록 하십시오. 나중에 런타임에 호출자 응용 프로그램에서 직접 호출할 수도 있습니다.

    .data.bss (및 C++ 생성자 호출)를 초기화하는 "복사 다운" 시작 코드를 완전히 제거하여 이에 의존하는 코드를 작성할 때 링커 오류가 발생하도록 하십시오. 많은 컴파일러에는 일반적으로 "최소/빠른 시작" 또는 이와 유사한 항목을 건너뛸 수 있는 옵션이 있습니다.

    이는 외부 라이브러리가 그러한 의존성을 포함하지 않도록 확인해야 함을 의미합니다.

  • 심각한 오류가 발생한 경우 되돌릴 수 있는 프로그램의 안전한 상태를 구현하고 정의합니다.

  • 오류 보고/오류 로그 시스템을 구현하는 것은 항상 도움이 됩니다.


Lundin

C를 사용하여 그러한 환경에서 강력하게 작동하는 프로그램을 작성하는 것이 가능할 수도 있지만 대부분의 컴파일러 최적화 형태가 비활성화된 경우에만 가능합니다. 최적화 컴파일러는 겉보기에 중복되는 많은 코딩 패턴을 "더 효율적인" 코딩 패턴으로 대체하도록 설계되었으며 x 가 다른 어떤 것도 보유할 수 없다는 것을 알 때 x==42 x 가 다른 값을 보유하는 특정 코드의 실행을 방지하기를 원합니다. 시스템이 일종의 전기적 결함을 수신하는 경우에만 해당 값을 보유할 수 있는 경우에도 마찬가지입니다.

변수를 volatile 선언하는 것은 종종 도움이 되지만 만병통치약은 아닙니다. 특히 중요한 점은 안전한 코딩을 위해서는 위험한 작업에 여러 단계를 활성화해야 하는 하드웨어 인터록이 있어야 하며 해당 코드는 다음 패턴을 사용하여 작성해야 한다는 것입니다.

 ... 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();

컴파일러가 비교적 리터럴 방식으로 코드를 번역하고 prepare_for_activation() 이후에 시스템 상태에 대한 모든 검사가 반복되면 시스템은 프로그램 카운터를 임의로 손상시키는 거의 모든 가능한 단일 글리치 이벤트에 대해 견고할 수 있습니다. 스택. 글리치 단지를 호출 한 후 발생하는 경우 prepare_for_activation() (다른 이유가 없기 때문에, 그는 활성화가되어 적절한있을 것입니다 의미하는 것이다 prepare_for_activation() 글리치 전에 호출 된 것)가. 결함으로 인해 코드가 prepare_for_activation() 부적절하게 도달하지만 후속 결함 이벤트가 없는 경우 유효성 검사를 통과하거나 먼저 cancel_preparations를 호출하지 않고 trigger_activation() prepare_for_activation() 을 호출한 컨텍스트가 반환된 trigger_activation() 직전의 지점으로 진행될 수 cancel_preparations() prepare_for_activation()trigger_activation() 대한 호출 사이에 발생하여 후자의 호출을 무해하게 만듭니다.

이러한 코드는 전통적인 C에서는 안전할 수 있지만 최신 C 컴파일러에서는 그렇지 않습니다. 그러한 컴파일러는 잘 정의된 메커니즘을 통해 발생할 수 있고 결과 결과도 잘 정의될 상황과 관련이 있는 코드만 포함하려고 공격적으로 노력하기 때문에 이러한 종류의 환경에서 매우 위험할 수 있습니다. 오류를 감지하고 정리하는 것이 목적인 코드는 경우에 따라 상황을 악화시킬 수 있습니다. 컴파일러가 시도한 복구가 어떤 경우에는 정의되지 않은 동작을 호출한다고 판단하면 그러한 경우에 이러한 복구를 필요로 하는 조건이 발생할 수 없다고 추론하여 이를 검사했을 코드를 제거할 수 있습니다.


supercat

이것은 매우 광범위한 주제입니다. 기본적으로 메모리 손상에서 실제로 복구할 수는 없지만 최소한 즉시 실패를 시도할 수는 있습니다. 다음은 사용할 수 있는 몇 가지 기술입니다.

  • 체크섬 상수 데이터 . 오랫동안 일정하게 유지되는 구성 데이터(구성한 하드웨어 레지스터 포함)가 있는 경우 초기화 시 체크섬을 계산하고 주기적으로 확인합니다. 불일치가 보이면 다시 초기화하거나 재설정해야 합니다.

  • 중복으로 변수를 저장합니다 . 중요한 변수 x 가 있으면 그 값을 x1 , x2x3 (x1 == x2) ? x2 : x3 .

  • 프로그램 흐름 모니터링을 구현합니다. 메인 루프에서 호출되는 중요한 기능/분기에서 고유한 값을 가진 전역 플래그를 XOR합니다. 테스트 범위가 거의 100%인 방사선이 없는 환경에서 프로그램을 실행하면 주기가 끝날 때 허용되는 플래그 값 목록이 제공됩니다. 편차가 보이면 재설정하십시오.

  • 스택 포인터를 모니터링합니다 . 메인 루프의 시작 부분에서 스택 포인터를 예상 값과 비교합니다. 편차 시 재설정합니다.


Dmitry Grigoryev

당신을 도울 수 있는 것은 감시견 입니다. 워치독은 1980년대 산업 컴퓨팅에서 광범위하게 사용되었습니다. 하드웨어 오류는 그 때보다 훨씬 더 일반적이었습니다. 또 다른 답변은 해당 기간을 나타냅니다.

워치독은 결합된 하드웨어/소프트웨어 기능입니다. 하드웨어는 숫자(예: 1023)에서 0까지 카운트다운하는 간단한 카운터입니다. TTL 또는 다른 논리를 사용할 수 있습니다.

소프트웨어는 하나의 루틴이 모든 필수 시스템의 올바른 작동을 모니터링하도록 설계되었습니다. 이 루틴이 올바르게 완료되면 = 컴퓨터가 정상적으로 실행되고 있음을 발견하면 카운터를 다시 1023으로 설정합니다.

전반적인 디자인은 정상적인 상황에서 소프트웨어가 하드웨어 카운터가 0에 도달하는 것을 방지하도록 되어 있습니다. 카운터가 0에 도달하면 카운터의 하드웨어는 유일한 작업을 수행하고 전체 시스템을 재설정합니다. 카운터 관점에서 0은 1024와 같고 카운터는 계속해서 다시 카운트다운합니다.

이 워치독은 연결된 컴퓨터가 많은 실패 사례에서 다시 시작되도록 합니다. 나는 오늘날의 컴퓨터에서 그러한 기능을 수행할 수 있는 하드웨어에 익숙하지 않다는 것을 인정해야 합니다. 외부 하드웨어에 대한 인터페이스는 이제 예전보다 훨씬 더 복잡해졌습니다.

워치독의 고유한 단점은 시스템이 실패한 시간부터 워치독 카운터가 0 + 재부팅 시간에 도달할 때까지 시스템을 사용할 수 없다는 것입니다. 그 시간은 일반적으로 외부 또는 사람의 개입보다 훨씬 짧지만 지원되는 장비는 해당 기간 동안 컴퓨터 제어 없이 진행할 수 있어야 합니다.


OldFrank

이 답변은 최소 비용 또는 빠른 시스템을 갖는 것 이상으로 올바르게 작동하는 시스템을 갖는 데 관심이 있다고 가정합니다. 방사성 물질을 가지고 노는 대부분의 사람들은 속도/비용보다 정확성/안전을 중시합니다.

여러 사람들이 당신이 할 수 있는 하드웨어 변경을 제안했고(좋아요 - 여기에 이미 답변에 좋은 것들이 많이 있으며 모든 것을 반복할 생각은 없습니다), 다른 사람들은 중복성(원칙적으로 훌륭함)을 제안했지만 제 생각에는 그렇게 생각하지 않습니다. 누군가가 중복성이 실제로 어떻게 작동하는지 제안했습니다. 어떻게 실패합니까? '잘못된'일이 언제인지 어떻게 알 수 있습니까? 많은 기술은 모든 것이 제대로 작동한다는 것을 기반으로 작동하므로 실패는 다루기 까다로운 문제입니다. 그러나 확장을 위해 설계된 일부 분산 컴퓨팅 기술은 실패를 예상합니다 (결국 충분한 확장이 있으면 단일 노드에 대한 모든 MTBF에서 많은 노드 중 하나의 노드 오류가 불가피함). 이를 환경에 활용할 수 있습니다.

다음은 몇 가지 아이디어입니다.

  • 전체 하드웨어가 nn 은 2보다 크며 가급적이면 홀수임) 각 하드웨어 요소가 서로 다른 하드웨어 요소와 통신할 수 있는지 확인하십시오. 이더넷은 이를 수행하는 한 가지 확실한 방법이지만 더 나은 보호를 제공하는 훨씬 더 간단한 경로(예: CAN)가 많이 있습니다. 공통 구성 요소(전원 공급 장치 포함)를 최소화합니다. 이것은 예를 들어 여러 위치에서 ADC 입력을 샘플링하는 것을 의미할 수 있습니다.

  • 애플리케이션 상태가 유한 상태 머신과 같은 단일 위치에 있는지 확인하십시오. 이것은 안정적인 저장을 배제하지 않지만 전적으로 RAM 기반일 수 있습니다. 따라서 여러 장소에 저장됩니다.

  • 상태 변경에 대한 쿼럼 프로토콜을 채택합니다. 예를 들어 RAFT 를 참조하십시오. C++에서 작업할 때 이에 대한 잘 알려진 라이브러리가 있습니다. FSM에 대한 변경은 대다수의 노드가 동의할 때만 이루어집니다. 프로토콜 스택과 쿼럼 프로토콜에 대해 스스로 롤링하는 대신 알려진 좋은 라이브러리를 사용하십시오. 그렇지 않으면 쿼럼 프로토콜이 중단될 때 중복성에 대한 모든 좋은 작업이 낭비됩니다.

  • FSM을 체크섬(예: CRC/SHA)하고 FSM 자체에 CRC/SHA를 저장해야 합니다(메시지에서 전송하고 메시지 자체에서 체크섬 포함). 노드가 이러한 체크섬에 대해 정기적으로 FSM을 확인하고 들어오는 메시지를 체크섬하고 체크섬이 쿼럼의 체크섬과 일치하는지 확인합니다.

  • 가능한 한 많은 다른 내부 검사를 시스템에 구축하여 자체 실패 재부팅을 감지하는 노드를 만듭니다(노드가 충분하다면 절반 작업을 수행하는 것보다 낫습니다). 다시 나타나지 않을 경우를 대비하여 재부팅하는 동안 쿼럼에서 완전히 제거되도록 하십시오. 재부팅 시 소프트웨어 이미지(및 로드하는 다른 모든 항목)를 체크섬하고 전체 RAM 테스트를 수행한 후 쿼럼에 다시 들어가게 합니다.

  • 하드웨어를 사용하여 지원하되 신중하게 수행하십시오. 예를 들어 ECC RAM을 얻을 수 있고 이를 통해 정기적으로 읽기/쓰기를 통해 ECC 오류를 수정할 수 있습니다(오류를 수정할 수 없는 경우 패닉). 그러나 (메모리에서) 정적 RAM은 원래 DRAM보다 이온화 방사선에 훨씬 더 내성이 있으므로 대신 정적 DRAM을 사용하는 것이 더 나을 수 있습니다. '하지 않을 것'의 첫 번째 요점도 참조하십시오.

주어진 노드가 하루 안에 실패할 확률이 1%이고 실패를 완전히 독립적으로 만들 수 있다고 가정해 봅시다. 5개의 노드를 사용하면 하루 안에 3개의 노드가 실패해야 하며 이는 0.00001%의 확률입니다. 더 많이, 글쎄, 당신은 아이디어를 얻을.

내가 하지 않을 것:

  • 처음부터 문제가 없는 것의 가치를 과소평가하십시오. 무게가 문제가 되지 않는 한, 장치 주변의 큰 금속 블록은 프로그래머 팀이 생각해 낼 수 있는 것보다 훨씬 저렴하고 안정적인 솔루션이 될 것입니다. EMI 입력의 광학적 결합도 문제입니다. 무엇이든 간에 구성 요소를 소싱할 때 전리 방사선에 대해 최고 등급을 받은 구성 요소를 소싱하려고 시도하십시오.

  • 자신의 알고리즘을 굴 립니다. 사람들은 이전에 이 일을 해왔습니다. 그들의 작업을 사용하십시오. 내결함성과 분산 알고리즘은 어렵습니다. 가능하면 다른 사람의 작업을 사용하십시오.

  • 더 많은 실패를 감지하기를 바라는 순진한 컴파일러 설정을 사용하십시오. 운이 좋다면 더 많은 실패를 감지할 수 있습니다. 특히 직접 롤링한 경우 덜 테스트된 컴파일러 내에서 코드 경로를 사용할 가능성이 더 큽니다.

  • 귀하의 환경에서 테스트되지 않은 기술을 사용하십시오. 고가용성 소프트웨어를 작성하는 대부분의 사람들은 HA가 올바르게 작동하는지 확인하기 위해 실패 모드를 시뮬레이션해야 하며 결과적으로 많은 실패 모드를 놓칩니다. 당신은 요구에 따라 자주 실패하는 '운 좋은' 위치에 있습니다. 따라서 각 기술을 테스트하고 응용 프로그램이 도입하는 복잡성을 초과하는 양만큼 MTBF를 실제로 개선하는지 확인합니다(복잡성과 함께 버그가 발생함). 특히 이것을 내 조언 쿼럼 알고리즘 등에 적용하십시오.


abligh

특히 소프트웨어 솔루션을 요청하고 C++를 사용하고 있으므로 연산자 오버로딩을 사용하여 자신의 안전한 데이터 유형을 만드는 것이 어떻습니까? 예를 들어:

uint32_t (및 double , int64_t 등)를 사용하는 대신 uint32_t의 배수(최소 3)를 포함하는 SAFE_uint32_t 수행하려는 모든 작업(* + - / << >> = == != 등)을 오버로드하고 오버로드된 작업이 각 내부 값에 대해 독립적으로 수행되도록 합니다. 즉, 한 번만 수행하고 결과를 복사하지 마십시오. 전후 모두 내부 값이 모두 일치하는지 확인합니다. 값이 일치하지 않으면 잘못된 값을 가장 일반적인 값으로 업데이트할 수 있습니다. 가장 일반적인 값이 없으면 오류가 있음을 안전하게 알릴 수 있습니다.

이렇게 하면 ALU, 레지스터, RAM 또는 버스에서 손상이 발생하더라도 문제가 되지 않으며 여전히 여러 번 시도하고 오류를 잡을 수 있는 매우 좋은 기회가 있습니다. 그러나 이것은 대체할 수 있는 변수에 대해서만 작동하지만 예를 들어 스택 포인터는 여전히 취약합니다.

부수적인 이야기: 오래된 ARM 칩에서도 비슷한 문제가 발생했습니다. 그것은 우리가 사용한 특정 칩과 함께 GCC의 이전 버전을 사용하는 툴체인으로 밝혀졌으며, 이는 (때로는) 값을 손상시키는 특정 엣지 케이스에서 함수로 전달되는 버그를 유발했습니다. 방사능으로 기기를 비난하기 전에 기기에 문제가 없는지 확인하십시오. 예, 때로는 컴파일러 버그입니다 =)


jkflying

면책 조항: 저는 방사능 전문가가 아니며 이런 종류의 응용 프로그램을 위해 일하지 않았습니다. 그러나 저는 중요한 데이터의 장기 보관을 위해 소프트 오류 및 중복 작업을 수행했습니다. 이는 어느 정도 연결되어 있습니다(같은 문제, 다른 목표).

내 생각에 방사능의 주요 문제는 방사능이 비트를 전환 할 수 있으므로 방사능이 모든 디지털 메모리를 변조할 수 있거나 변조할 수 있다는 것 입니다. 이러한 오류를 일반적으로 소프트 오류 , 비트 로트 등이라고 합니다.

그렇다면 문제는 메모리가 신뢰할 수 없을 때 어떻게 안정적으로 계산하는가 하는 것입니다.

소프트 오류 비율을 크게 줄이려면(대부분 소프트웨어 기반 솔루션이기 때문에 계산 오버헤드를 희생하여) 다음 중 하나를 수행할 수 있습니다.

  • 좋은 오래된 중복성 체계 에 의존하고 더 구체적으로 더 효율적인 오류 수정 코드 (같은 목적이지만 더 적은 중복성으로 더 많은 비트를 복구할 수 있는 더 똑똑한 알고리즘)에 의존합니다. 이것은 때때로 (잘못) 체크섬이라고도 합니다. 이러한 종류의 솔루션을 사용하면 언제든지 프로그램의 전체 상태를 마스터 변수/클래스(또는 구조체?)에 저장하고 ECC를 계산하고 어떤 작업을 수행하기 전에 ECC가 올바른지 확인해야 합니다. 아니, 필드를 수리하십시오. 그러나 이 솔루션은 소프트웨어가 작동할 수 있다고 보장하지 않습니다. 가짜 결과를 얻지 마십시오).

  • 또는 소프트 오류가 있는 경우에도 프로그램이 여전히 올바른 결과를 제공하도록 보장 하는 탄력적인 알고리즘 데이터 구조를 사용할 수 있습니다. 이러한 알고리즘은 기본적으로 혼합된 ECC 체계가 있는 일반적인 알고리즘 구조의 혼합으로 볼 수 있지만 탄력성 체계가 구조에 밀접하게 제한되어 있으므로 추가 절차를 인코딩할 필요가 없기 때문에 이것이 훨씬 더 탄력적입니다. ECC를 확인하기 위해 일반적으로 훨씬 빠릅니다. 이러한 구조는 소프트 오류의 이론적 한계까지 모든 조건에서 프로그램이 작동하도록 하는 방법을 제공합니다. 추가 보안을 위해 이러한 탄력적 구조를 이중화/ECC 체계와 혼합할 수도 있습니다(또는 가장 중요한 데이터 구조를 탄력적으로 인코딩하고 나머지는 기본 데이터 구조에서 다시 계산할 수 있는 소모성 데이터를 ECC 비트 또는 계산이 매우 빠른 패리티 검사).

복원력 있는 데이터 구조(최근의 알고리즘 및 중복 엔지니어링 분야이지만 흥미롭고 새로운 분야임)에 관심이 있다면 다음 문서를 읽을 것을 권합니다.

  • 탄력적 알고리즘 데이터 구조 소개: Giuseppe F.Italiano, Universita di Roma "Tor Vergata"

  • Christiano, P., Demaine, ED, & Kishore, S. (2011). 추가 오버헤드가 있는 무손실 내결함성 데이터 구조. 알고리즘 및 데이터 구조(pp. 243-254). 스프링거 베를린 하이델베르크.

  • Ferraro-Petrillo, U., Grandoni, F., & Italiano, GF (2013). 메모리 결함에 탄력적인 데이터 구조: 사전에 대한 실험적 연구. 실험 알고리즘 저널(JEA), 18, 1-6.

  • 이탈리아노, GF (2010). 탄력적인 알고리즘 및 데이터 구조. 알고리즘과 복잡성에서 (pp. 13-24). 스프링거 베를린 하이델베르크.

탄력적인 데이터 구조 분야에 대해 더 알고 싶다면 Giuseppe F. Italiano의 작업을 확인하고(심판을 통해 작업) Faulty-RAM 모델 (Finocchi et al. 2005에서 소개됨, Finocchi 및 이탈리아노 2008).

/편집: 주로 RAM 메모리 및 데이터 저장에 대한 소프트 오류 방지/복구를 설명했지만 계산(CPU) 오류 에 대해서는 이야기하지 않았습니다. 다른 답변은 이미 데이터베이스에서와 같이 원자적 트랜잭션을 사용하는 것에 대해 지적했으므로 저는 또 다른 간단한 계획인 redundancy 및 대다수 투표를 제안할 것입니다.

아이디어는 수행해야 하는 각 계산에 대해 x번 동일한 계산 을 수행하고 결과를 x개의 다른 변수(x >= 3)에 저장한다는 것입니다. 그런 다음 x 변수 를 비교할 수 있습니다.

  • 모두 동의하면 계산 오류가 전혀 없습니다.
  • 동의하지 않는 경우 다수결을 사용하여 올바른 값을 얻을 수 있습니다. 이는 계산이 부분적으로 손상되었음을 의미하므로 시스템/프로그램 상태 스캔을 트리거하여 나머지가 괜찮은지 확인할 수도 있습니다.
  • 과반수 투표로 승자를 결정할 수 없는 경우(모든 x 값이 다름) 비상 안전 절차(재부팅, 사용자에게 경고 발생 등)를 트리거하는 완벽한 신호입니다.

이 이중화 체계는 ECC(실제로 O(1))에 비해 매우 빠르며 안전 장치 가 필요할 때 명확한 신호를 제공합니다. 다수결은 또한 (거의) 손상된 출력을 생성하지 않고 사소한 계산 오류로부터 복구 하도록 보장됩니다. x 계산이 동일한 출력을 제공할 확률이 극미하기 때문입니다(가능한 출력이 많기 때문에 거의 불가능합니다. 무작위로 3번 동일하게, x > 3인 경우 더 적은 기회를 얻습니다.

따라서 다수결을 사용하면 손상된 출력으로부터 안전하고 중복성 x == 3을 사용하면 1개의 오류를 복구할 수 있습니다(x == 4의 경우 2개의 오류를 복구할 수 있습니다. 등). -- 정확한 방정식은 nb_error_recoverable == (x-2) 여기서 x는 다수결을 사용하여 복구하기 위해 최소한 2개의 동의 계산이 필요하기 때문에 계산 반복 횟수입니다.

단점은 한 번 대신 x번을 계산해야 하므로 추가 계산 비용이 발생하지만 선형 복잡성이 있으므로 점근적으로 얻을 수 있는 이점에 대해 많은 것을 잃지 않는다는 것입니다. 다수결을 수행하는 빠른 방법은 배열에서 모드를 계산하는 것이지만 중앙값 필터를 사용할 수도 있습니다.

또한 계산이 올바르게 수행되었는지 추가로 확인하려면 하드웨어를 직접 만들 수 있다면 x CPU로 장치를 구성하고 시스템을 연결하여 과반수 투표가 완료된 x CPU에서 계산이 자동으로 복제되도록 할 수 있습니다. 끝에서 기계적으로 (예를 들어 AND/OR 게이트 사용). 이것은 종종 항공기 및 미션 크리티컬 장치에서 구현됩니다( 3중 모듈식 이중화 참조). 이렇게 하면 계산 오버헤드가 없고(추가 계산이 병렬로 수행되기 때문에) 소프트 오류로부터 또 다른 보호 계층을 갖게 됩니다(계산 중복 및 과반수 투표가 하드웨어에서 직접 관리되지 않고 하드웨어에서 관리되기 때문에). 소프트웨어 -- 프로그램이 단순히 메모리에 저장된 비트이기 때문에 더 쉽게 손상될 수 있습니다...).


gaborous

한 점은 아무도 언급하지 않은 것 같습니다. GCC로 개발하고 ARM에서 크로스 컴파일한다고 말합니다. 여유 RAM, 정수 크기, 포인터 크기, 특정 작업을 수행하는 데 걸리는 시간, 시스템이 지속적으로 실행되는 시간 또는 이와 같은 다양한 항목에 대해 가정하는 코드가 없다는 것을 어떻게 알 수 있습니까? 이것은 매우 일반적인 문제입니다.

대답은 일반적으로 자동화된 단위 테스트입니다. 개발 시스템에서 코드를 실행하는 테스트 하네스를 작성한 다음 대상 시스템에서 동일한 테스트 하네스를 실행합니다. 차이점을 찾으십시오!

또한 임베디드 장치에 오류가 있는지 확인하십시오. "이 작업을 수행하지 마십시오. 충돌이 발생할 수 있으므로 해당 컴파일러 옵션을 활성화하면 컴파일러가 이 문제를 해결할 것입니다"라는 내용이 있을 수 있습니다.

요컨대, 가장 가능성이 높은 충돌 소스는 코드의 버그입니다. 이것이 사실이 아니라는 것을 확실히 확신할 때까지 (아직) 더 난해한 실패 모드에 대해 걱정하지 마십시오.


Graham

방사선 환경 외부에 마스터가 있는 3개 이상의 슬레이브 머신이 필요합니다. 모든 I/O는 투표 및/또는 재시도 메커니즘이 포함된 마스터를 통과합니다. 슬레이브에는 각각 하드웨어 워치독이 있어야 하며 이를 범프하라는 호출은 비자발적 범핑의 가능성을 줄이기 위해 CRC 등으로 둘러싸여 있어야 합니다. 범핑은 마스터에 의해 제어되어야 하므로 마스터와의 연결이 끊어지면 몇 초 안에 재부팅되는 것과 같습니다.

이 솔루션의 한 가지 장점은 슬레이브와 동일한 API를 마스터에 사용할 수 있으므로 중복성이 투명한 기능이 된다는 것입니다.

편집 : 의견에서 "CRC 아이디어"를 명확히해야 할 필요성을 느낍니다. CRC로 범프를 둘러싸거나 마스터에서 임의의 데이터에 대한 다이제스트 검사를 수행하는 경우 슬레이브가 자체 워치독을 범할 가능성은 0에 가깝습니다. 그 임의의 데이터는 조사 중인 슬레이브가 다른 슬레이브와 정렬될 때만 마스터에서 전송됩니다. 랜덤 데이터 및 CRC/다이제스트는 각 범프 후에 즉시 지워집니다. 마스터-슬레이브 범프 주파수는 워치독 타임아웃의 두 배 이상이어야 합니다. 마스터에서 보낸 데이터는 매번 고유하게 생성됩니다.


Jonas Byström

애플리케이션의 많은 인스턴스를 실행하는 것은 어떻습니까? 충돌이 임의의 메모리 비트 변경으로 인한 경우 일부 앱 인스턴스가 통과하여 정확한 결과를 생성할 가능성이 있습니다. (통계적 배경이 있는 사람의 경우) 원하는 만큼 작은 전체 오류를 달성하기 위해 주어진 비트 플롭 확률이 얼마나 많은 인스턴스가 필요한지 계산하는 것은 아마도 매우 쉽습니다.


ren

당신이 묻는 것은 매우 복잡한 주제이며 쉽게 대답할 수 없습니다. 다른 답변은 괜찮지만 수행해야 하는 모든 작업의 작은 부분만 다루었습니다.

주석에서 볼 수 있듯이 하드웨어 문제를 100% 고칠 수는 없지만 다양한 기술을 사용하여 하드웨어 문제를 줄이거나 잡을 가능성이 높습니다.

내가 당신이라면 가장 높은 안전 무결성 수준(SIL-4)의 소프트웨어를 만들 것입니다. IEC 61513 문서(원자력 산업용)를 가져와서 따르십시오.


BЈовић

누군가는 이온이 비트를 쉽게 뒤집는 것을 방지하기 위해 느린 칩을 사용한다고 언급했습니다. 비슷한 방식으로 실제로 여러 비트를 사용하여 단일 비트를 저장하는 특수 CPU/램을 사용할 수 있습니다. 따라서 모든 비트가 뒤집힐 가능성이 매우 낮기 때문에 하드웨어 내결함성을 제공합니다. 따라서 1 = 1111이지만 실제로 뒤집기 위해서는 4번 맞아야 합니다. (2비트가 뒤집히면 이미 모호하므로 4는 잘못된 숫자일 수 있습니다.) 따라서 8을 사용하면 램이 8배 줄어들고 액세스 시간이 약간 느려지지만 훨씬 더 안정적인 데이터 표현을 얻을 수 있습니다. 특수 컴파일러(모든 것에 대해 x 양의 더 많은 공간 할당) 또는 언어 구현(이런 방식으로 할당하는 데이터 구조에 대한 래퍼 작성)을 사용하여 소프트웨어 수준에서 모두 이 작업을 수행할 수 있습니다. 또는 논리적 구조가 동일하지만 펌웨어에서 이를 수행하는 특수 하드웨어.


Alex C

하드웨어가 "이 환경에 맞게 설계됨"을 의미하는지 아는 것이 도움이 될 것입니다. SEU 오류의 존재를 어떻게 수정 및/또는 표시합니까?

한 우주 탐사 관련 프로젝트에서 우리는 SEU 오류에 대한 예외/인터럽트를 발생시키는 맞춤형 MCU를 가지고 있었지만 약간의 지연이 있습니다.

특히 데이터 캐시가 취약했기 때문에 핸들러는 문제가 되는 캐시 라인을 무효화하고 프로그램을 다시 시작했습니다. 다만, 예외의 부정확한 특성으로 인해 예외 발생 insn이 이끄는 insn 시퀀스를 다시 시작할 수 없을 수도 있습니다.

우리는 위험한(다시 시작할 수 없는) 시퀀스(예: lw $3, 0x0($2) $2 $3 에 데이터 종속적이지 않음)가 뒤따르는 insn을 식별했으며 GCC를 수정하여 이러한 시퀀스가 발생하지 않도록 했습니다. (예: 최후의 수단으로 두 개의 숙소를 nop ).

고려해야 할 사항 ...


chill

하드웨어에 장애가 발생하면 기계적 저장소를 사용하여 복구할 수 있습니다. 코드 기반이 작고 물리적 공간이 있는 경우 기계 데이터 저장소를 사용할 수 있습니다.

여기에 이미지 설명 입력

방사선의 영향을 받지 않는 재료의 표면이 있을 것입니다. 여러 기어가 있을 것입니다. 기계식 판독기는 모든 기어에서 작동하며 위아래로 유연하게 움직일 수 있습니다. Down은 0을 의미하고 Up은 1을 의미합니다. 0과 1에서 코드 기반을 생성할 수 있습니다.


Hitul

첫째, 실패를 중심으로 애플리케이션을 설계하십시오 . 정상적인 흐름 작동의 일부로 재설정될 것으로 예상하는지 확인합니다(응용 프로그램 및 장애 유형에 따라 소프트 또는 하드). 이것은 완벽하기가 어렵습니다. 어느 정도의 트랜잭션이 필요한 중요한 작업은 어셈블리 수준에서 확인하고 조정해야 핵심 지점에서 중단이 일관되지 않은 외부 명령으로 이어지지 않도록 할 수 있습니다. 복구할 수 없는 메모리 손상 또는 제어 흐름 편차가 감지되는 즉시 빠르게 실패합니다. 가능한 경우 실패를 기록하십시오.

둘째, 가능한 경우 손상을 수정하고 계속하십시오 . 이는 상수 테이블(및 가능한 경우 프로그램 코드)을 자주 체크섬 및 수정하는 것을 의미합니다. 아마도 각 주요 작업 전 또는 시간 제한 인터럽트에서 자동 수정되는 구조에 변수를 저장합니다(다시 각 주요 작업 이전 또는 시간 제한 인터럽트에서 3에서 과반수 투표를 취하고 단일 편차인 경우 수정). 가능한 경우 수정 사항을 기록하십시오.

셋째, 테스트 실패 . 무작위로 메모리의 비트를 뒤집는 반복 가능한 테스트 환경을 설정합니다. 이렇게 하면 손상 상황을 복제하고 이러한 상황을 중심으로 애플리케이션을 설계하는 데 도움이 됩니다.


MrBigglesworth

순환 스케줄러를 사용하십시오. 이를 통해 중요한 데이터의 정확성을 확인하기 위해 정기적인 유지 관리 시간을 추가할 수 있습니다. 가장 자주 발생하는 문제는 스택 손상입니다. 소프트웨어가 주기적이면 주기 사이에 스택을 다시 초기화할 수 있습니다. 인터럽트 호출에 스택을 재사용하지 마십시오. 각 중요한 인터럽트 호출에 대해 별도의 스택을 설정하십시오.

Watchdog 개념과 유사하게 데드라인 타이머가 있습니다. 함수를 호출하기 전에 하드웨어 타이머를 시작하십시오. 기한 타이머가 인터럽트되기 전에 함수가 반환되지 않으면 스택을 다시 로드하고 다시 시도하십시오. 3/5 시도 후에도 여전히 실패하면 ROM에서 다시 로드해야 합니다.

소프트웨어를 여러 부분으로 나누고 이러한 부분을 분리하여 별도의 메모리 영역과 실행 시간을 사용합니다(특히 제어 환경에서). 예: 신호 수집, 데이터 사전 보유, 주요 알고리즘 및 결과 구현/전송. 이것은 한 부분의 오류가 나머지 프로그램의 오류를 일으키지 않는다는 것을 의미합니다. 따라서 신호 수집을 복구하는 동안 나머지 작업은 오래된 데이터에서 계속됩니다.

모든 것은 CRC가 필요합니다. RAM 부족으로 실행하면 .text에도 CRC가 필요합니다. 주기적 스케줄러를 사용하는 경우 CRC를 정기적으로 확인하십시오. 일부 컴파일러(GCC 아님)는 각 섹션에 대해 CRC를 생성할 수 있고 일부 프로세서에는 CRC 계산을 수행하기 위한 전용 하드웨어가 있지만 이는 귀하의 질문 범위를 벗어납니다. CRC를 검사하면 메모리의 ECC 컨트롤러가 문제가 되기 전에 단일 비트 오류를 복구하라는 메시지가 표시됩니다.

부팅에 워치독을 사용하면 한 번만 작동하지 않습니다. 부팅에 문제가 발생한 경우 하드웨어 지원이 필요합니다.


Gerhard

supercat의 의견, 최신 컴파일러의 경향 및 기타 사항을 감안할 때 고대로 돌아가 전체 코드를 어셈블리 및 정적 메모리 할당으로 모든 곳에서 작성하고 싶습니다. 이러한 종류의 완전한 신뢰성을 위해 조립에 더 이상 비용의 큰 차이가 발생하지 않는다고 생각합니다.


Joshua

여기에 엄청난 양의 답변이 있지만 이에 대한 내 생각을 요약하려고 합니다.

무언가 충돌하거나 제대로 작동하지 않는 것은 자신의 실수로 인해 발생할 수 있습니다. 그러면 문제를 찾을 때 쉽게 수정할 수 있습니다. 그러나 하드웨어 오류의 가능성도 있습니다. 이는 전체적으로 수정하는 것이 불가능하지는 않더라도 어렵습니다.

나는 먼저 기록(스택, 레지스터, 함수 호출)을 통해 문제 상황을 포착하려고 시도하는 것이 좋습니다. 파일의 어딘가에 기록하거나 어떻게든 직접 전송하여("아, 충돌합니다").

이러한 오류 상황에서 복구는 재부팅(소프트웨어가 여전히 활성 상태이고 작동 중인 경우) 또는 하드웨어 재설정(예: hw watchdogs)입니다. 처음부터 시작하기가 더 쉽습니다.

문제가 하드웨어와 관련된 경우 로깅은 어떤 함수 호출 문제가 발생하는지 식별하는 데 도움이 되며 작동하지 않는 항목과 위치에 대한 내부 지식을 제공할 수 있습니다.

또한 코드가 상대적으로 복잡한 경우 "분할 및 정복"하는 것이 합리적입니다. 문제가 의심되는 일부 기능 호출을 제거/비활성화하는 것을 의미합니다. 일반적으로 코드의 절반을 비활성화하고 나머지 절반을 활성화하면 "작동합니다"/ "작동하지 않음"과 같은 결정을 내린 후 코드의 다른 절반에 집중할 수 있습니다. (문제가 있는 곳)

일정 시간 후에 문제가 발생하면 스택 오버플로가 의심될 수 있습니다. 스택 포인트 레지스터가 지속적으로 증가하는 경우 모니터링하는 것이 좋습니다.

그리고 "hello world" 종류의 응용 프로그램이 될 때까지 코드를 완전히 최소화할 수 있고 여전히 무작위로 실패하면 하드웨어 문제가 예상되고 "하드웨어 업그레이드"가 필요합니다. 즉, 이러한 cpu/ram/... -방사선을 더 잘 견딜 수 있는 하드웨어 조합.

가장 중요한 것은 아마도 시스템이 완전히 중지/재설정/작동하지 않는 경우 로그를 다시 가져오는 방법일 것입니다. 아마도 부트스탭이 가장 먼저 해야 할 일은 문제가 있는 상황이 덮인 경우 집으로 돌아가는 것입니다.

환경에서 신호를 전송하고 응답을 수신하는 것이 가능하다면 일종의 온라인 원격 디버깅 환경을 구성하려고 시도할 수 있지만 최소한 통신 미디어가 작동하고 일부 프로세서/램이 작동 상태여야 합니다. 그리고 원격 디버깅이란 GDB/gdb 스텁 종류의 접근 방식 또는 애플리케이션에서 되돌려 받는 데 필요한 자체 구현(예: 로그 파일 다운로드, 호출 스택 다운로드, 램 다운로드, 다시 시작)을 의미합니다.


TarmoPikaro

나는 정말 많은 훌륭한 답변을 읽었습니다!

여기 내 2센트가 있습니다. 메모리를 확인하거나 빈번한 레지스터 비교를 수행하는 소프트웨어를 작성하여 메모리/레지스터 이상에 대한 통계 모델을 구축하십시오. 또한 문제를 실험할 수 있는 가상 머신 스타일의 에뮬레이터를 만듭니다. 접합 크기, 클록 주파수, 공급업체, 케이스 등을 변경하면 다른 동작이 관찰될 것입니다.

데스크탑 PC 메모리도 일정 비율의 오류가 발생하지만 일상 업무에 지장을 주지는 않습니다.


user9016329

출처 : http:www.stackoverflow.com/questions/36827659/compiling-an-application-for-use-in-highly-radioactive-environments

반응형