BWP-WS19-02/Implementierungsdetails: Unterschied zwischen den Versionen

Aus Verteilte Systeme - Wiki
Zur Navigation springen Zur Suche springen
Zeile 38: Zeile 38:
 
bwp_ws19/zephyr/drivers/counter/counter_nrfx_timer.c
 
bwp_ws19/zephyr/drivers/counter/counter_nrfx_timer.c
   
<source lang="cpp">
+
<source lang="c">
 
#define COUNTER_NRFX_TIMER_DEVICE(idx) \
 
#define COUNTER_NRFX_TIMER_DEVICE(idx) \
 
BUILD_ASSERT_MSG(DT_NORDIC_NRF_TIMER_TIMER_##idx##_PRESCALER <= \
 
BUILD_ASSERT_MSG(DT_NORDIC_NRF_TIMER_TIMER_##idx##_PRESCALER <= \
Zeile 83: Zeile 83:
 
&counter_nrfx_driver_api)
 
&counter_nrfx_driver_api)
 
</source>
 
</source>
  +
  +
  +
... ##idx## wurde durch 0 ersetzt. Ob das Sinn macht weiß ich nicht, aber jetzt kann man besser lesen was dieses Makro macht:
  +
  +
<source lang="c">
  +
/* counter init function */
  +
static int counter_0_init(struct device *dev)
  +
{
  +
IRQ_CONNECT(DT_NORDIC_NRF_TIMER_TIMER_0_IRQ_0,
  +
DT_NORDIC_NRF_TIMER_TIMER_0_IRQ_0_PRIORITY,
  +
irq_handler, DEVICE_GET(timer_0), 0);
  +
  +
static const struct counter_timer_config config = {
  +
.freq = DT_NORDIC_NRF_TIMER_TIMER_0_PRESCALER,
  +
.mode = NRF_TIMER_MODE_TIMER, //Hier müssen wir dann den Counter Mode einstellen
  +
.bit_width = (TIMER0_MAX_SIZE == 32) ? NRF_TIMER_BIT_WIDTH_32 : NRF_TIMER_BIT_WIDTH_16,
  +
};
  +
  +
return init_timer(dev, &config);
  +
}
  +
  +
  +
static struct counter_nrfx_data counter_idx_data;
  +
static struct counter_nrfx_ch_data counter_idx_ch_data[CC_TO_ID(TIMER_0_CC_NUM)];
  +
LOG_INSTANCE_REGISTER(LOG_MODULE_NAME, idx, CONFIG_COUNTER_LOG_LEVEL);
  +
  +
  +
/* counter options */
  +
static const struct counter_nrfx_config nrfx_counter_0_config = {
  +
.info = {
  +
.max_top_value = (TIMER_0_MAX_SIZE == 32) ? 0xffffffff : 0x0000ffff,
  +
.freq = TIMER_CLOCK / (1 << DT_NORDIC_NRF_TIMER_TIMER_idx_PRESCALER),
  +
.flags = COUNTER_CONFIG_INFO_COUNT_UP,
  +
.channels = CC_TO_ID(TIMER_idx_CC_NUM),
  +
},
  +
.ch_data = counteridx_ch_data,
  +
.timer = NRF_TIMER_idx,
  +
LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx)
  +
};
  +
  +
/* Device and API init */
  +
DEVICE_AND_API_INIT(timer_idx, DT_NORDIC_NRF_TIMER_TIMER_idx_LABEL, counter_idx_init,
  +
&counter_idx_data, &nrfx_counter_idx_config.info, PRE_KERNEL_1,
  +
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &counter_nrfx_driver_api)
  +
</source>
  +
  +
  +
  +
Jetzt können wir diese Structs zb im Programm
  +
  +
bwp_ws19/zephyr/samples/drivers/counter/alarm/src/main.c
  +
  +
einbinden, um einen counter zu initialisieren.
  +
  +
  +
'''PPI Programmable Peripheral Interconnect'''
   
   

Version vom 20. Dezember 2019, 22:48 Uhr

