RK3288|RK3288 android7.1 mlx90640温度传感器调试

(1) 驱动调试:
1.1) dts 配置:
RK3288|RK3288 android7.1 mlx90640温度传感器调试
文章图片

1.2 添加kconfig
RK3288|RK3288 android7.1 mlx90640温度传感器调试
文章图片

1.3 修改makefile
1.4 添加tmp_mlx90640.c
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef CONFIG_OF_GPIO
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DRIVER_NAME “mlx90640”
#define MLX90640_IOCTL_MAGIC ‘m’
#define MLX90640_GET_DATA _IOR(MLX90640_IOCTL_MAGIC, 1, int *)
#define MLX90640_SET_DATA _IOR(MLX90640_IOCTL_MAGIC, 2, int *)
#define DATA_LENGTH 1664
struct mlx90640_chip {
struct mutex i2c_lock;
struct i2c_client *client;
const char *names;
};
struct MLX90640_R_DATA{
uint16_t reg;
uint16_t size;
uint16_t buff[DATA_LENGTH];
};
struct MLX90640_W_DATA{
uint16_t reg;
uint16_t size;
uint16_t data;
};
struct mlx90640_chip *gchip = NULL;
static int mlx90640_open(struct inode *inode, struct file *filp)
{
return 0;
}
int mlx90640_release(struct inode *inode, struct file *filp)
{
return 0;
}
static int i2c_master_recv_(struct i2c_client *client,char *msgbuf,uint16_t *data,uint16_t nMemAdddressRead)
{
struct i2c_msg msgs[2];
struct i2c_adapter *adap = client->adapter;
int ret;
uint16_t bytesRemaining = nMemAdddressRead * 2;
int cnt = 0;
int i = 0;
uint16_t *p = data;
char i2cData[DATA_LENGTH];

msgs[0].addr = client->addr; msgs[0].flags = I2C_M_TEN; /* write */ msgs[0].len = 2; msgs[0].buf = msgbuf; msgs[1].addr = client->addr; msgs[1].flags = I2C_M_RD | I2C_M_NOSTART; msgs[1].len = bytesRemaining; msgs[1].buf = i2cData; memset(i2cData,0,bytesRemaining); ret = i2c_transfer(adap,&msgs[0],2); for(cnt = 0; cnt < nMemAdddressRead; cnt++){ i = cnt << 1; *p++ = ((uint16_t)i2cData[i] << 8) | i2cData[i+1]; } return 0;

}
static int mlx90640_write_data(struct i2c_client *client,uint16_t reg,uint16_t buf)
{
int ret = 0;
u8 abuf[4];
abuf[0] = reg >> 8;
abuf[1] = reg;
abuf[2] = buf >> 8;
abuf[3] = buf;
ret = i2c_master_send(client,abuf,4);
return ret;
}
static int mlx90640_read_data(struct i2c_client *client,uint16_t reg,uint16_t *data,uint16_t nMemAdddressRead)
{
int rc;
u8 msgbuf[2];
msgbuf[0] = reg >> 8;
msgbuf[1] = reg;
rc = i2c_master_recv_(client,msgbuf,data,nMemAdddressRead);
return 0;
}
static long mlx90640_ioctl(struct file file, unsigned int cmd,unsigned long arg)
{
struct MLX90640_R_DATA data;
struct MLX90640_W_DATA w_data;
mutex_lock(&gchip->i2c_lock);
switch(cmd){
case MLX90640_GET_DATA:
if(copy_from_user((void
)&data,(void __user*)arg,sizeof(struct MLX90640_R_DATA))){
printk(“MLX90640_ioctl SE_IOC_GET_DATA copy_from_user error\n”);
mutex_unlock(&gchip->i2c_lock);
return -EFAULT;
}
if(mlx90640_read_data(gchip->client,data.reg,&data.buff[0],data.size) != 0){
printk(“MLX90640_ioctl read data failed,reg:0x%x ,size:%d \n”,data.reg,data.size);
mutex_unlock(&gchip->i2c_lock);
return -EFAULT;
}
if(copy_to_user((void __user*)arg,(void*)&data,sizeof(struct MLX90640_R_DATA))){
printk(“MLX90640_ioctl SE_IOC_GET_DATA copy_to_user error\n”);
mutex_unlock(&gchip->i2c_lock);
return -EFAULT;
}
break;
case MLX90640_SET_DATA:
if(copy_from_user((void*)&w_data,(void __user*)arg,sizeof(struct MLX90640_W_DATA))){
printk(“MLX90640_ioctl SE_IOC_SET_DATA copy_from_user error\n”);
mutex_unlock(&gchip->i2c_lock);
return -EFAULT;
}
mlx90640_write_data(gchip->client,w_data.reg,w_data.data);
break;
default:
printk(“MLX90640_ioctl cmd:0x%x error\n”,cmd);
break;
}
mutex_unlock(&gchip->i2c_lock);
return 0;
}
static struct file_operations mlx90640_fops =
{
.owner = THIS_MODULE,
.open = mlx90640_open,
.release = mlx90640_release,
.unlocked_ioctl = mlx90640_ioctl,
};
static struct miscdevice mlx90640_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = “mlx90640”,
.fops = &mlx90640_fops,
};
static int mlx90640_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
struct mlx90640_chip *chip;
struct MLX90640_R_DATA data;
struct i2c_adapter *adapter = client->adapter;
int ret;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)){ return -ENODEV; } chip = devm_kzalloc(&client->dev,sizeof(struct mlx90640_chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->names = DRIVER_NAME; chip->client = client; mutex_init(&chip->i2c_lock); gchip = chip; data.reg = 0x8000; data.size = 1; mlx90640_read_data(gchip->client,data.reg,&data.buff[0],data.size);

#if 0
struct MLX90640_W_DATA w_data;
w_data.reg = 0x800D;
w_data.size = 1;
w_data.data = https://www.it610.com/article/0x1291;
MLX90640_write_data(gchip->client,w_data.reg,w_data.data);
#endif
data.reg = 0x800D;
mlx90640_read_data(gchip->client,data.reg,&data.buff[1],data.size);
printk(“harris mlx90640_probe read 0x8000->0x%x 0x800D->0x%x\n”,data.buff[0],data.buff[1]);
ret = misc_register(&mlx90640_dev); return 0;

}
static int mlx90640_remove(struct i2c_client *client)
{
return 0;
}
static const struct i2c_device_id mlx90640_dt_id[] = {
{“mlx90640”, 0},
{ }
};
MODULE_DEVICE_TABLE(i2c, mlx90640_dt_id);
static const struct of_device_id mlx90640_dt_ids[] = {
{ .compatible = “mlx90640”, },
{ }
};
MODULE_DEVICE_TABLE(i2c, mlx90640_dt_ids);
static struct i2c_driver mlx90640_driver = {
.probe = mlx90640_probe,
.remove = mlx90640_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(mlx90640_dt_ids),
},
.id_table = mlx90640_dt_id,
};
static int __init mlx90640_init(void)
{
return i2c_add_driver(&mlx90640_driver);
}
static void __exit mlx90640_exit(void)
{
i2c_del_driver(&mlx90640_driver);
}
subsys_initcall(mlx90640_init);
module_exit(mlx90640_exit);
MODULE_AUTHOR(“xxx”);
MODULE_DESCRIPTION(“i2c driver for mlx90640”);
MODULE_LICENSE(“GPL”);
(2) jni 部分:
2.1 修改frameworks/base/Android.mk 文件,添加需要编译的aidl文件
RK3288|RK3288 android7.1 mlx90640温度传感器调试
文章图片

