Hardware platform: s3c6410
Operating systems: Ubuntu, Windows
Board SUBSYSTEM: Android
Development tools: Jdk,ndk,eclipse
This test starts with the Linux kernel module compilation, taking the s3c6410 PWM driver as an example.
PWM_6410.C:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h > #include <linux/delay.h> #include <linux/poll.h> #include <linux/clk.h> #include <linux/ cdev.h> #include <linux/device.h> #include <linux/miscdevice.h> #include <linux/interrupt.h># Include <plat/regs-timer.h> #include <plat/gpio-cfg.h> #include <asm/irq.h> #include <asm/io.h > #include <asm/mach/time.h> #include <asm/uaccess.h> #include <mach/map.h> #include <mach/ regs-clock.h> #include <mach/regs-gpio.h> #include <mach/hardware.h> #include <mach/gpio-bank-e.h > #include <mach/gpio-bank-f.h> #include <mach/gpio-bank-k.h> #include <mach/regs-irq.h> #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 <<);//Timer1 tmp |= (0x2u <<); 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 ");p CLK = 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 <<);//Set Gpf15writel (TMP, S3C6 4xx_gpfcon);} static int S3c64xx_pwm_open (struct inode *inode, struct file *file) {if (!down_trylock (&lock)) return 0;elSereturn-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) r Eturn-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_cl OSE,. 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_regis ter (&misc);p rintk (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 Add:
obj-$ (config_pwm_s3c6410) + = PWM_6410.O
Kconfig Add:
Config pwm_s3c6410tristate "PWM" depends on cpu_s3c6410
Make Menuconfig kernel after configuration kernel
Make Zimage to start the Android system
Ls/dev will see a device driver with the name PWM
The driver has been loaded, so it's time to write the test program under Android. JNI is the abbreviation for Java Native interface, called Java Local, which allows Java code to interact with code written in other languages. The test program is written using Jni method.
Eclipse builds a new application project, named PWM, with the package named COM.EXAMPLE.PWM
Java code generated by default: 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 {@Overrideprotected void OnCreate (Bundle Savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.LAYOUT.ACTIVITY_PWM);} @Overridepublic boolean Oncreateoptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is PR Esent.getmenuinflater (). Inflate (R.MENU.ACTIVITY_PWM, menu); return true;}}
To add a local method:
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 {@Overrideprotected void OnCreate (Bundle Savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.LAYOUT.ACTIVITY_PWM);} @Overridepublic boolean Oncreateoptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is PR Esent.getmenuinflater (). Inflate (R.MENU.ACTIVITY_PWM, menu); return true;} public static native int pwm_set_freq (int i, int j), static { system.loadlibrary ("PWM"); Add a C + + Dynamic Library Import method }}
Edit Res/layout under Activity_pwm.xml
To add a button control
<button android:id= "@+id/pwm_on" android:layout_width= "wrap_content" android:layout_height= " Wrap_content " android:layout_above=" @+id/textview1 " android:layout_alignleft=" @+id/textview1 " Android:layout_marginbottom= "39DP" android:onclick= "onpwmonclicked" android:text= "@string/pwm"/>
Edit Res/values under Strings.xml
Add to
<string name= "PWM" >pwm</string>
Added in 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 {@Overrideprotected void OnCreate (Bundle Savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.LAYOUT.ACTIVITY_PWM);} @Overridepublic boolean Oncreateoptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is PR Esent.getmenuinflater (). Inflate (R.MENU.ACTIVITY_PWM, menu); return true;} public void onpwmonclicked (View v) { pwm_set_freq (1,200);//press the key to output the waveform }public static native int Pwm_set_freq ( int i, int j); static { system.loadlibrary ("PWM"); Add the C + + Dynamic Library Import method , which needs to compile the build using the NDK tool. } }
Once the above steps are in place, compile the project and copy the project to Ubuntu
Create a JNI folder in the project directory:
To generate a JNI header file using the Javah command
Note that there are no spaces after the colon
Generated header file:
Com_example_pwm_pwmactivity.h:
/* Don't EDIT this file-it are machine generated */#include <jni.h>/* Header for class com_example_pwm_pwmactivity */#ifndef _included_com_example_pwm_pwmactivity#define _included_com_example_pwm_pwmactivity#ifdef __ Cplusplusextern "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:PW M_set_freq * Signature: (II) I */jniexport jint jnicall java_com_example_pwm_pwmactivity_pwm_1set_1freq (JNIENV *, Jclass , Jint, jint); #ifdef __cplusplus} #endif #endif
Copy the header file to the JNI directory and create the PWM.C under the JNI directory:
#include <jni.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include < unistd.h> #include <sys/ioctl.h> #include <android/log.h> #define LOG_TAG "PWM"//android logcat #define L OGI (...) __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) {//function name is consistent with the header file, 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;}
Create android.mk in the JNI directory
Local_path: = $ (call My-dir) include $ (clear_vars) Local_module: = pwmlocal_src_files: = pwm.clocal_ldlibs: =-lloglocal_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)
Command Ndk-build, if there is no Libs/armeabi in the project directory, create the Armeabi
Generated libpwm.so is the library file we need in Android application engineering
static { system.loadlibrary ("PWM"); Add a C + + Dynamic Library Import method }
Project files containing libpwm.so from Ubuntu to Windows,eclipse Open project, build apk
pwm.apk
Install on the board, enter command under control Terminal:
PM Install-f pwm.apk
After the installation successfully prompts success, click the PWM button to open the software.
Oscilloscope output 200Hz 50% waveform, test success.