完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
(1) 驱动调试: 1.1) dts 配置: 1.2 添加kconfig 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 << 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 errorn”); 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 errorn”); 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 errorn”); 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 errorn”,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 = 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%xn”,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文件 2.2 在frameworks/base/core/java/android/os/目录下 添加ITempMlsSensor.aidl 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 2.5 添加com_android_server_TempMlsSensor.cpp frameworksbaseservicescorejni在这目录下 内容如下: /*
#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 ***yteArray TempMlsSensorRead_native(JNIEnv* env , jobject /* clazz */,jint length) { ***yteArray 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); }; #endif /HARDWARE_LED_HAL_H/ 3.2 修改hardware/libhardware/modules/Android.mk 修改mlx90640目录下的Android.mk hardwarelibhardwaremodulesmlx90640目录下文件浏览 (4) app 部分:还正在调试 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
533 浏览 0 评论
803 浏览 1 评论
700 浏览 1 评论
1926 浏览 1 评论
3171 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 13:41 , Processed in 0.689968 second(s), Total 84, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号