코드 크기와 성능이 동시에 필요한 임베디드 장치 드라이버 라이브러리 (Arduino Mega)를 작성 중입니다.조건부 템플릿을 사용하여 함수 호출하기 C++
는 SPI 제어기는 이동 동작의 시퀀스를 가지고
- 선택 SPI 슬레이브 노드
- 데이터 전송
- 선택 해제 슬레이브 노드
셀렉트/셀렉트되어 시작/거래 중지. 이는 핀을 높게 또는 낮게 어서 실행됩니다. SPI 슬레이브 노드 회로는 표준 비 반전 디지털 신호 (select == high voltage, deselect == ground) 또는 inverted 신호 (select == ground, deselect == high voltage)를 사용할 수 있습니다.
select()는 핀이 반전되었는지 확인하기 위해 런타임 조건을 사용하여 구현 될 수 있습니다 (clearPin()을 발행하거나) (setPin()을 발행하십시오). deselect()도 마찬가지입니다. consts와 정적 정의를 사용하면 컴파일러 은이 컴파일 할 때 조건을 풀 수 있어야합니다. 결과적으로 컴파일러 (Avr-gcc 4.9)는 이러한 표현식을 줄일 수 있다는 것을 항상 깨닫지 못합니다.
그래서,이 같은 조건 템플릿을 사용하기 위해 노력하고있어이 문제를 해결 얻을 :
// Uses digital pin # 33 as Select pin
static struct SelectPin<SelectPinType::INVERTED> SpiSel
{
Pin::PIN_DIO_33
};
...
SpiSel.select();
doTransfer(dataBuffer);
SpiSel.deselect();
모든 :
enum class SelectPinType : const bool
{
STANDARD = false,
INVERTED = true
};
template <SelectPinType tInvertedSelect>
struct SelectPin;
template<>
struct SelectPin<SelectPinType::INVERTED>
{
const Pin::IOPin &mChipSelectPin;
inline void select() const __attribute__((always_inline))
{
Pin::clr(mChipSelectPin); // Select inverted pin
}
inline void deselect() const __attribute__((always_inline))
{
Pin::set(mChipSelectPin); // Deselect inverted pin
}
};
template<>
struct SelectPin<SelectPinType::STANDARD>
{
const Pin::IOPin &mChipSelectPin;
inline void select() const __attribute__((always_inline))
{
Pin::set(mChipSelectPin); // Select standard pin
}
inline void deselect() const __attribute__((always_inline))
{
Pin::clr(mChipSelectPin); // Deselect standard pin
}
};
합니다 (선택을)과() 해제 다음처럼 사용할 수 있습니다 잘 작동하고 select()/deselect()는 5 개 미만의 어셈블러 명령어로 컴파일됩니다. 그러나 구조체 SelectPin의 인스턴스를 전달하는 방법에 대한 해결책을 찾을 수 없는데, 함수 매개 변수 목록에 템플릿 조건을 지정하지 않아도됩니다. 내가 함수에서 선택 - 전송 - 선택 해제를 wrapp하려는 경우 즉, 나는 다음을 수행해야합니다 :
내가 과부하 기능을 쓸 수도 있기 때문에// Inverted select pin transaction
inline void doTransaction(const SelectPin<SelectPinType::INVERTED> &fSelectPin, Spi::Transfer &fTransfer)
{
// Perform the SPI transaction
fSelectPin.select();
doTransfer(fTransfer);
fSelectPin.deselect();
// Done
return;
}
// Non-inverted select pin transaction
inline void doTransaction(const SelectPin<SelectPinType::STANDARD> &fSelectPin, Spi::Transfer &fTransfer)
{
// Perform the SPI transaction
fSelectPin.select();
doTransfer(fTransfer);
fSelectPin.deselect();
// Done
return;
}
반전 및 템플릿을 사용하지 않고 선택 핀을 비는 반전 , 나는 기본적으로 제곱에 돌아 간다.
본질적으로 기본 템플릿을 단일 함수 정의의 매개 변수로 사용할 수 있도록 방법이 있습니까? 의 라인을 따라 뭔가 :
// Accept any condition for the SelectPin template
inline void doTransaction(const SelectPin<SelectPinType::*> &fSelectPin, Spi::Transfer &fTransfer)
{
// Perform the SPI transaction
fSelectPin.select();
doTransfer(fTransfer);
fSelectPin.deselect();
// Done
return;
}
주 예, 내가이 개 과부하 기능이 바로 일을 할 것이라는 점을 깨닫게하지만이 내 크레이프 선택 핀 이외의 일반적인 영향을 미칠 수 있다는 것을 생각합니다.
감사합니다! 그 자리에서! – Nilsie