2017-11-22 2 views
1

저는 기존 소프트웨어의 기능이 새로운 하드웨어의 새로운 소프트웨어 아키텍처로 실현되는 임베디드 프로젝트에서 작업하고 있습니다.get/set 래퍼를 숨기고 있지만 레지스터를 투명하게 사용합니다.

목표는 복잡한 하드웨어 장치를 제어하는 ​​것입니다. 이전 소프트웨어에는 메모리에 매핑 된 장치의 레지스터가 있었으며 소프트웨어는 해당 레지스터를 직접 수정합니다. 이와 같이

: 새 하드웨어 (ommited되지 않을 수 있음) 래퍼

/* Register is defined with offset */ 
#define REGISTER_1 regMem[0x1234] 

/* And can be accessed like this (obvious) */ 

REGISTER_1 = 0; 
if (REGISTER_1 == 0) {...} 

SET(REG_ADDR,VALUE); 
GET(REG_ADDR); 

으로든 이들 레지스터에 액세스 할 수있다.

모든 레지스터 액세스를 다시 작성하지 않고 레지스터를 제어하는 ​​기존의 큰 코드베이스를 재사용 할 수있는 변경이 있습니까?

매크로 내에 GET/SET 기능을 숨기는 방법이 있습니까?

#define REGISTER_1 ??? /* Return value with 
GET(REGISTER_1) if not accessed with an assignment like REGISTER_1 = ... */ 

나는 레지스터의 로컬 복사본에 더러운 플래그를 설정 매크로 코드 메커니즘과 같은 캐시에 대해 생각하고 자동 이럴 당신이 그것을 시도하고

+0

레지스터 사용 방법을 확인하고 적절하게 변경해야 할 것 같습니다. 변경된 패턴은 사용 패턴이 매우 정교하고 조심스럽게 만들어진 Perl 스크립트 (또는 다른 유사한 강력한 스크립팅 언어)가 95 + %의 작업을 수행 할 수 있기 때문에 몇 가지 사례를 수동으로 매핑 할 수 있습니다. –

+2

이것은 "WITHOUT"이 아니지만 래핑 된 레지스터 액세스가 해킹보다 더 많은 미래의 증거이므로 이러한 리팩토링을 수행하는 올바른 방법입니다. (나는 전에 이것을 해 봤는데, 그만한 가치가있다.) 이전 하드웨어의 레지스터에 대해 GET 및 SET 함수를 만듭니다. 레지스터를 변경하여 오래된 하드웨어의 함수를 하나씩 사용하고, 일을 계속하기 위해 자주 테스트하십시오. 당신의 목표는 모든 오래된 "REGISTER_1"과 같은 변수를 삭제하거나 이름을 바꾸는 것입니다. 이를 달성하면 새로운 하드웨어의 GET/SET 기능을 사용할 수 있습니다. – Art

+0

새 프로젝트에서 C++을 사용할 수 있다면 이렇게 할 수 있습니다. 그러나 @ Art의 아이디어가 아마도 가장 좋은 접근 방법 일 것입니다. 결과물에서 이진 비교를 수행하여 모든 것이 일치하는지 확인할 수도 있습니다. 문제를 식별하는 한 가지 방법은 GET에 대한 모든 액세스를 변경하고 lvalues가 필요할 때 컴파일러에서 오류를 발생시키는 것입니다. –

답변

1

.../업데이트 액세스에 레지스터를 가져옵니다 주위에 잘못된 길. 하드웨어 레지스터에 접근하는 것은 변수에 값을 저장하는 정신적 모델과는 거리가 멀다. 표준에서는 각 단락에서 조작의 부작용에 대해 언급하고 컴파일러가 제어 할 수없는 내용을 변경하는 셀에 대해서는 volatile을 제공하지만 C 프로그래머는 더 깊은 결과에 대해 전혀 다른 시각을 보일 것입니다. 귀하의 특별한 경우에 적용되는 표준 문구. 그러므로 우리가 인간 독자를 속여 겉보기에 무해한 과제를 읽으려고 할 때 많은 정보가 손실되거나 숨겨집니다. 더 이상 아직 인터럽트 작업을 사용하는 경우 읽기 - 수정 - 쓰기 오류의 천재가 발생할 수 있습니다 (예 : DigiPort_A |= 1;).

이전 코드베이스에서 레지스터 액세스가 균일하게 이루어지면 Jonathan Leffler가 권장하는 접근법을 시도하고 추가 작업이 고객을위한 견습생이되어야 함을 나타내어 임베디드 프로그래밍을 보지 않아야 함을 알립니다. 전기 엔지니어의 부업 일뿐입니다.

관련 문제