2024-04-10 12:21:46 +08:00
# DeviceDriver
Device driver for Linux platform, including various small sensors and actuators, along with application-level programs.
```bash
.
2024-04-26 09:45:12 +08:00
├── SConstruct
2024-04-10 12:21:46 +08:00
├── include
├── Kconfig
├── party
│ ├── framebuffer
│ │ ├── fbtools.c
│ │ └── fbtools.h
│ ├── linux_i2c
│ │ ├── linuxi2c.c
│ │ └── linuxi2c.h
│ ├── linux_spi
│ │ ├── linux_spi.c
│ │ └── linux_spi.h
│ ├── linux_uart
│ │ ├── linux_uart.c
│ │ └── linux_uart.h
│ └── ptmx
│ ├── ptmx_creat.c
│ └── ptmx_creat.h
```
## linux_uart
A non-standard C library for Linux, used to read and write to serial devices under the /dev directory. It facilitates serial communication on Linux.
The library is located in [components/DeviceDriver/party/linux_uart ](../../components/DeviceDriver/party/linux_uart ).
Activate the component.
Use the command `make menuconfig` to enable 'Enable DeviceDriver -> compile uart lib' and compile the UART library.
Permanently enable.
Add the following to the config_defaults.mk file in the project:
```
CONFIG_DEVICE_DRIVER_ENABLED=y
CONFIG_DEVICE_UART_ENABLED=y
```
Usage example: [examples/linux_uart ](../../examples/linux_uart )
API
```c
typedef struct {
int baud ; // UART baud rate.
int data_bits ; // UART data bits.
int stop_bits ; // UART stop bits.
char parity ; // parity.
} uart_t ;
/**
* @brief init uart
* @note
* @param [in] dev device name
* @param [in] param struct uart_t pointer
* @retval [return] [>0] fd index
* @retval [return] [<=0] fail code
*/
int linux_uart_init ( char * dev , void * param );
/**
* @brief close uart
* @note
* @param [in] fd fd index
* @retval
*/
void linux_uart_deinit ( int fd );
/**
* @brief Read data from UART.
* @note
* @param [in] fd fd index
* @param [in] cnt buff size
* @param [in] buf buff pointer
* @retval [return] [>0] The size of the read data.
* @retval [return] [<0] Read failure code.
*/
int linux_uart_read ( int fd , int cnt , void * buf );
/**
* @brief Send data from UART.
* @note
* @param [in] fd fd index
* @param [in] cnt buff size
* @param [in] buf buff pointer
* @retval [return] [>0] The size of the sent data.
* @retval [return] [<0] Send failure code.
*/
int linux_uart_write ( int fd , int cnt , void * buf );
```
## linux_i2c
A non-standard C library for Linux, used to read and write to i2c devices under the /dev directory. It facilitates i2c communication on Linux.
The library is located in [components/DeviceDriver/party/linux_i2c ](../../components/DeviceDriver/party/linux_i2c ).
Activate the component.
Use the command `make menuconfig` to enable 'Enable DeviceDriver -> compile i2c lib' and compile the i2c library.
Permanently enable.
Add the following to the config_defaults.mk file in the project:
```
CONFIG_DEVICE_DRIVER_ENABLED=y
CONFIG_DEVICE_I2C_ENABLED=y
```
Usage example: [examples/linux_i2c ](../../examples/linux_i2c )
API:
```c
/* I2c device */
typedef struct i2c_device {
int bus ; /* I2C Bus fd, return from i2c_open */
unsigned short addr ; /* I2C device(slave) address */
unsigned char tenbit ; /* I2C is 10 bit device address */
unsigned char delay ; /* I2C internal operation delay, unit millisecond */
unsigned short flags ; /* I2C i2c_ioctl_read/write flags */
unsigned int page_bytes ; /* I2C max number of bytes per page, 1K/2K 8, 4K/8K/16K 16, 32K/64K 32 etc */
unsigned int iaddr_bytes ; /* I2C device internal(word) address bytes, such as: 24C04 1 byte, 24C64 2 bytes */
} LINUXI2CDevice ;
/* Close i2c bus */
void linuxi2c_close ( int bus );
/*
** @brief : Open i2c bus
** #bus_name : i2c bus name such as: /dev/i2c-1
** @return : failed return -1, success return i2c bus fd
*/
int linuxi2c_open ( const char * bus_name );
/*
** @brief : Initialize LINUXI2CDevice with defualt value
** #device : LINUXI2CDevice struct
*/
void linuxi2c_init_device ( LINUXI2CDevice * device );
/*
** @brief : Get LINUXI2CDevice struct desc
** #device : LINUXI2CDevice struct
** #buf : Description message buffer
** #size : #buf size
** @return : return i2c device desc
*/
char * linuxi2c_get_device_desc ( const LINUXI2CDevice * device , char * buf , size_t size );
/* Select i2c device on i2c bus */
int linuxi2c_select ( int bus , unsigned long dev_addr , unsigned long tenbit );
/* I2C internal(word) address convert */
void linuxi2c_iaddr_convert ( unsigned int int_addr , unsigned int iaddr_bytes , unsigned char * addr );
/* I2C file I/O read, write
** @brief : read #len bytes data from #device #iaddr to #buf
** #device : LINUXI2CDevice struct, must call i2c_device_init first
** #iaddr : i2c_device internal address will read data from this address, no address set zero
** #buf : i2c data will read to here
** #len : how many data to read, lenght must less than or equal to buf size
** @return : success return read data length, failed -1
*/
ssize_t linuxi2c_read ( const LINUXI2CDevice * device , unsigned int iaddr , void * buf , size_t len );
ssize_t linuxi2c_write ( const LINUXI2CDevice * device , unsigned int iaddr , const void * buf , size_t len );
/* I2c ioctl read, write can set i2c flags
** i2c_ioctl_read/write
** I2C bus top layer interface to operation different i2c devide
** This function will call XXX:ioctl system call and will be related
** i2c-dev.c i2cdev_ioctl to operation i2c device.
** 1. it can choice ignore or not ignore i2c bus ack signal (flags set I2C_M_IGNORE_NAK)
** 2. it can choice ignore or not ignore i2c internal address
**
*/
ssize_t linuxi2c_ioctl_read ( const LINUXI2CDevice * device , unsigned int iaddr , void * buf , size_t len );
ssize_t linuxi2c_ioctl_write ( const LINUXI2CDevice * device , unsigned int iaddr , const void * buf , size_t len );
/*
** i2c_primitive_read/write
** I2C bus top layer interface to operation different i2c devide
** This function will call XXX:primitive system call and will be related
** i2c-dev.c i2cdev_ioctl to operation i2c device.
** 1. it can choice ignore or not ignore i2c bus ack signal (flags set I2C_M_IGNORE_NAK)
** 2. it can choice ignore or not ignore i2c internal address
**
*/
ssize_t linuxi2c_primitive_read ( const LINUXI2CDevice * device , void * offset , size_t offset_len , void * buf , size_t buf_len );
ssize_t linuxi2c_primitive_write ( const LINUXI2CDevice * device , void * offset , size_t offset_len , void * buf , size_t buf_len );
```
## linux_spi
A non-standard C library for Linux, used to read and write to spi devices under the /dev directory. It facilitates spi communication on Linux.
The library is located in [components/DeviceDriver/party/linux_spi ](../../components/DeviceDriver/party/linux_spi ).
Activate the component.
Use the command `make menuconfig` to enable 'Enable DeviceDriver -> compile spi lib' and compile the i2c library.
Permanently enable.
Add the following to the config_defaults.mk file in the project:
```
CONFIG_DEVICE_DRIVER_ENABLED=y
CONFIG_DEVICE_SPI_ENABLED=y
```
Usage example: [examples/linux_spi ](../../examples/linux_spi )
API:
```c
// open and init SPIdev
// * spi_mode may have next mask: SPI_LOOP | SPI_CPHA | SPI_CPOL |
// SPI_LSB_FIRST | SPI_CS_HIGH SPI_3WIRE | SPI_NO_CS | SPI_READY
// or 0 by zefault
int spi_init ( spi_t * self ,
const char * device , // filename like "/dev/spidev0.0"
int mode , // SPI_ * ( look "linux/spi/spidev.h" )
int bits , // bits per word (usually 8)
int speed ); // max speed [Hz]
//----------------------------------------------------------------------------
// sets mode on existing spi
int spi_set_mode ( spi_t * self , int mode );
//----------------------------------------------------------------------------
// sets speed on existing spi
int spi_set_speed ( spi_t * self , int speed );
//----------------------------------------------------------------------------
// close SPIdev file and free memory
void spi_free ( spi_t * self );
//----------------------------------------------------------------------------
// read data from SPIdev
int spi_read ( spi_t * self , void * rx_buf , int len );
//----------------------------------------------------------------------------
// write data to SPIdev
int spi_write ( spi_t * self , const void * tx_buf , int len );
//----------------------------------------------------------------------------
// read and write `len` bytes from/to SPIdev
int spi_exchange ( spi_t * self , void * rx_buf , const void * tx_buf , int len );
//----------------------------------------------------------------------------
// read data from SPIdev from specific register address
int spi_read_reg8 ( spi_t * self , uint8_t reg_addr , void * rx_buf , int len );
//----------------------------------------------------------------------------
// write data to SPIdev to specific register address
int spi_write_reg8 ( spi_t * self , uint8_t reg_addr , const void * tx_buf , int len );
```
## framebuffer
A non-standard C library for Linux, used to read and write to framebuffer devices under the /dev directory. It facilitates framebuffer communication on Linux.
The library is located in [components/DeviceDriver/party/framebuffer ](../../components/DeviceDriver/party/framebuffer ).
Activate the component.
Use the command `make menuconfig` to enable 'Enable DeviceDriver -> compile framebuffer lib' and compile the i2c library.
Permanently enable.
Add the following to the config_defaults.mk file in the project:
```
CONFIG_DEVICE_DRIVER_ENABLED=y
CONFIG_DEVICE_FRAMEBUFFER_ENABLED=y
```
Usage example: [examples/linux_framebuffer ](../../examples/linux_framebuffer )
API:
```c
/* a framebuffer device structure */
typedef struct fbdev {
int fb ;
unsigned long fb_mem_offset ;
unsigned long fb_mem ;
struct fb_fix_screeninfo fb_fix ;
struct fb_var_screeninfo fb_var ;
char dev [ 20 ];
} FBDEV , * PFBDEV ;
/* open & init a frame buffer */
/* to use this function,
you must set FBDEV.dev="/dev/fb0"
or "/dev/fbX" */
/* it's your frame buffer. */
int fb_open ( PFBDEV pFbdev );
/*close a frame buffer*/
int fb_close ( PFBDEV pFbdev );
/*get display depth*/
int get_display_depth ( PFBDEV pFbdev );
/*draw rgb888 or rgb565 to framebuffer.color=24/16*/
void fb_draw_img ( PFBDEV pFbdev , int w , int h , int color , void * buf );
void fb_put_pixel ( PFBDEV pFbdev , int x , int y , unsigned int color );
/*full screen clear */
void fb_memset ( void * addr , int c , size_t len );
```
## ptmx
A non-standard C library for Linux, used to read and write to pts devices under the /dev directory. Standard input/output for linux virtual terminals to operate other processes. Useful in daemons.
The library is located in [components/DeviceDriver/party/ptmx ](../../components/DeviceDriver/party/ptmx ).
Activate the component.
Use the command `make menuconfig` to enable 'Enable DeviceDriver -> compile ptmx lib' and compile the i2c library.
Permanently enable.
Add the following to the config_defaults.mk file in the project:
```
CONFIG_DEVICE_DRIVER_ENABLED=y
CONFIG_DEVICE_PTMX_ENABLED=y
```
Usage example: [examples/ptxm_tcp_tran ](../../examples/ptxm_tcp_tran )
API:
```c
typedef enum {
PTMX_STOP = 0 ,
PTMX_RUN = 1
} ptmx_status_t ;
/*msg call back */
typedef void ( * msg_call_back_t )( const char * , int );
/* a ptmx device structure */
struct ptmx_creat_t
{
int master_ptmx ;
char slave_ptmx_name [ 50 ];
int ptmx_status ;
pthread_t ptmx_loop_handler_d ;
msg_call_back_t call ;
int buff_size ;
};
/*creat a ptmx struct ptmx_creat_t */
struct ptmx_creat_t * ptmx_creat ();
/*destroy ptmx struct ptmx_creat_t */
int ptmx_destroy ( struct ptmx_creat_t ** p );
/*open one ptmx*/
int ptmx_open ( struct ptmx_creat_t * self );
/*set msg callback fun*/
void ptmx_set_msg_callback ( struct ptmx_creat_t * self , msg_call_back_t fun );
void * ptmx_loop_handler ( void * par );
/*exit one ptmx*/
void ptmx_exit ( struct ptmx_creat_t * self );
#ifdef __cplusplus
class ptmx
{
private :
struct ptmx_creat_t ptm ;
public :
ptmx ();
/*open ptmx*/
int open ();
/*set ptmx read buff*/
void set_buff_size ( int size );
/*set msg callback fun*/
void set_msg_call_back ( msg_call_back_t msg );
std :: string get_slave_ptmx_name ();
void exit ();
~ ptmx ();
};
#endif
```