| | 1 | = GIET-VM / BDV Driver = |
| | 2 | |
| | 3 | [[PageOutline]] |
| | 4 | |
| | 5 | The [source:soft/giet_vm/giet_drivers/tim_driver.c tim_driver.c] and [source:soft/giet_vm/giet_drivers/tim_driver.h tim_driver.h] files define the TIM driver. |
| | 6 | |
| | 7 | The ''vci_multi_timer'' component is a multi-channels timer controller. |
| | 8 | |
| | 9 | For the GIET, it is an ''internal'' peripheral, replicated in each cluster. |
| | 10 | |
| | 11 | The SEG_TIM_BASE address must be defined in the hard_config.h file. |
| | 12 | |
| | 13 | There is two types of timers: |
| | 14 | * '''kernel timers''' : one per processor, used for context switch. The local_id is in [0, NB_PROCS_MAX-1]. |
| | 15 | * '''user timers''' : requested by the task in the mapping_info data structure. The local_id is in [NB_PROCS_MAX, NB_PROCS_MAX + NB_TIM_CHANNELS -1]. |
| | 16 | |
| | 17 | The global timer index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id |
| | 18 | |
| | 19 | The virtual base address of the associated segment is: vbase = SEG_TIM_BASE + cluster_xy * PERI_CLUSTER_INCREMENT |
| | 20 | |
| | 21 | The SEG_TIM_BASE, PERI_CLUSTER_INCREMENT, NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file. |
| | 22 | |
| | 23 | The addressable registers map is defined [source:soft/giet_vm/giet_drivers/tim_driver.h here]. |
| | 24 | |
| | 25 | |
| | 26 | |
| | 27 | |
| | 28 | === void '''_timer_start'''( unsigned int cluster_xy, unsigned int local_id, unsigned int period ) === |
| | 29 | This function activates a timer in the vci_timer component by writing in the proper register the period value. |
| | 30 | It can be used by both the kernel to initialise a "system" timer, or by a task (through a system call) to configure an "user" timer. |
| | 31 | |
| | 32 | === void '''_timer_stop'''( unsigned int cluster_xy, unsigned int local_id ) === |
| | 33 | This function desactivates a timer in the vci_timer component by writing in the proper register. |
| | 34 | |
| | 35 | === void '''_timer_reset_irq'''( unsigned int cluster_xy, unsigned int local_id ) === |
| | 36 | This function acknowlegge a timer interrupt in the vci_timer component by writing in the proper register. |
| | 37 | It can be used by both the isr_switch() for a "system" timer, or by the _isr_timer() for an "user" timer. |
| | 38 | |
| | 39 | === void '''_timer_reset_cpt'''( unsigned int cluster_xy, unsigned int local_id) === |
| | 40 | This function resets the timer counter. To do so, we re-write the period in the proper register, what causes the count to restart. |
| | 41 | This function is called during a context switch (user or preemptive). |
| | 42 | |
| | 43 | === void '''_timer_isr'''( unsigned int irq_type, unsigned int irq_id, unsigned int channel ) === |
| | 44 | This Interrupt Service Routine handles the IRQs generated by the "user" timers. |
| | 45 | The IRQs generated by the "system" timers should be handled by _isr_switch(). |
| | 46 | It can be a HWI or a PTI. The channel argument is the timer local index. |
| | 47 | The ISR acknowledges the IRQ, registers the event in the proper entry |
| | 48 | of the _user_timer_event[] array, and a log message is displayed on TTY0. |