说明:第一版架构为:APP+JNI(NDK)+Driver(linux),优点是开发简单,周期短,也作为自己的毕业设计
现在更新第二版,FM服务完全植入Android系统中,成为系统服务,架构为:APP+Frameworks+JNI+HAL+Driver
整个系统设计,大致分为三篇文章介绍完毕,包括:
一、驱动设计篇
二、系统API接口篇
三、APP功能实现篇
---------------------------------------------------(二)系统接口篇-----------------------------------------------------------------
说明:关于系统接口,在FM系统中完全用不到这么复杂的流程,我这里是想把整个系统调用流程捋顺,所以使用了Frameworks(AIDL)->JNI->HAL
1.Frameworks
1.1.首先我们需设计好暴露给APP端的API接口,这里我们采用aidl的机制实现
进入到frameworks/base/core/java/android/os目录下,新建IFMService.aidl文件
1 package android.os;
2
3 interface IFMService {
4 int getADC();
5 int getFreq();
6 void setFreq(int freq);
7 void searchNextorPreFreq(int enable);
8 void setNextorPreFreq(int enable);
9 void enableMute(int enable);
10 int getIsMute();
11 void startAutoSearch();
12 }
1.2.回到frameworks/base目录,编写编译规则,生成Stub接口文件
打开Android.mk文件,在LOCAL_SRC_FILES属性中添加
1 LOCAL_SRC_FILES +=
2 ...
3 core/java/android/os/IFMService.aidl
4 ...
1.3.在frameworks/base目录下,使用mm命令编译IFMService.aidl生成IHelloService.Stub,在使用mm目录之前需要lunch系统的编译环境
Stub实质上就是binder通信,client<-->proxy<-->stub<-->service
1.4.进入到frameworks/base/services/java/com/android/server,新建FMService.java文件,继承IHelloService.Stub并实现接口函数
1 package com.android.server;
2
3 import android.content.Context;
4 import android.os.IFMService;
5 import android.util.Slog;
6
7 public class FMService extends IFMService.Stub {
8
9 private static final String TAG = "FMService";
10
11 FMService() {
12 Slog.d(TAG,"FM init...");
13 init_native();
14 }
15
16 public int getADC(){
17
18 return getADC_native();
19 }
20
21 public int getFreq(){
22 return getFreq_native();
23 }
24
25 public void setFreq(int freq){
26
27 setFreq_native(freq);
28 return ;
29 }
30
31 public void searchNextorPreFreq(int enable){
32
33 searchNextorPreFreq_native(enable);
34 return ;
35 }
36
37 public void setNextorPreFreq(int enable){
38
39 setNextorPreFreq_native(enable);
40 return ;
41 }
42
43 public void enableMute(int enable){
44
45 enableMute_native(enable);
46 return ;
47 }
48
49 public int getIsMute(){
50 return getIsMute_native();
51 }
52
53 public void startAutoSearch(){
54
55 startAutoSearch_native();
56 return ;
57 }
58
59 private static native boolean init_native();
60 private static native int getADC_native();
61 private static native int getFreq_native();
62 private static native void setFreq_native(int freq);
63 private static native void searchNextorPreFreq_native(int enable);
64 private static native void setNextorPreFreq_native(int enable);
65 private static native void enableMute_native(int enable);
66 private static native int getIsMute_native();
67 private static native void startAutoSearch_native();
68
69 };
在这个文件中,我们把函数调用传递到了JNI
1.5.最后在Frameworks中我们需要启动我们的FMservice
进入frameworks/base/services/java/com/android/server目录,在SystemServer.java文件中添加
1 class ServerThread extends Thread {
2 @Override
3 public void run() {
4 if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5 try {
6 Slog.i(TAG, "DiskStats Service");
7 ServiceManager.addService("diskstats", new DiskStatsService(context));
8 } catch (Throwable e) {
9 reportWtf("starting DiskStats Service", e);
10 }
11 try {
12
13 Slog.i(TAG, "FM Service");
14
15 ServiceManager.addService("fm5767", new FMService());
16
17 } catch (Throwable e) {
18
19 Slog.e(TAG, "Failure starting FM Service", e);
20
21 }
22 }
23 }
24 }
1.6.编译service(若修改了service的实现方法可模块编译service模块)
进入frameworks/base/services/java,使用命令mm进行编译,在out目录下的system/frameworks下生成services.jar,使用adb直接cp到板子上重启即可生效
2.JNI
2.1.实现JNi函数,函数传递到HAL层
进入frameworks/base/services/jni目录,新建com_android_server_FMService.cpp文件
1 #define LOG_TAG "FMService_jni"
2 #include "jni.h"
3 #include "JNIHelp.h"
4 #include "android_runtime/AndroidRuntime.h"
5 #include 6 #include 7 #include 8 #include 9 #include 10 11 namespace android 12 { 13 /*在硬件抽象层中定义的硬件访问结构体,参考 14 struct tea5767_device_t* tea5767_device = NULL; 15 16 //访问硬件的接口 17 static jint tea5767_getADC(JNIEnv* env, jobject clazz){ 18 int adc = 0; 19 if(!tea5767_device){ 20 LOGE("FM jni is not open.."); 21 return adc; 22 } 23 adc = tea5767_device->getADC(tea5767_device); 24 LOGI("get fm adc = %d",adc); 25 26 return adc; 27 } 28 29 static jint tea5767_getFreq(JNIEnv* env, jobject clazz){ 30 int freq = 0; 31 if(!tea5767_device){ 32 LOGE("FM jni is not open.."); 33 return freq; 34 } 35 freq = tea5767_device->getFreq(tea5767_device); 36 LOGI("get fm freq = %d",freq); 37 38 return freq; 39 } 40 41 static void tea5767_setFreq(JNIEnv* env, jobject clazz, jint freq){ 42 43 if(!tea5767_device){ 44 LOGE("FM jni is not open.."); 45 return ; 46 } 47 tea5767_device->setFreq(tea5767_device,freq); 48 LOGI("set fm freq = %d",freq); 49 50 return ; 51 } 52 53 static void tea5767_searchNextorPreFreq(JNIEnv* env, jobject clazz, jint enable){ 54 55 if(!tea5767_device){ 56 LOGE("FM jni is not open.."); 57 return ; 58 } 59 tea5767_device->searchNextorPreFreq(tea5767_device,enable); 60 LOGI("searchNextorPreFreq state = %d",enable); 61 62 return ; 63 } 64 65 static void tea5767_setNextorPreFreq(JNIEnv* env, jobject clazz, jint enable){ 66 67 if(!tea5767_device){ 68 LOGE("FM jni is not open..");
上一篇:基于iTop4412的FM收音机系统设计(一)
下一篇:基于iTop4412的FM收音机系统设计(三)
推荐阅读最新更新时间:2024-11-17 02:53
推荐帖子
- 晒晒我昨天做的万年历
- 首先感谢一下版主和管理员给我提供的帮助,谢谢!昨天忙了一天终于把电子万年历做出来了,传上来和大家分享。做了花时间嘻嘻收大家1芯币 晒晒我昨天做的万年历赞一个不错加油加油回复楼主08221034的帖子谢谢管理员夸奖速度还是很快滴HOHO回复板凳08221034的帖子呵呵管理员您是女孩还是男孩我想你的单片机一定很厉害顶顶,加油。用的DS-18B20数字温度传感器阿不错不错。顶顶。不错啊,继续努力啊不错的设计,加油。是的呵呵
- 08221034 单片机
- DSP 的图像显示放大
- 如何将一定区域内的图像放大在标准PAL576*720下请问有相关代码么DSP的图像显示放大
- maxcio DSP 与 ARM 处理器
- 竞赛中会用到的封装大全哦
- 本帖最后由paulhyde于2014-9-1509:04编辑竞赛中会用到的封装大全哦本帖最后由paulhyde于2014-9-1509:04编辑已经有了,还是本帖最后由paulhyde于2014-9-1509:04编辑不错画pcb的时候挺有用本帖最后由paulhyde于2014-9-1509:04编辑恩,谢谢楼主本帖最后由paulhyde于2014-9-1509:04编辑
- dtcxn 电子竞赛
- ATMEGA8数控电源制作资料
- ATMEGA8数控电源制作资料ATMEGA8数控电源制作资料能简单介绍一下更好,或上个图资料还算全,就是没介绍。资料还算全,就是没介绍。收下,谢谢资料还算全,就是没介绍。A东西不错好东西,呵呵下来参考参考谢谢惨没有币···············再顶一下····真是不好意思在支持下···终于下到了那个辛苦啊惨没有币···············资料还算全,就是没介绍。给个图吧。支持dingyige~
- ahshan Microchip MCU
- 找做C/C++嵌入式的朋友
- 有谁作C/C++嵌入式的,大家一起聊聊,MSN:japan-soft@hotmail.com天天在线!找做C/C++嵌入式的朋友最讨厌小日本,LZ自己聊吧!!!LZ的ID实在不讨好。是个雌的想L聊可以先看看样貌,公的就不要聊了。友情Up!
- 醉清风 嵌入式系统
- 基于TI Davinci架构的双核嵌入式应用处理器OMAPL138开发入门
- 一、简介TI的达芬奇架构嵌入式应用处理器使用DSP与ARM结合的非对称多核结构,当然现在也有管脚全兼容的单核。本文要介绍的就是其中的一款低功耗处理器OMAPL138。OMAPL138包括一个主频300M的ARM9处理器内核和一个300M的C6748DSP内核(均是32位处理器)。此外还有大量外设在此不做说明,与通用的ARM与DSP内核相比有如下一些不同点:1.内存映射,该处理器的外设与内存统一编址,DSP与ARM共享4G内存空间。但其中有一部分DSP仅可见(如DSP的数
- Aguilera DSP 与 ARM 处理器
设计资源 培训 开发板 精华推荐
- AD8505ARJZ-R7 脉搏血氧计红色和红外电流源作为电压基准器件的缓冲器的典型应用电路
- 使用 LTC3637HDHC 24.5V 至 76V 输入至 24V 输出和 350mA 输入电流限制的典型应用
- 用于服务器的 10.8 至 13.2V 热插拔控制器
- LT1172CT、1.25A 高效恒流充电器的典型应用
- TAR5S19U 点稳压器(低压差稳压器)的典型应用
- 使用 ADM3066EBCPZ-R7 3 至 5.5 V、±12 kV IEC ESD 保护、50 Mbps RS-485 收发器的典型应用
- LT1764AEFE-1.5 3.3 VIN 至 2.5 VOUT LDO 稳压器的典型应用
- RE46C117 DC-DC转换器和压电喇叭驱动器的典型应用
- 使用 NXP Semiconductors 的 PPC5643LFF2MLQ1 的参考设计
- 希尔伯特走线加热板