2.2 在frameworks/base/core/java/android/os/目录下 添加ITempMlsSensor.aidl
RK3288|RK3288 android7.1 mlx90640温度传感器调试
文章图片

2.3 添加aidl 文件后,编译后会生成ITempMlsSensor.java 重写里面的方法。
frameworks/base/services/core/java/com/android/server 目录下添加TempMlsSensor.java文件。内容如下:
package com.android.server;
import android.util.Slog;
import android.os.ITempMlsSensor;
import android.content.Context;
public class TempMlsSensor extends ITempMlsSensor.Stub{
private static final String TAG = “TempMlsSensor”;
private final Context mContext; public static final String TEMPMLSSENSOR_STATS_SERVICE = "TempMlsSensor"; public TempMlsSensor(Context context) { Slog.d(TAG,"TempMlsSensor"); mContext = context; }@Override public int TempMlsSensorOpen() throws android.os.RemoteException { return nativeTempMlsSensorOpen(); }@Override public int TempMlsSensorWrite(int value) throws android.os.RemoteException { return nativeTempMlsSensorWrite(value); }@Override public int TempMlsSensorReadValue() throws android.os.RemoteException { return nativeTempMlsSensorReadValue(); }@Override public byte[] TempMlsSensorRead(int length) throws android.os.RemoteException{return nativeTempMlsSensorRead(length); }@Override public int TempMlsSensorIoctl(int cmd, int value) throws android.os.RemoteException { return nativeTempMlsSensorIoctl(cmd,value); }@Override public int TempMlsSensorClose() throws android.os.RemoteException { return nativeTempMlsSensorClose(); }public static native int nativeTempMlsSensorOpen(); public static native int nativeTempMlsSensorWrite(int value); public static native byte[] nativeTempMlsSensorRead(int length); public static native int nativeTempMlsSensorReadValue(); public static native int nativeTempMlsSensorIoctl(int cmd,int value); public static native int nativeTempMlsSensorClose();

}
2.4 修改frameworks/base/service/core/jni/Android.mk
RK3288|RK3288 android7.1 mlx90640温度传感器调试
文章图片

