Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android JNI用於驅動測試

Android JNI用於驅動測試

編輯:關於Android編程

硬件平台:S3C6410

操作系統:Ubuntu、windows

板子系統:Android

開發工具:jdk,ndk,eclipse

本次測試從linux內核模塊編譯開始,以S3C6410的pwm驅動為例。

pwm_6410.c:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define DEVICE_NAME  "pwm"

static struct semaphore lock;

static void PWM_Set_Freq( unsigned long freq )
{
	unsigned long tcon;
	unsigned long tcnt;
	unsigned long tcfg1;
	unsigned long tcfg0;
	unsigned long pclk;
	unsigned tmp;
	struct clk *clk_p;

    printk ("Freq is %d",freq);
	tmp = readl(S3C64XX_GPFCON);//PWM GPF15
    tmp &= ~(0x3U << 30);// Timer1
    tmp |=  (0x2U << 30);
	writel(tmp, S3C64XX_GPFCON);
	tcon  = __raw_readl(S3C_TCON);
	tcfg1 = __raw_readl(S3C_TCFG1);
	tcfg0 = __raw_readl(S3C_TCFG0);
	tcfg0 &= ~S3C_TCFG_PRESCALER0_MASK;
	tcfg0 |= (50 - 1); 
    tcfg1 &= ~S3C_TCFG1_MUX1_MASK;
    tcfg1 |= S3C_TCFG1_MUX1_DIV16;
	__raw_writel(tcfg1, S3C_TCFG1);
	__raw_writel(tcfg0, S3C_TCFG0);
	clk_p = clk_get(NULL, "pclk");
	pclk  = clk_get_rate(clk_p);
	tcnt  = (pclk/50/16)/freq;
	__raw_writel(tcnt, S3C_TCNTB(1));
	__raw_writel(tcnt/2, S3C_TCMPB(1));
	tcon &= ~(0xf << 8);
	tcon |= (0xb << 8);		
	__raw_writel(tcon, S3C_TCON);
	tcon &= ~(2 << 8);
	__raw_writel(tcon, S3C_TCON);
}

void PWM_Stop( void )
{
	unsigned tmp;
	tmp = readl(S3C64XX_GPFCON);
	tmp &= ~(0x3U << 30);// set GPF15
	writel(tmp, S3C64XX_GPFCON);
}

static int s3c64xx_pwm_open(struct inode *inode, struct file *file)
{
	if (!down_trylock(&lock))
		return 0;
	else
		return -EBUSY;
}

static int s3c64xx_pwm_close(struct inode *inode, struct file *file)
{
	up(&lock);
	return 0;
}

static long s3c64xx_pwm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
	switch (cmd) 
	{
		case 1:
			if (arg == 0)
			return -EINVAL;
			PWM_Set_Freq(arg);
			break;

		case 0:
			PWM_Stop();
			break;
	}
	return 0;
}


static struct file_operations dev_fops = {
    .owner		= THIS_MODULE,
    .open		= s3c64xx_pwm_open,
    .release	= s3c64xx_pwm_close, 
    .unlocked_ioctl	= s3c64xx_pwm_ioctl,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name  = DEVICE_NAME,
    .fops  = &dev_fops,
};

static int __init dev_init(void)
{
	int ret;
	init_MUTEX(&lock);
	ret = misc_register(&misc);
	printk (DEVICE_NAME"\tinitialized\n");
    return ret;
}

static void __exit dev_exit(void)
{
	misc_deregister(&misc);
}

MODULE_LICENSE("GPL");
module_init(dev_init);
module_exit(dev_exit);
Makefile添加:

obj-$(CONFIG_PWM_S3C6410)        += pwm_6410.o
Kconfig添加:

config PWM_S3C6410
	tristate "pwm"
	depends on CPU_S3C6410

make menuconfig配置內核後編譯內核

make zImage後啟動Android系統

ls /dev會看到名稱為pwm的設備驅動

驅動已經加載好,這時候就要編寫Android下的測試程序。JNI是Java Native Interface的縮寫,即Java本地調用,它允許java代碼和其他語言寫的代碼進行交互。寫測試程序時使用JNI方式實現。

eclipse建立一個新的應用工程,取名為pwm,包名為com.example.pwm

默認生成的java代碼:PwmActivity.java

package com.example.pwm;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;

public class PwmActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pwm);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_pwm, menu);
		return true;
	}
}
添加本地方法:

package com.example.pwm;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;

public class PwmActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pwm);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_pwm, menu);
		return true;
	}
       public static native int pwm_set_freq(int i, int j);
	
	static {  
	System.loadLibrary("pwm");  // 添加 C/C++動態庫導入方法  
	}
}

編輯res/layout下activity_pwm.xml

添加button控件

    
編輯res/values下strings.xml

添加

pwm
PwmActivity.java中添加:

    public void onPwmOnClicked(View v){
    	pwm_set_freq(1,200);
    }
PwmActivity.java:

package com.example.pwm;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;

public class PwmActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pwm);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_pwm, menu);
		return true;
	}
        public void onPwmOnClicked(View v){
    	        pwm_set_freq(1,200); //按下按鍵就輸出波形
        }
	public static native int pwm_set_freq(int i, int j);
	
	static {  
	System.loadLibrary("pwm");  // 添加 C/C++動態庫導入方法  ,這個庫需要使用NDK工具編譯生成。
	}  
}
上述步驟就緒後,編譯工程,再將該工程拷貝到Ubuntu下

