編輯:關於Android編程
硬件平台:S3C6410
操作系統:Ubuntu、windows
板子系統:Android
開發工具:jdk,ndk,eclipse
本次測試從linux內核模塊編譯開始,以S3C6410的pwm驅動為例。
pwm_6410.c:
#includeMakefile添加:#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);
obj-$(CONFIG_PWM_S3C6410) += pwm_6410.oKconfig添加:
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
添加
PwmActivity.java中添加:pwm
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百分之五十的波形,測試成功。
前言團隊協作中,盡量保證各自代碼自己維護。這樣既能保證代碼編寫者在邏輯上的一慣性,也能避免修改不熟悉的代碼而引起bug問題。但即使是這樣的規避,也依然無法避免程序員之間代
Android 線性布局: AbsoluteLayout布局和RelativeLayout布局。 1、絕對布局 AbsoluteLayout絕對定位Absolu
基礎配置部分解說過程是從你Native加入rn模塊,新建的rn項目配置的東西都有首先 在你的項目根目錄同級開一個rn目錄(這裡只是舉個例子)mkdir xxx-rn &a
概述本篇博客是對developer.android.com/上的Training課程的簡單翻譯,若是覺得翻譯出來的理解有困難,請點擊下方鏈接查看原文!關於DrawerLa