Implementierung der Hauptsteuerungs API (Team Antrieb und Mechanik)

Implementierung des ersten Meilensteins

Für die Implementierung des ersten Meilensteins wurde vom Systemarchiteckturteam die generelle Kommunikation zwischen den Teams festgelegt. Hierbei wird ein Job-System verwendet, womit jedes Subteam seine Jobs abfängt und abarbeitet. Während dieser Jobs ist es möglich mittels Mailboxen die Informationen der anderen Teams abzufragen. Die dazugehörige Implementierung findet sich aktuell unter diesem Link.

Implementierung und Erfüllung des zweiten Meilensteins

Bei der Implementierung des zweiten Meilensteins haben wir das Chassis des Prototyps für den ITS-E zusammen gebaut. Hierbei ist aufgefallen, dass das Auto, wenn es durch die Motoren angetrieben wurde leicht schräg fährt. Nach einigen Optimierungen am Chassis waren die Abweichungen nicht mehr ganz so groß - jedoch noch sichtbar. Das könnte durch nicht "echt-parallel" zueinander angebrachten Motoren und/oder der ungleichmäßigen Drehung der Motoren und/oder an der unterschiedlichen Spannungsversorgung durch den Motortreiber liegen. Die eigentliche Implementierung der Motorfunktionen war ja schon im ersten Meilenstein behandelt, für den zweiten Meilenstein haben wir hier nichts anpassen müssen. Das erbrachte Ergebnis ist unter diesem Link zu finden.

Aktivitätendiagramm

Das folgende Aktivitätendiagramm ist für den gesamten Ablauf der Antriebs API gedacht.

Image from iOS.jpg


Implementierung des Counters

Um externe Impulse der rotary-encoder und des solar-click Ladereglers ohne CPU zählen zu können sollen IC interne Counter verwendet werden. Beim verwendeten feather-board sind diese counter unter der Kategorie timer/counter zu finden. Es gibt keine expliziten Counter. Die Timer inkrementieren per Default über einen angeschlossenen Takt (Wahlweise 1MHz oder 16MHz). Über ein MODE Bit kann der Time als Counter fungieren:

Timer_counter.png


Linksammlung zum Thema Counter

Da sich derzeit sowohl das Antriebs- als auch Energie- Team mit dem Counter beschäftigt folgt hier eine Linksammlung mit vermutlich relevanten Dateien:


default MODE

bwp_ws19/modules/hal/nordic/nrfx_config_nrf52832.h:#define NRFX_TIMER_DEFAULT_CONFIG_MODE 0

driver

bwp_ws19/zephyr/drivers/counter/counter_nrfx_timer.c

#define COUNTER_NRFX_TIMER_DEVICE(idx)					       \
	BUILD_ASSERT_MSG(DT_NORDIC_NRF_TIMER_TIMER_##idx##_PRESCALER <=	       \
			TIMER_PRESCALER_PRESCALER_Msk,			       \
			"TIMER prescaler out of range");		       \
	DEVICE_DECLARE(timer_##idx);					       \
	static int counter_##idx##_init(struct device *dev)		       \
	{								       \
		IRQ_CONNECT(DT_NORDIC_NRF_TIMER_TIMER_##idx##_IRQ_0,	       \
			    DT_NORDIC_NRF_TIMER_TIMER_##idx##_IRQ_0_PRIORITY,  \
			    irq_handler, DEVICE_GET(timer_##idx), 0);	       \
		static const struct counter_timer_config config = {	       \
			.freq =	DT_NORDIC_NRF_TIMER_TIMER_##idx##_PRESCALER,   \
			.mode = NRF_TIMER_MODE_TIMER,			       \
			.bit_width = (TIMER##idx##_MAX_SIZE == 32) ?	       \
					NRF_TIMER_BIT_WIDTH_32 :	       \
					NRF_TIMER_BIT_WIDTH_16,		       \
		};							       \
		return init_timer(dev, &config);			       \
	}								       \
	static struct counter_nrfx_data counter_##idx##_data;		       \
	static struct counter_nrfx_ch_data				       \
		counter##idx##_ch_data[CC_TO_ID(TIMER##idx##_CC_NUM)];	       \
	LOG_INSTANCE_REGISTER(LOG_MODULE_NAME, idx, CONFIG_COUNTER_LOG_LEVEL); \
	static const struct counter_nrfx_config nrfx_counter_##idx##_config = {\
		.info = {						       \
			.max_top_value = (TIMER##idx##_MAX_SIZE == 32) ?       \
					0xffffffff : 0x0000ffff,	       \
			.freq = TIMER_CLOCK /				       \
			   (1 << DT_NORDIC_NRF_TIMER_TIMER_##idx##_PRESCALER), \
			.flags = COUNTER_CONFIG_INFO_COUNT_UP,		       \
			.channels = CC_TO_ID(TIMER##idx##_CC_NUM),	       \
		},							       \
		.ch_data = counter##idx##_ch_data,			       \
		.timer = NRF_TIMER##idx,				       \
		LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx)	       \
	};								       \
	DEVICE_AND_API_INIT(timer_##idx,				       \
			    DT_NORDIC_NRF_TIMER_TIMER_##idx##_LABEL,	       \
			    counter_##idx##_init,			       \
			    &counter_##idx##_data,			       \
			    &nrfx_counter_##idx##_config.info,		       \
			    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,  \
			    &counter_nrfx_driver_api)


... ##idx## wurde durch 0 ersetzt. Ob das Sinn macht weiß ich nicht, aber jetzt kann man besser lesen was dieses Makro macht:

/* counter init function */
static int counter_0_init(struct device *dev)
{
	IRQ_CONNECT(DT_NORDIC_NRF_TIMER_TIMER_0_IRQ_0,
		    DT_NORDIC_NRF_TIMER_TIMER_0_IRQ_0_PRIORITY,
		    irq_handler, DEVICE_GET(timer_0), 0);

	static const struct counter_timer_config config = {
		.freq =	DT_NORDIC_NRF_TIMER_TIMER_0_PRESCALER,
		.mode = NRF_TIMER_MODE_TIMER,		//Hier müssen wir dann den Counter Mode einstellen
		.bit_width = (TIMER0_MAX_SIZE == 32) ? NRF_TIMER_BIT_WIDTH_32 : NRF_TIMER_BIT_WIDTH_16,
	};		
	
	return init_timer(dev, &config);
}


static struct counter_nrfx_data counter_idx_data;
static struct counter_nrfx_ch_data counter_idx_ch_data[CC_TO_ID(TIMER_0_CC_NUM)];
LOG_INSTANCE_REGISTER(LOG_MODULE_NAME, idx, CONFIG_COUNTER_LOG_LEVEL);


/* counter options */
static const struct counter_nrfx_config nrfx_counter_0_config = {
		.info = {
						.max_top_value = (TIMER_0_MAX_SIZE == 32) ? 0xffffffff : 0x0000ffff,
						.freq = TIMER_CLOCK / (1 << DT_NORDIC_NRF_TIMER_TIMER_idx_PRESCALER),
						.flags = COUNTER_CONFIG_INFO_COUNT_UP,
						.channels = CC_TO_ID(TIMER_idx_CC_NUM),
		},
		.ch_data = counteridx_ch_data,
		.timer = NRF_TIMER_idx,
		LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx)
};

/* Device and API init */
DEVICE_AND_API_INIT(timer_idx, DT_NORDIC_NRF_TIMER_TIMER_idx_LABEL, counter_idx_init,
		    						&counter_idx_data, &nrfx_counter_idx_config.info, PRE_KERNEL_1,
										CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &counter_nrfx_driver_api)


Jetzt können wir diese Structs zb im Programm

bwp_ws19/zephyr/samples/drivers/counter/alarm/src/main.c

einbinden, um einen counter zu initialisieren.


PPI Programmable Peripheral Interconnect


...