2.5 添加com_android_server_TempMlsSensor.cpp
\frameworks\base\services\core\jni\在这目录下
内容如下:
/*
  • Copyright ? 2009 The Android Open Source Project
  • Licensed under the Apache License, Version 2.0 (the “License”);
  • you may not use this file except in compliance with the License.
  • You may obtain a copy of the License at
  • http://www.apache.org/licenses/LICENSE-2.0

  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an “AS IS” BASIS,
  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • See the License for the specific language governing permissions and
  • limitations under the License.
    */
#define LOG_TAG “TempMlsSensor”
#include “jni.h”
#include “JNIHelp.h”
#include “android_runtime/AndroidRuntime.h”
#include
#include
#include
#include
#include
#include
#include
#define MLX90640_IOCTL_MAGIC ‘m’
#define MLX90640_GET_DATA _IOR(MLX90640_IOCTL_MAGIC, 1, int *)
#define MLX90640_SET_DATA _IOR(MLX90640_IOCTL_MAGIC, 2, int *)
int mlx_fd=-1 ;
namespace android
{
static mlx90640_device_t *g_device;
static int init_native(mlx90640_device_t **device)
{
int ret ;
hw_module_t *module;
mlx90640_device_t *mlx90640_device;
ret=hw_get_module(MLX90640_HARDWARE_MODULE_ID,(hw_module_t const **)&module);
if(ret)
{
return -1;

}
ret = module->methods->open(module,NULL,(hw_device_t **)&mlx90640_device);
if(ret<0)
return -1;
*device=mlx90640_device;

return 0;
}
static jint TempMlsSensorOpen_native(JNIEnv* /* env /, jobject / clazz */)
{
init_native(&g_device); g_device->mlx90640_open(g_device); return 0;

}
static jint TempMlsSensorWrite_native(JNIEnv* /* env /, jobject / clazz */,jint value)
{
return 0;

}
static jbyteArray TempMlsSensorRead_native(JNIEnv* env , jobject /* clazz */,jint length)
{
jbyteArray byteArray = env->NewByteArray(768);
return byteArray;

}
static jint TempMlsSensorRead_native_value(JNIEnv* /* env /, jobject / clazz */)
{
return g_device->mlx90640_read(g_device);

}
//*/
static jint TempMlsSensorIoctl_native(JNIEnv* /* env /, jobject / clazz */,jint cmd ,jint value)
{
return 0;
}
static jint TempMlsSensorClose_native(JNIEnv* /* env /, jobject / clazz */)
{
//close(mlx_fd); return 0;

}
static const JNINativeMethod method_table[] = {
{ “nativeTempMlsSensorOpen”, “()I”, (void*)TempMlsSensorOpen_native },
{ “nativeTempMlsSensorWrite”, “(I)I”, (void*)TempMlsSensorWrite_native },
{ “nativeTempMlsSensorRead”, “(I)[B”, (void*)TempMlsSensorRead_native },
{ “nativeTempMlsSensorReadValue”, “()I”, (void*)TempMlsSensorRead_native_value },
{ “nativeTempMlsSensorIoctl”, “(II)I”, (void*)TempMlsSensorIoctl_native },
{ “nativeTempMlsSensorClose”, “()I”, (void*)TempMlsSensorClose_native },
};
int register_android_server_TempMlsSensor(JNIEnv *env)
{
return jniRegisterNativeMethods(env, “com/android/server/TempMlsSensor”,
method_table, NELEM(method_table));
}
};
(3) hal 部分:
3.1 添加mlx90640.h文件
hardware/libhardware/include/hardware/mlx90640.h
#ifndef HARDWARE_MLX90640_HAL_H
#define HARDWARE_MLX90640_HAL_H
#define MLX90640_HARDWARE_MODULE_ID “mlx90640”
#define MLX90640_API_VERSION HARDWARE_MODULE_API_VERSION(1,0)
struct mlx90640_device_t {
struct hw_device_t common;
int fd; int (*mlx90640_open)(struct mlx90640_device_t *device); int (*mlx90640_ioctl)(struct mlx90640_device_t *device, int which, int status); void (*mlx90640_close)(struct mlx90640_device_t *device); int (*mlx90640_read)(struct mlx90640_device_t *device);

};
【RK3288|RK3288 android7.1 mlx90640温度传感器调试】#endif /HARDWARE_LED_HAL_H/
3.2 修改hardware/libhardware/modules/Android.mk
RK3288|RK3288 android7.1 mlx90640温度传感器调试
文章图片

修改mlx90640目录下的Android.mk
RK3288|RK3288 android7.1 mlx90640温度传感器调试
文章图片

\hardware\libhardware\modules\mlx90640目录下文件浏览
RK3288|RK3288 android7.1 mlx90640温度传感器调试
文章图片
整个开发包连接
https://download.csdn.net/download/baidu_37552881/12495631
(4) app 部分:还正在调试
创建QQ技术交流群,进QQ技术交流,大家一起交流RK,Mstar平台。QQ群:712288614

    推荐阅读