ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
24 ноября
26091
Сергей Борщ (14.04.2005 22:37, просмотров: 3032)
Продолжаем разговор (с) Карлсон, про С++ http://www.caxapa.ru/mcu/wwwboard.html?id=25595
все примерно правильно и на уровне перегрузки операторов я сделал уже давно. Но возможно сделал неправильно, ибо уперся в тупик. Пока раскритикуйте то, что есть, а я попытаюсь красиво сформулировать дальнейшие вопросы.
class	TExtBusBase {	// примитивы доступа к шине
 protected:
	TExtBusBase() {};

	static void SetAddress (uint16_t Address);		// выставляет адрес в порты
	static void WriteByte (uint16_t Address, uint8_t Data);	// пишет байт
	static uint8_t ReadByte (uint16_t Address); 		// читает байт
};
Поскольку перегрузка операторов не распространяется на члены класса или структуры, а мне нужно "снаружи" хранить самые разные данные, то мне нужно создать шаблон для "любого типа во внешней памяти". Кроме того, надо как то указывать адрес, по которому размещать эти данные во внешней памяти. Я не придумал ничего лучше, чем неявно использовать для адреса this:
template < class T > class TExtBus : protected TExtBusBase {	// переменная произвольного размера
 public:
	T operator=(T x);
	operator T();
 protected:
    TExtBus() {}
    T data;	// reserve sizeof(T) bytes
};
/****************************************************************************/
template < class T >	
T TExtBus < T > ::operator=(T x) {
	for(int i = 0; i < sizeof(T); i++)
		WriteByte(uint16_t(this) + i, ((uint8_t *)&x)[sizeof(T)-1-i]);
	return x;
}
Теперь могу описывать структуры:
#pragma pack(push,1)
struct TW3100ASocket {
	TExtBus < uint8_t > Status;
	TExtBus < uint8_t > Options;
	TExtBus < uint8_t > dummy[6];
	TExtBus < uint32_t > DestinationIP;
	TExtBus < uint16_t > DestinationPort, SourcePort;
	TExtBus < uint8_t > IPProtocol, TypeOfService;
	TExtBus < uint16_t > MaxSegmentSize;
};
struct TW3100A {
	TExtBus < uint8_t > Command[4];		// C0_CR...C3_CR
	TExtBus < uint8_t > IntStatus[4];	// C0_ISR...C3_ISR
	TExtBus < uint8_t > IntFlags, IntMask;	// IF, IMR
...........
	TW3100ASocket Socket[4];
 	TExtBus < uint8_t > dummy4[0xE0];
};
тепрь все вроде красиво:
TW3100A *const W3100A_core = 0;	//относительно этого рассчитывается this 

void foo() {
	W3100A_core->Command[0] = RESET;	// SW reset
	W3100A_core->SourceIP = Config->Ethernet.IP_ADDR;
	W3100A_core->Netmask = Config->Ethernet.NETMASK;
	W3100A_core->Gateway = Config->Ethernet.GATEWAY;
....
	W3100A_core->RxPointers[SocketNo].RxReadPointer =  RxReadPtr + RxSize;	// Update rx_rd_ptr
....
	W3100A_core->Command[SocketNo] = RECEIVE;

} 
Какие потециальные грабли могут быть? обращения W3100A_core->member компилятор прекрасно оптимизирует и подставляет константу указатель+смещение члена.