SPI模块的HAL访问Linux内核驱动程序
linux-dash
A beautiful web dashboard for Linux
项目地址:https://gitcode.com/gh_mirrors/li/linux-dash
免费下载资源
·
1、在hardware/libhardware/modules下创建spihal文件夹。
2、在spihal中创建spihal.c、Android.mk文件。
spihal.c
#define LOG_TAG "SpiStub"
#include <hardware/hardware.h>
#include <hardware/spihal.h>
#include <fcntl.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include "spidev.h"
#define DEVICE_NAME "/dev/spidev1.0"
#define MODULE_NAME "spidev1.0"
#define MODULE_AUTHOR "HSL"
/* 函数声明 */
static int hal_spi_init(struct spi_device_t *dev);
static int hal_spi_read(struct spi_device_t *dev, unsigned char *data, int size);
static int hal_spi_write(struct spi_device_t *dev, unsigned char *data, int size);
static int hal_spi_open(const struct hw_module_t *module, char const *name, struct hw_device_t **device);
static int hal_spi_close(struct hw_device_t *device);
/* 定义变量 */
static uint8_t mode = 0;
static uint8_t bits = 8;
static uint32_t speed = 600*1000;
static uint16_t delay = 0;
struct spi_ioc_transfer spi_tr;
/* 定义初始化spi */
static int hal_spi_init(struct spi_device_t *dev)
{
/* mode */
if(ioctl(dev->fd, SPI_IOC_WR_MODE, &mode) < 0)
{
ALOGE("SpiStub: SPI wr_mode error\n");
}
else
ALOGE("SpiStub: SPI wr_mode ok\n");
if(ioctl(dev->fd, SPI_IOC_RD_MODE, &mode) < 0)
{
ALOGE("SpiStub: SPI rd_mode error\n");
}
else
ALOGE("SpiStub: SPI rd_mode ok\n");
/* bits */
if(ioctl(dev->fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0)
{
ALOGE("SpiStub: SPI wr_bits_per_word error\n");
}
else
ALOGE("SpiStub: SPI wr_bit_per_word ok\n");
if(ioctl(dev->fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
{
ALOGE("SpiStub: SPI rd_bit_per_word error\n");
}
else
ALOGE("SpiStub: SPI rd_bit_per_word ok\n");
/* speed */
if(ioctl(dev->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
{
ALOGE("SpiStub: SPI wr_max_speed_hz error\n");
}
else
ALOGE("SpiStub: SPI wr_max_speed_hz ok\n");
if(ioctl(dev->fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0)
{
ALOGE("SpiStub: SPI rd_max_speed_hz error\n");
}
else
ALOGE("SpiStub: SPI rd_max_speed_hz ok\n");
return 0;
}
/* 定义spi读函数 */
static int hal_spi_read(struct spi_device_t *dev, unsigned char *data, int size)
{
spi_tr.rx_buf = (unsigned long)data;
spi_tr.len = size;
spi_tr.delay_usecs = delay;
if((ioctl(dev->fd, SPI_IOC_MESSAGE(1), &spi_tr)) < 0)
{
ALOGE("SpiStub: SPI read error!\n");
return -1;
}
return 0;
}
/* 定义spi写函数 */
static int hal_spi_write(struct spi_device_t *dev, unsigned char *data, int size)
{
spi_tr.tx_buf = (unsigned long)data;
spi_tr.len = size;
spi_tr.delay_usecs = delay;
if((ioctl(dev->fd, SPI_IOC_MESSAGE(1), &spi_tr)) < 1)
{
ALOGE("SpiStub: SPI write error!\n");
return -1;
}
return 0;
}
/* 定义spi设备打开函数 */
static int hal_spi_open(const struct hw_module_t *module, char const *name, struct hw_device_t **device)
{
struct spi_device_t *dev;
dev = (struct spi_device_t *)malloc(sizeof(struct spi_device_t));
if(!dev)
{
ALOGE("SpiStub: failed malloc space!\n");
return -1;
}
memset(dev, 0, sizeof(struct spi_device_t));
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = (struct hw_module_t *)module;
dev->common.close = hal_spi_close;
dev->spi_init = hal_spi_init;
dev->spi_read = hal_spi_read;
dev->spi_write = hal_spi_write;
if((dev->fd = open(DEVICE_NAME, O_RDWR | O_NONBLOCK)) < 0)
{
ALOGE("SpiStub: failed spi open .\n");
free(dev);
return -1;
}
ALOGE("SpiStub: open /dev/spi1.0 successfuly .\n");
*device = &(dev->common);
return 0;
}
/* 定义spi设备关闭函数 */
static int hal_spi_close(struct hw_device_t *device)
{
struct spi_device_t *dev = (struct spi_device_t *)device;
if(dev)
{
ALOGE("SpiStub: close /dev/spi1.0\n");
close(dev->fd);
free(dev);
}
return 0;
}
/* 模块方法表 */
static struct hw_module_methods_t spi_module_methods =
{
open:hal_spi_open
};
/* 模块实例变量 */
struct spi_module_t HAL_MODULE_INFO_SYM =
{
common:
{
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = SPI_HARDWARE_MODULE_ID,
.name = MODULE_NAME,
.author = MODULE_AUTHOR,
.methods = &spi_module_methods,
}
};
<pre class="html" name="code">
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := spihal.c
LOCAL_MODULE := spi_ts.default
include $(BUILD_SHARED_LIBRARY)
3、把源码kernel_imx/drivers/spi下spidev.c文件复制到自己创建spihal文件夹下以便调用。
4、在hardware/libhardware/include/hardware目录下创建spihal.h文件
spihal.h
#ifndef __SPIHAL_H__
#define __SPIHAL_H__
#include <hardware/hardware.h>
#include <fcntl.h>
#include <errno.h>
__BEGIN_DECLS
/* 定义模块ID */
#define SPI_HARDWARE_MODULE_ID "spi_ts"
/* 在HAL层规定不能直接使用hw_module_t结构体,因此做一个封装 */
struct spi_module_t
{
struct hw_module_t common;
};
/* 定义一个spi控制结构体 */
struct spi_device_t
{
struct hw_device_t common;
int fd;//设备文件描述符
int (*spi_init)(struct spi_device_t *dev);//spi初始化
int (*spi_read)(struct spi_device_t *dev,unsigned char *data, int size);//从spi里读数据
int (*spi_write)(struct spi_device_t *dev,unsigned char *data, int size);//往spi里发数据
};
__END_DECLS
#endif
5、在源码主目录下编译
执行命令:mmm hardware/libhardware/include/hardware/spihal
6、把生成的该库放到开发板的/system/lib/hw目录下
加执行权限 chown root spi_ts.default.so
chmod 777 spi_ts.default.so
注意:在Android.mk中生成的库名字(LOCAL_MODULE := spi_ts.default)一定要和模块ID相对应(#define SPI_HARDWARE_MODULE_ID "spi_ts")否则在运行的时候JNI层无法访问HAL层的库
GitHub 加速计划 / li / linux-dash
6
1
下载
A beautiful web dashboard for Linux
最近提交(Master分支:4 个月前 )
186a802e
added ecosystem file for PM2 4 年前
5def40a3
Add host customization support for the NodeJS version 4 年前
更多推荐
已为社区贡献14条内容
所有评论(0)