2016-10-28 20 views
2

일부 메모리 매핑 된 레지스터를 읽거나 쓰는 베어 메탈 프로그램 (드라이버)이 있습니다. 는 예컨대 :메모리 액세스 (MISRA 2008)

void foo_read(uint64_t reg_base, uint32_t *out_value) 
{ 
    *out = READREG(reg_base + FOO_REG_OFFSET); 
} 
  • reg_base 메모리 매핑 장치 (64 비트 어드레스 )
  • FOO_REG_OFFSET는 레지스터 (#define FOO_REG_OFFSET 0x00000123)의 오프셋의베이스 어드레스이다. 레지스터 "foo"는 32 비트 "와이드"입니다.

READREG는 다음과 같이 정의된다 :

#define READREG(address) (*(uint32_t*)(address)) 

는 MISRA 2008 포인터 (5-2-7/5-2-8은 긴 긴 부호에서 캐스트와 함께 행복하지 않다 추측 수 있듯이 보고 됨). 내 질문은 : 메모리에 액세스하고 MISRA 경고를 없애기위한 최선의/적절한 방법은 무엇입니까? 포인터로 캐스팅하기 전에 uintptr_t로 캐스팅하려고 시도했지만 This didn't help입니다.

감사합니다.

+2

오히려 분명한 질문이다. reg_base' 실제로 포인터입니다, 왜'uint8_t *'로 입력하지? – hidefromkgb

+1

@hidefromkgb : 또는'uint32_t *','reg_base'가 정말로 정수 일 필요가 있다면'uintptr_t'보다는'uint64_t'를 사용해야하는 이유는 무엇입니까? (MISRA는 그것도 좋아하지 않을 것이다. 그러나'intptr_t' 나'uintptr_t'는 포인터 값을 가지고있는 정수에서 가장 논리적 인 타입이다.) –

+1

@KeithThompson, wouldn \'t'uint32_t *'는 FOO_REG_OFFSET에 4를 곱한다. 'reg_base'에 추가 하시겠습니까? – hidefromkgb

답변

1

여기에 몇 가지 확인 - 우선, READ_REG에 대한 정의가 누락되는 volatile - 그것이 있어야 뭔가 둘째

#define READREG(address) (*(uint32_t volatile *)(address)) 

같은 - 이것은 CPU 별 물론입니다 - 일반적으로, 홀수 번지 (오프셋 0x123)에서 32 비트 값을 읽는 것은 작동하지 않습니다. 최소한 (느린 속도 (여러 버스 사이클)) 많은 아키텍처에서 프로세서 예외가 발생합니다. (BTW, 2 개 값이 포인터로 캐스팅되기 전에 추가되기 때문에 그 포인터 연산이 여기 놀이로 오지 않습니다 유의하시기 바랍니다.)

은 원래의 질문에 대답하기 : 최선이 무엇인지

을 메모리에 액세스 할 수/적절한 방법이

잘 MISRA의 경고

를 제거 - 당신이 MISRA 규칙 위반이다 (이 경우에이를, 우리는 ... 거기했습니다) 그래서 당신은 경고를 얻을 것입니다.

그래서해야 할 일은 체계적이고 쉽게 식별 할 수있는 방식으로 경고를 억제하는 것입니다. 제 생각에는 오픈 소스 인 Quantum Platform (QP) 이벤트 중심 프레임 워크의 코드보다 더 좋은 예제와 설명이 없습니다. 특히 :

  • 체크 아웃의 예는 QP's MISRA Compliance 행렬이이 처리하는 방법 - macro that wraps/encapsulates such "int to ptr" casts (예 - 예를 들어, 단지 Q_UINT2PTR_CAST 매크로
  • 체크 아웃 QP의 실제 소스 코드에 대한 PDF 검색 이 방법은 식별하기 쉬운 방식으로 이루어지며 한 곳에서 경고를 변경/억제하기가 쉽습니다.
  • 마지막으로 PC-Lint 구성 파일 qpc.lnt를 확인하십시오. 경고는 한 곳에서 표시되지 않습니다. 이것은 this app note, 섹션 6에 설명되어 있습니다.3 :

6.3 5-2-8 규칙 유형을 무효화 할 (REQ) 정수형 또는 포인터

목적은 포인터 타입의 객체로 변환되지 않는다.

이 특정 하드 코딩 된 하드웨어 주소에 직접 액세스해야하는 경우 QP/C++ 응용 프로그램이 규칙 5-2-8에서 벗어날 수 있습니다. QP/C++ 프레임 워크는이 편차를 매크로 Q_UINT2PTR_CAST()에 캡슐화합니다. #define QK_ISR_EXIT() . . . \ *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \

가 나는 등 MISRA 경고 suppresions, 규정 준수 문제에 대해 이야기 할 시간이 없어하지만 위의 여러분에게 필요한 모든 것을 제공 : 다음 코드는이 매크로의 사용 사례를 제공한다.

P. 당신이 말하는 MISRA 가이드 라인을 잘 모르겠다. C에 대해서는 2004 & 2012 가이드 라인이 있고, C++의 경우 2008 가이드 라인이있다. (나는 거의 2017이다.)

+0

#define FOO_REG_OFFSET 0x00000123은 그 예입니다. 물론 홀수 오프셋이 없습니다. – AndreiSS

+0

@AndreiSS - 물론 그렇지 않습니다. 또한이 질문에 대한 대답을 수락하지 않았습니다. – Dan