工程目錄下創建jni文件夾:

\

使用javah命令生成jni頭文件
\

注意冒號後沒有空格<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+yfqzybXEzbfOxLz+o7o8L3A+CjxwPjxpbWcgc3JjPQ=="/uploadfile/Collfiles/20140712/2014071209061958.png" alt="\">

com_example_pwm_PwmActivity.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_example_pwm_PwmActivity */

#ifndef _Included_com_example_pwm_PwmActivity
#define _Included_com_example_pwm_PwmActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_pwm_PwmActivity_MODE_PRIVATE
#define com_example_pwm_PwmActivity_MODE_PRIVATE 0L
#undef com_example_pwm_PwmActivity_MODE_WORLD_READABLE
#define com_example_pwm_PwmActivity_MODE_WORLD_READABLE 1L
#undef com_example_pwm_PwmActivity_MODE_WORLD_WRITEABLE
#define com_example_pwm_PwmActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_pwm_PwmActivity_MODE_APPEND
#define com_example_pwm_PwmActivity_MODE_APPEND 32768L
#undef com_example_pwm_PwmActivity_MODE_MULTI_PROCESS
#define com_example_pwm_PwmActivity_MODE_MULTI_PROCESS 4L
#undef com_example_pwm_PwmActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_pwm_PwmActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_pwm_PwmActivity_BIND_AUTO_CREATE
#define com_example_pwm_PwmActivity_BIND_AUTO_CREATE 1L
#undef com_example_pwm_PwmActivity_BIND_DEBUG_UNBIND
#define com_example_pwm_PwmActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_pwm_PwmActivity_BIND_NOT_FOREGROUND
#define com_example_pwm_PwmActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_pwm_PwmActivity_BIND_ABOVE_CLIENT
#define com_example_pwm_PwmActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_pwm_PwmActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_pwm_PwmActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_pwm_PwmActivity_BIND_WAIVE_PRIORITY
#define com_example_pwm_PwmActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_pwm_PwmActivity_BIND_IMPORTANT
#define com_example_pwm_PwmActivity_BIND_IMPORTANT 64L
#undef com_example_pwm_PwmActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_pwm_PwmActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_pwm_PwmActivity_CONTEXT_INCLUDE_CODE
#define com_example_pwm_PwmActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_pwm_PwmActivity_CONTEXT_IGNORE_SECURITY
#define com_example_pwm_PwmActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_pwm_PwmActivity_CONTEXT_RESTRICTED
#define com_example_pwm_PwmActivity_CONTEXT_RESTRICTED 4L
#undef com_example_pwm_PwmActivity_RESULT_CANCELED
#define com_example_pwm_PwmActivity_RESULT_CANCELED 0L
#undef com_example_pwm_PwmActivity_RESULT_OK
#define com_example_pwm_PwmActivity_RESULT_OK -1L
#undef com_example_pwm_PwmActivity_RESULT_FIRST_USER
#define com_example_pwm_PwmActivity_RESULT_FIRST_USER 1L
#undef com_example_pwm_PwmActivity_DEFAULT_KEYS_DISABLE
#define com_example_pwm_PwmActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_pwm_PwmActivity_DEFAULT_KEYS_DIALER
#define com_example_pwm_PwmActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_pwm_PwmActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_pwm_PwmActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_pwm_PwmActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_pwm_PwmActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_pwm_PwmActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_pwm_PwmActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
 * Class:     com_example_pwm_PwmActivity
 * Method:    pwm_set_freq
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_pwm_PwmActivity_pwm_1set_1freq
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

將頭文件拷貝到jni目錄下,jni目錄下創建pwm.c:

#include  
#include  
#include  
#include  
#include  
#include  
#include  

#define LOG_TAG "PWM" //android logcat 
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__ ) 
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS_ _) 

jint JNICALL Java_com_example_pwm_PwmActivity_pwm_1set_1freq(JNIEnv *env, jclass thiz, jint cmd, jint freq)  
{ //函數名與頭文件中的保持一致
	int fd;

	fd = open("/dev/pwm",O_RDWR);
	if (fd < 0)
	{
		printf ("Open /dev/pwm file error\n");
		return -1;
	}
	
	ioctl(fd,1,200);
	close (fd);
	return 0;
}

jni目錄下創建Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := pwm
LOCAL_SRC_FILES := pwm.c
LOCAL_LDLIBS := -llog
LOCAL_C_INCLUDES := $(MY_ANDROID_SOURCE)/frameworks/base/core/jni/android/graphics \
$(MY_ANDROID_SOURCE)/external/skia/include/core \
$(MY_ANDROID_SOURCE)/external/skia/include/images \
$(MY_ANDROID_SOURCE)/frameworks/base/include \
$(MY_ANDROID_SOURCE)/system/core/include 
include $(BUILD_SHARED_LIBRARY)
命令ndk-build,如果工程目錄下沒有libs/armeabi,那麼就創建armeabi

\
生成了libpwm.so就是我們在Android應用工程中需要的庫文件

 static {    
    System.loadLibrary("pwm");  // 添加 C/C++動態庫導入方法    
    }  

將含有libpwm.so的工程文件從Ubuntu中考到windows,eclipse打開工程,編譯生成apk

pwm.apk

在板子上安裝,控制終端下輸入命令:

pm install -f pwm.apk

安裝成功提示success之後,點開軟件,點擊pwm按鈕。

示波器輸出200Hz百分之五十的波形,測試成功。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved