| | 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 | |