| 1 | = GIET-VM / TTY Driver = |
| 2 | |
| 3 | [[PageOutline]] |
| 4 | |
| 5 | The [source:soft/giet_vm/giet_drivers/tty_driver.c tty_driver.c] and [source:soft/giet_vm/giet_drivers/tty_driver.h tty_driver.h] files define the TTY driver. |
| 6 | |
| 7 | This ''vci_multi_tty'' component is a multi-terminals controller. It is an ''external'' peripheral. |
| 8 | |
| 9 | The total number of terminals must be defined by the configuration parameter NB_TTY_CHANNELS in the hard_config.h file. |
| 10 | |
| 11 | The kernel terminal is TTY[0]. The "user" TTYs are allocated to applications by the GIET in the boot phase, as defined in the mapping_info data structure. The corresponding tty_id must be stored in the context of the task by the boot code. |
| 12 | |
| 13 | The SEG_TTY_BASE address must be defined in the hard_config.h file. |
| 14 | |
| 15 | The virtual base address of the associated segment is vbase = SEG_TTY_BASE + cluster_io << 32 |
| 16 | |
| 17 | The addressable registers map are defined [source:soft/giet_vm/giet_drivers/tty_driver.h here]. |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | === unsigned int '''_tty_get_register'''( unsigned int channel, unsigned int index ) === |
| 25 | This low level function returns the value of register (channel / index). |
| 26 | |
| 27 | === void '''_tty_set_register'''( unsigned int channel, unsigned int index, unsigned int value ) === |
| 28 | This low level function set a new value in register (channel / index). |
| 29 | |
| 30 | === unsigned int '''_tty_write'''( const char* buffer, unsigned int length, unsigned int channel ) === |
| 31 | This non-blocking function writes a character string from a fixed-length buffer to a TTY terminal identified by the channel argument. This function is intended to be used to handle a system call, and should not be used by the kernel for log messages on TTY 0. If channel argument is 0xFFFFFFFF, the TTY index is found in the task context. |
| 32 | It is non blocking: it tests the TTY_STATUS register, and stops the transfer as soon as the TTY_STATUS[WRITE] bit is set. |
| 33 | Returns the number of characters that have been written. |
| 34 | |
| 35 | === unsigned int '''_tty_read'''( char* buffer, unsigned int length, unsigned int channel ) === |
| 36 | This non-blocking function fetches one character from the terminal identified by the channel argument. If the channel argument is 0xFFFFFFFF, the channel index is obtained from the current task context. |
| 37 | It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been filled by the TTY_ISR. |
| 38 | It test the _tty_rx_full[tty_id] variable, read the _tty_rx_buf[tty_id] buffer, writes this character to the target buffer, and resets the_tty_rx_full[tty_id] register. The length argument is not used. |
| 39 | Returns the number of characters that have been read (0/1). |
| 40 | |
| 41 | === void '''_tty_get_lock'''( unsigned int channel, unsigned int* save_sr_ptr ) === |
| 42 | This blocking function try to take the lock protecting exclusive access to TTY terminal identified by the "channel" argument. |
| 43 | It enters a critical section before taking the lock, and save the SR value at address defined by the ''save_sr_ptr'' argument. |
| 44 | It returns only when the lock has been successfully taken. |
| 45 | |
| 46 | === void '''_tty_release_lock'''( unsigned int channel, unsigned int* save_sr_ptr ) === |
| 47 | This function releases the lock protecting exclusive access to TTY terminal identified by the channel argument. |
| 48 | It exit the critical section after lock release, and restore SR value from address defined by the ''save_sr_ptr'' argument. |
| 49 | |
| 50 | === void '''_tty_rx_isr'''( unsigned int irq_type, unsigned int irq_id, unsigned int channel ) === |
| 51 | This Interrupt Service Routine handles the IRQ signaling that the RX buffer is not empty. IT can be an HWI or an SWI. |
| 52 | There is one communication buffer _tty_rx_buf[i] and one synchronisation variable _tty_rx_full[i] per channel. |
| 53 | It does nothing if the TTY_RX buffer is empty, or if the kernel buffer is full when the ISR is called. |
| 54 | |
| 55 | === void '''_tty_tx_isr'''( unsigned int irq_type, unsigned int irq_id, unsigned int channel ) === |
| 56 | This Interrupt Service Routine handles the IRQ signaling that the TX buffer is empty. IT can be an HWI or an SWI. |
| 57 | There is one communication buffer _tty_rx_buf[i] and one synchronisation variable _tty_rx_full[i] per channel. |
| 58 | A character is lost if the buffer is full when the ISR is executed. |
| 59 | It is not implemented yet... |
| 60 | |