当前位置:  编程技术>移动开发
本页文章导读:
    ▪ARM程序上载步骤        ARM程序下载步骤      以下是我写给生产调试中心的简单程序下载调试步骤 ,记录在此。     PS:CSDN 的博客真垃圾,图片都传不了,下次再想办法把图片补上来了                .........
    ▪ FreeBSD 9.1内核资料编译分析        FreeBSD 9.1内核文件编译分析 本文不是叫大家怎么做FreeBSD内核,做内核太简单了,不管是Linux和Unix。 在网上找了好久,一点可用的文章都没有找到,FreeBSD的官网的文章也没有给出说法,只能.........
    ▪ JNI范例2-扫描SD卡中mp3文件,native层调用Java自定义的类       JNI实例2---扫描SD卡中mp3文件,native层调用Java自定义的类       此博客是在研究完《Android内核剖析》中2.2章节JNI调用机制后,才完成的。在此非常感谢该书的作者。此书的内容较多,讲述的.........

[1]ARM程序上载步骤
    来源: 互联网  发布时间: 2014-02-18
ARM程序下载步骤

      以下是我写给生产调试中心的简单程序下载调试步骤 ,记录在此。 

   PS:CSDN 的博客真垃圾,图片都传不了,下次再想办法把图片补上来了

 

                                                                     Xxxx板程序下载调试说明

Xxxx板程序下载调试包括以下几个步骤

1.     烧写uboot

2.     烧写内核

3.     烧写文件系统

4.     测试系统运行状况

 

一.   烧写uboot

  1.单击〝开始〞,〝运行〞,输入〝CMD〞单击〝确定〞。

 

2.依次在界面中输入”e:”和” cd  JFlasn”(根据JFlash文件夹所在具体目录作修改)并回车。


3.进入JFlash目录下后,输入Jflashmm.exe pxa270 u-boot.bin回车。

    (或者执行a.bat)


提示:若输入命令后,并未进入下载,可重复该操作几遍。

 

4.烧写成功,〝Verification successful!〞

 

 

 

 

 

 

 

 

二.   烧写内核和文件系统

注:在成功完成uboot烧写的前提下,进行以下操作

 

1.建立PC和XXXXXXX板的串口和网口连接。在windows XP系统中打开超级终端,选择串口〝COM1〞,设置波特率115200;单击〝确定〞。

 

 

2.按下XXXXXXX板复位键,重启系统,此时若超级终端界面有数据显示(如下图内容),表明uboot烧写成功,同时按下电脑键盘” I ”键。进入内核和文件系统烧写。

 

3.在超级终端中输入:ping 168.3.0.55回车。出现 host 168.3.0.55 is alive说明网络环境通路配置成功。 若出现host 168.3.0.55 is not alive说明网络环境未通。 

 

4.在超级终端输入protect off all  回车

5.在超级终端输入 erase  0x80000  0x1ffffff 回车

 

6.在超级终端中输入:tftp 0xa0008000 uImage回车,若出现done,表明传送成功,若未出现done,请检查网络连接,或者关闭重试

 

7.根据NOR flash分区输入:cp.b 0xa0008000 0x80000 0x163ae8 (内核大小,由上一步操作得到),若出现copy to flash  done 表明操作成功。

  

 

 8.在超级终端中输入:tftp 0xa0008000 rootfs.img回车

 

 9.根据NOR flash分区输入:cp.b 0xa0008000 0x300000 0x5c0000 (文件系统的大小,由上一步操作得到)出现copy to flash done表明该步操作成功。

 

 

 至此,uboot,内核,文件系统烧写完成。

 

三.  测试系统运行状况

1.     若能顺利完成以上操作,则表明系统串口,网口功能模块正常

2.     在超级终端输入sset bootargs console=ttyS0,115200 ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs 回车

3.     在超级终端输入saveenv回车

4.     在超级终端输入 boot回车,查看超级终端显示内容,分以下几种情况

(1)若出现下图情况,表明系统在一直重启,系统不正常

 

  (2)若出现下图情况,表明内核初步启动正常。

 

 5.若内核启动正常,继续往下看超级终端显示,若未出现“error”字符,则表明内核启动成功,文件系统挂载成功。若出现“error”字符,有两种情况,一是核心板有问题,二是底板有问题,所以下载程序时,建议选用没有任何故障的底板,这样当出现“error”字符时,可以基本判断是核心板的问题。

 

注释:出现error字符那一行最左端字符表明出错设备名称,如上图所示,表明usb接口出现异常。

6.打开虚拟主机终端界面,输入telnet 168.3.0.47回车,输入登录密码root 回车。

7.输入ps,查看运行中的进程,若有exchanger,则表明程序在正常运行。

8.内核启动,挂载文件系统成功,并未出现“error”字符。Exchanger进程在运行,初步可以判定系统arm核心板正常运行,详细的功能模块测试可以在整机测试时进行测试。

9.在超级终端输入set bootargs console=ttyS3,115200 ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs 回车.

10..在超级终端输入saveenv回车


    
[2] FreeBSD 9.1内核资料编译分析
    来源: 互联网  发布时间: 2014-02-18
FreeBSD 9.1内核文件编译分析

本文不是叫大家怎么做FreeBSD内核,做内核太简单了,不管是Linux和Unix。

在网上找了好久,一点可用的文章都没有找到,FreeBSD的官网的文章也没有给出说法,只能自己在/usr/src和/usr/src/sys和/usr/src/sys/conf下面疯狂的grep,找文件,找引用,才有了自己的一些理解。

先说说Linux的内核文件的编译关联吧,Linux的每个文件的编译和是kconfig配置关联在一起的,kconfig在经过make menuconfig之后,得到一个.config文件,然后每个文件夹下面的Makefile,会check这个全局的.config文件,来决定哪些文件该编译,哪些不用编译。多说无益,参考代码即可。

FreeBSD的做法有些不一样了,Linux把哪些文件要编译分散到了每个文件夹,然后check Makefile。FreeBSD是做两个总的文件,决定哪些文件该编译哪些不该,这两个文件分别是这个路径下:
ztz0223@BTazuo:/usr/src/sys/conf % pwd
/usr/src/sys/conf
的两个文件:files,files.i386
files是与架构无关的,也就是不管代码在什么平台上面编译,i386或者power pc上面都靠这个文件控制编译。对应的files.i386,就是特定平台的编译控制。

我们来看一下,这两个文件里面是什么吧,首先是files:
2082 dev/xe/if_xe.c          optional xe
2083 dev/xe/if_xe_pccard.c       optional xe pccard
2084 dev/xl/if_xl.c          optional xl pci
2085 dev/xl/xlphy.c          optional xl pci
2086 fs/coda/coda_fbsd.c     optional vcoda
2087 fs/coda/coda_psdev.c        optional vcoda
2088 fs/coda/coda_subr.c     optional vcoda
2089 fs/coda/coda_venus.c        optional vcoda
2090 fs/coda/coda_vfsops.c       optional vcoda
2091 fs/coda/coda_vnops.c        optional vcoda
2092 fs/deadfs/dead_vnops.c      standard
2093 fs/devfs/devfs_devs.c       standard
2094 fs/devfs/devfs_dir.c        standard
2095 fs/devfs/devfs_rule.c       standard
2096 fs/devfs/devfs_vfsops.c     standard
2097 fs/devfs/devfs_vnops.c      standard
2098 fs/fdescfs/fdesc_vfsops.c   optional fdescfs
2099 fs/fdescfs/fdesc_vnops.c    optional fdescfs
2100 fs/fifofs/fifo_vnops.c      standard
2101 fs/hpfs/hpfs_alsubr.c       optional hpfs
2102 fs/hpfs/hpfs_lookup.c       optional hpfs
"files" [readonly] 3544 lines --57%--     

再看files.i386:
417 i386/i386/minidump_machdep.c    standard
418 i386/i386/mp_clock.c        optional smp
419 i386/i386/mp_machdep.c      optional native smp
420 i386/xen/mp_machdep.c       optional xen smp
421 i386/i386/mp_watchdog.c     optional mp_watchdog smp
422 i386/i386/mpboot.s      optional smp native
423 i386/xen/mptable.c      optional apic xen
424 i386/i386/perfmon.c     optional perfmon
425 i386/i386/pmap.c        optional native
426 i386/xen/pmap.c         optional xen
427 i386/i386/ptrace_machdep.c  standard
428 i386/i386/stack_machdep.c   optional ddb | stack
429 i386/i386/support.s     standard
430 i386/i386/swtch.s       standard
431 i386/i386/sys_machdep.c     standard
432 i386/i386/trap.c        standard
433 i386/i386/uio_machdep.c     standard
434 i386/i386/vm86.c        standard
435 i386/i386/vm_machdep.c      standard
436 i386/ibcs2/ibcs2_errno.c    optional ibcs2
437 i386/ibcs2/ibcs2_fcntl.c    optional ibcs2
438 i386/ibcs2/ibcs2_ioctl.c    optional ibcs2
439 i386/ibcs2/ibcs2_ipc.c      optional ibcs2
440 i386/ibcs2/ibcs2_isc.c      optional ibcs2
"files.i386" [readonly] 537 lines --71%--                      

对于上面的files,我要说的就是,后面带有standard的表明该文件一定会编译,不管是快速编译指定模块,还是全部完全编译。 二 optional xxx标识当xxx选项开启的时候,才会编译对应的文件。如果内核里指定了options,就会编译到内核文件里,而不是以模块方式可以动态加载的了,一般都会建议采用模块方式。
上面files.i386可以看出:
436 i386/ibcs2/ibcs2_errno.c    optional ibcs2  只有在ibcs2选项开启的时候才会编译
而:
432 i386/i386/trap.c        standard                 在i386架构平台下编译的话,一定要编译的。

OK,说到这里,已经知道文件如何编译的了,那么在指定快速编译的时候,就是在make.conf里面指定编译的模块,就如官网文档所示:

    ------------------------------
    联编内核

    1. 进入 /usr/src 目录:
    # cd /usr/src
    2. 编译内核:
    # make buildkernel KERNCONF=MYKERNEL
    3. 安装新内核:
    # make installkernel KERNCONF=MYKERNEL

    注意: 使用这种方法联编内核时, 需要安装完整的 FreeBSD 源代码。
    提示: 默认情况下, 在联编您所定制的内核时, 全部 内核模块也会同时参与构建。 如果您希望更快地升级内核, 或者只希望联编您所需要的模块, 则应在联编之前编辑 /etc/make.conf:
    MODULES_OVERRIDE = linux acpi sound/sound sound/driver/ds1 ntfs

    这个变量的内容是所希望构建的模块列表。
    WITHOUT_MODULES = linux acpi sound ntfs

    这个变量的内容是将不在联编过程中编译的顶级模块列表。 如果希望了解更多与构建内核有关的变量, 请参见 make.conf(5) 联机手册。
    ------------------------------
比如,我在/etc/make.conf里面指定:
MODULES_OVERRIDE = xfs

那么是不是仅仅编译xfs的文件吗?
当然不是,当我们执行
# make buildkernel KERNCONF=MYKERNEL
开始编译的时候,会发现打印里面有
cc -c -O -pipe  -std=c99 -g -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option   -nostdinc  -I. -I/usr/src/sys -I/usr/src/sys/contrib/altq -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-common -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000  -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-sse -msoft-float -ffreestanding -fstack-protector -Werror  /usr/src/sys/cam/ata/ata_all.c
但是我们可以从files里面看出来:
 110 cam/ata/ata_all.c       optional scbus
scbus开启才会编译这个文件。
为什么他会编译?
很简单,我们看
# make buildkernel KERNCONF=MYKERNEL
 的最开始有一些打印,是删除中间文件的:
--------------------------
>>> stage 2.1: cleaning up the object tree
--------------------------
cd /usr/obj/usr/src/sys/GENERIC_20130217; MAKEOBJDIRPREFIX=/usr/obj  MACHINE_ARCH=i386  MACHINE=i386  CPUTYPE= GROFF_BIN_PATH=/usr/obj/usr/src/tmp/legacy/usr/bin  GROFF_FONT_PATH=/usr/obj/usr/src/tmp/legacy/usr/share/groff_font  GROFF_TMAC_PATH=/usr/obj/usr/src/tmp/legacy/usr/share/tmac  _SHLIBDIRPREFIX=/usr/obj/usr/src/tmp  _LDSCRIPTROOT=  VERSION="FreeBSD 9.1-RELEASE i386 901000"  INSTALL="sh /usr/src/tools/install.sh"  PATH=/usr/obj/usr/src/tmp/legacy/usr/sbin:/usr/obj/usr/src/tmp/legacy/usr/bin:/usr/obj/usr/src/tmp/legacy/usr/games:/usr/obj/usr/src/tmp/usr/sbin:/usr/obj/usr/src/tmp/usr/bin:/usr/obj/usr/src/tmp/usr/games:/sbin:/bin:/usr/sbin:/usr/bin make KERNEL=kernel cleandir
rm -f *.o *.so *.So *.ko *.s eddep errs  kernel.debug kernel kernel.symbols  linterrs makelinks tags vers.c  vnode_if.c vnode_if.h vnode_if_newproto.h vnode_if_typedef.h  agp_if.c ata_if.c eisa_if.c miibus_if.c mmcbr_if.c mmcbus_if.c mvs_if.c card_if.c power_if.c pci_if.c pcib_if.c ppbus_if.c hdac_if.c ac97_if.c channel_if.c feeder_if.c mixer_if.c mpu_if.c mpufoi_if.c synth_if.c uart_if.c usb_if.c g_part_if.c g_raid_md_if.c g_raid_tr_if.c isa_if.c bus_if.c clock_if.c cpufreq_if.c device_if.c linker_if.c serdev_if.c acpi_if.c acpi_wmi_if.c agp_if.h ata_if.h eisa_if.h miibus_if.h mmcbr_if.h mmcbus_if.h mvs_if.h card_if.h power_if.h pci_if.h pcib_if.h ppbus_if.h hdac_if.h ac97_if.h channel_if.h feeder_if.h mixer_if.h mpu_if.h mpufoi_if.h synth_if.h uart_if.h usb_if.h g_part_if.h g_raid_md_if.h g_raid_tr_if.h isa_if.h bus_if.h clock_if.h cpufreq_if.h device_if.h linker_if.h serdev_if.h acpi_if.h acpi_wmi_if.h  acpi_quirks.h aicasm* y.tab.h aic7xxx_seq.h aic7xxx_reg.h  aic7xxx_reg_print.c aic79xx_seq.h aic79xx_reg.h  aic79xx_reg_print.c feeder_eq_gen.h feeder_rate_gen.h  snd_fxdiv_gen.h miidevs.h pccarddevs.h teken_state.h usbdevs.h  usbdevs_data.h acpi_wakecode.o acpi_wakecode.bin acpi_wakecode.h  acpi_wakedata.h
rm -f .depend machine x86

会删除一些生成的临时文件,和一些头文件,再生成这些头文件,FreeBSD的内核编译的时候,头文件变了,相关的c文件都是要重新编译过的。这就解释上面的增量编译xfs的时候,会要编译一些不相关的文件。

再回到上面的:
 110 cam/ata/ata_all.c       optional scbus
这个scbus option是在哪里开的?
很简单了,就是在文件夹/usr/src/sys/i386/conf/下面

ztz0223@BTazuo:/usr/src/sys/i386/conf %
打开GENERIC文件看就知道了:

 18 #
19 # $FreeBSD: release/9.1.0/sys/i386/conf/GENERIC 235877 2012-05-24 03:45:13Z mav $
20
21 cpu     I486_CPU
22 cpu     I586_CPU
23 cpu     I686_CPU
24 ident       GENERIC
25
26 makeoptions DEBUG=-g        # Build kernel with gdb(1) debug symbols
27
28 options     SCHED_ULE       # ULE scheduler
29 options     PREEMPTION      # Enable kernel thread preemption
30 options     INET            # InterNETworking
31 options     INET6           # IPv6 communications protocols
32 options     SCTP            # Stream Control Transmission Protocol
33 options     FFS         # Berkeley Fast Filesystem
34 options     SOFTUPDATES     # Enable FFS soft updates support
35 options     UFS_ACL         # Support for access control lists
36 options     UFS_DIRHASH     # Improve performance on big directories
37 options     UFS_GJOURNAL        # Enable gjournal-based UFS journaling
38 options     MD_ROOT         # MD is a potential root device
39 options     NFSCL           # New Network Filesystem Client
40 options     NFSD            # New Network Filesystem Server
41 options     NFSLOCKD        # Network Lock Manager
42 options     NFS_ROOT        # NFS usable as /, requires NFSCL
43 options     MSDOSFS         # MSDOS Filesystem
44 options     CD9660          # ISO 9660 Filesystem
45 options     PROCFS          # Process filesystem (requires PSEUDOFS)
46 options     PSEUDOFS        # Pseudo-filesystem framework
47 options     GEOM_PART_GPT       # GUID Partition Tables.
48 options     GEOM_RAID       # Soft RAID functionality.
49 options     GEOM_LABEL      # Provides labelization
50 options     COMPAT_FREEBSD4     # Compatible with FreeBSD4
51 options     COMPAT_FREEBSD5     # Compatible with FreeBSD5
52 options     COMPAT_FREEBSD6     # Compatible with FreeBSD6
53 options     COMPAT_FREEBSD7     # Compatible with FreeBSD7
54 options     SCSI_DELAY=5000     # Delay (in ms) before probing SCSI
55 options     KTRACE          # ktrace(1) support
56 options     STACK           # stack(9) support
"GENERIC" [readonly] 361L, 14505C    

这里有options,标识对应的选项开启了。

还有一个问题,就是代码里面有一些:
 137 #ifdef INET
138 int (*carp_iamatch_p)(struct ifnet *, struct in_ifaddr *, struct in_addr *,
139     u_int8_t **);
140 #endif
141 #ifdef INET6
142 struct ifaddr *(*carp_iamatch6_p)(struct ifnet *ifp, struct in6_addr *taddr6);
143 caddr_t (*carp_macmatch6_p)(struct ifnet *ifp, struct mbuf *m,
144     const struct in6_addr *taddr);
145 #endif
146
147 struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int) = NULL;
148
"net/if.c" [readonly] 3419 lines --2%-- 
这个INET在哪里定义的呢?

回到路径::/usr/src/sys/conf ,查看两个文件:
-rw-r--r--  1 root  wheel   23377 Dec  4 06:11 options
-rw-r--r--  1 root  wheel    1563 Dec  4 06:11 options.i386

ztz0223@BTazuo:/usr/src/sys/conf % less options
388 DEVICE_POLLING
389 DEV_ENC         opt_enc.h
390 DEV_PF          opt_pf.h
391 DEV_PFLOG       opt_pf.h
392 DEV_PFSYNC      opt_pf.h
393 DEV_VLAN        opt_vlan.h
394 DUMMYNET        opt_ipdn.h
395 ETHER_8022      opt_ef.h
396 ETHER_8023      opt_ef.h
397 ETHER_II        opt_ef.h
398 ETHER_SNAP      opt_ef.h
399 INET            opt_inet.h
400 INET6           opt_inet6.h

则可以知道INET就定义在opt_inet.h中,而在编译过FreeBSD内核之后,在/usr/obj/usr/src/sys/GENERIC生成的临时文件路径下面,就有这个opt_inet.h文件了,查看一下:
ztz0223@BTazuo:/usr/obj/usr/src/sys/GENERIC_20130217 % vim opt_inet.h
 1 #define INET 1

同样options.i386里面也会指定一些平台代码需要的头文件和宏定义。

最后一个问题,就是在/etc/make.conf指定:
MODULES_OVERRIDE = xfs
标识增量编译xfs,那么xfs就是一个模块,该模块在哪里指定?在/usr/src/sys/modules下面,有很多文件夹:

ztz0223@BTazuo:/usr/src/sys/modules % ls -la  | grep xfs
drwxr-xr-x    2 root  wheel    512 Dec  4 05:09 xfs
ztz0223@BTazuo:/usr/src/sys/modules %

这个下面的文件夹里面只有Makefile,没有其他的东西的,这些Makefile就是指定编译模块增量编译内核的时候,指定编译的Makefile了。

这里看一下xfs下面的Makefile内容了:

ztz0223@BTazuo:/usr/src/sys/modules % cat xfs/Makefile
# $FreeBSD: release/9.1.0/sys/modules/xfs/Makefile 229734 2012-01-06 21:23:00Z dim $

.PATH:  ${.CURDIR}/../../gnu/fs/xfs \
        ${.CURDIR}/../../gnu/fs/xfs/FreeBSD \
        ${.CURDIR}/../../gnu/fs/xfs/FreeBSD/support

KMOD=    xfs

WERROR=

SRCS =  vnode_if.h \
        xfs_alloc.c \
        xfs_alloc_btree.c \
        xfs_bit.c \
        xfs_bmap.c \
        xfs_bmap_btree.c \
        xfs_btree.c \
        xfs_buf_item.c \
        xfs_da_btree.c \
        xfs_dir.c \
        xfs_dir2.c \
        xfs_dir2_block.c \
        xfs_dir2_data.c \
        xfs_dir2_leaf.c \
        xfs_dir2_node.c \
        xfs_dir2_sf.c \
        xfs_dir2_trace.c \
        xfs_dir_leaf.c \
        xfs_error.c \
        xfs_extfree_item.c \
        xfs_freebsd_iget.c \
        xfs_fsops.c \
        xfs_ialloc.c \
        xfs_ialloc_btree.c \
        xfs_inode.c \
        xfs_inode_item.c \
        xfs_iocore.c \
        xfs_itable.c \
        xfs_dfrag.c \
        xfs_log.c \
        xfs_log_recover.c \
        xfs_mount.c \
        xfs_rename.c \
        xfs_trans.c \
        xfs_trans_ail.c \
        xfs_trans_buf.c \
        xfs_trans_extfree.c \
        xfs_trans_inode.c \
        xfs_trans_item.c \
        xfs_utils.c \
        xfs_vfsops.c \
        xfs_vnodeops.c \
        xfs_rw.c \
        xfs_iget.c \
        xfs_attr_leaf.c \
        xfs_attr.c \
        xfs_dmops.c \
        xfs_qmops.c \
        xfs_mountops.c \
        xfs_vnops.c \
        xfs_frw.c \
        xfs_iomap.c \
        xfs_buf.c \
        xfs_globals.c \
        xfs_dmistubs.c \
        xfs_behavior.c \
        xfs_super.c \
        xfs_stats.c \
        xfs_sysctl.c \
        xfs_vfs.c \
        xfs_vnode.c \
        xfs_fs_subr.c \
        xfs_ioctl.c \
        debug.c \
        ktrace.c \
        mrlock.c \
        uuid.c \
        kmem.c \
        kdb.c

SRCS+=  opt_ddb.h

.include <bsd.kmod.mk>

CFLAGS+= -I${.CURDIR}/../../gnu/fs/xfs/FreeBSD \
         -I${.CURDIR}/../../gnu/fs/xfs/FreeBSD/support \
         -I${.CURDIR}/../../gnu/fs/xfs

CWARNFLAGS.xfs_ioctl.c=         ${NO_WSELF_ASSIGN}
CWARNFLAGS+=                    ${CWARNFLAGS.${.IMPSRC:T}}
ztz0223@BTazuo:/usr/src/sys/modules %

再看一下,增量编译的过程打印,这里只附上xfs链接的相关的部分:

ld  -d -warn-common -r -d -o xfs.kld xfs_alloc.o xfs_alloc_btree.o xfs_bit.o xfs_bmap.o xfs_bmap_btree.o xfs_btree.o xfs_buf_item.o xfs_da_btree.o xfs_dir.o xfs_dir2.o xfs_dir2_block.o xfs_dir2_data.o xfs_dir2_leaf.o xfs_dir2_node.o xfs_dir2_sf.o xfs_dir2_trace.o xfs_dir_leaf.o xfs_error.o xfs_extfree_item.o xfs_freebsd_iget.o xfs_fsops.o xfs_ialloc.o xfs_ialloc_btree.o xfs_inode.o xfs_inode_item.o xfs_iocore.o xfs_itable.o xfs_dfrag.o xfs_log.o xfs_log_recover.o xfs_mount.o xfs_rename.o xfs_trans.o xfs_trans_ail.o xfs_trans_buf.o xfs_trans_extfree.o xfs_trans_inode.o xfs_trans_item.o xfs_utils.o xfs_vfsops.o xfs_vnodeops.o xfs_rw.o xfs_iget.o xfs_attr_leaf.o xfs_attr.o xfs_dmops.o xfs_qmops.o xfs_mountops.o xfs_vnops.o xfs_frw.o xfs_iomap.o xfs_buf.o xfs_globals.o xfs_dmistubs.o xfs_behavior.o xfs_super.o xfs_stats.o xfs_sysctl.o xfs_vfs.o xfs_vnode.o xfs_fs_subr.o xfs_ioctl.o debug.o ktrace.o mrlock.o uuid.o kmem.o kdb.o

有这么多,我想足够理解了。

 


    
[3] JNI范例2-扫描SD卡中mp3文件,native层调用Java自定义的类
    来源: 互联网  发布时间: 2014-02-18
JNI实例2---扫描SD卡中mp3文件,native层调用Java自定义的类
       此博客是在研究完《Android内核剖析》中2.2章节JNI调用机制后,才完成的。在此非常感谢该书的作者。此书的内容较多,讲述的知识点也比较深入,值得各位Android coder们学习。
在Android应用开发时,有时候为了提升程序的效率,需要使用到JNI编程,调用native C代码,协作完成应用的某些功能。
                                           理论讲解
JNI接口主要包含两种情况,第一种为从Java中调用C,第二种为从C中调用Java。
一. Java访问C
      Java类中可以定义某些native函数。当Java编译器遇到native函数时,不会关心该函数的具体实现。在程序运行时,调用native方法前,必须将C所生成的lib库装载进来。
当调用native时,编译器会向native引擎传递调用者的包名,函数名和参数类型。在产生的C函数中,会包含至少两个参数:JNIEnv指针,指向JVM的对象,可以访问JVM内部的各种对象。第二个参数为jobject,指调用者对象。
二. C访问Java
      如果C中需要使用Java的某个变量而进行相应的处理,或者C中也想调用Java中的某个函数完成某些功能,那么C就得访问Java。
      Java中是没有指针的,C访问Java时只能使用特定的接口,需要将要访问的类名,函数名称和参数传递给Java引擎。其步骤如下:
      1.获取Java对象的类
     cls = env->GetObjectClass(jobject);
     env为native函数中的第一个参数,jobject为第二个参数。
     2. 获取Java函数的id值
      jmethodID mid = env->GetMethodId(cls,"method_name","(Ljava/lang/String;)V");
      该方法第二个参数为Java中的函数名称,第三个参数:Ljava/lang/String表示String类型的参数。
     “[Ljava/lang/String;”表示String数组。返回值V代表void.
      需要注意的是GetMethodID方法的格式。
 jmethodID GetMethodID(JNIEnv *env, jclass clazz,const char *name, const char *sig);
     JNIEnv这个参数C++中不需要。clazz就是前面得到的jclass,name则是方法名称,sig是方法签名。
    3. 找到函数后,开始调用函数 env->CallXXXMethod(jobject,mid,ret);
     其中XXX代表函数返回值类型,具体包括Void,Object,Boolean,Byte,Char等…
通过以上三步,实现了C中调用Java函数的目标。
***************************************************************************************************************************
      另外一个问题:C访问Java类中的变量时如何实现的?其实跟以上的步骤相似,也为三个步骤:
     1.获取Java对象
     2.获取变量的id值 .jmethodID id = env->GetFiledId(cls,"filed_name”,”I”);第三个参数为变量的类型
     3. 获取变量的值
     Value = env->GetXXXFiled(env,jobjcet,fid);
     这个函数以返回值的方式获取变量值。    
      为了更好的将上述知识点表述清楚,本博客实现一个简单的demo,力争让大家理解清楚。
                                                     应用实例

     自定义一个类,该对象用于描述sd卡中mp3音频文件的属性。可以参看我前一篇博客内容(JNI实例1---扫描SD卡中mp3文件)native函数用于遍历MP3文件,之后调用Java的Track_Info类方法,native函数分别调用setDisplayName(),setSize(),setFilePath()等函数。

public class Track_Info implements Serializable{
	
	private String displayName;
	private long size;
	private String ext;//后缀名称,eg.mp3
	private String filePath;
	private String parentPath;
	

	public String getDisplayName() {
		return displayName;
	}
	
	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}
	
	public long getSize() {
		return size;
	}
	
	public void setSize(long size) {
//		Log.e("Track_Info.java", "setSize() called in JNI, size = " + size);
		this.size = size;
	}
	
	public String getExt() {
		return ext;
	}
	
	public void setExt(String ext) {
		this.ext = ext;
	}
	
	public String getFilePath() {
		return filePath;
	}
	
	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}
	
	public String getParentPath() {
		return parentPath;
	}
	
	public void setParentPath(String parentPath) {
		this.parentPath = parentPath;
	}
}

     在Java层的native方法为:    

    public native void scanDir(String dirPath);
    public native String[] getPathArray(String dirPath);  
    public native Track_Info[] getTracksArray(String dirPath); 

调用该native函数时,传入sd卡目录名称(String类型),函数返回一个Track_Info对象数组。(getTracksArray函数)

     在实现这个demo时,遇到如下几个问题:

      1.没有很好掌握GetMethodID函数的使用

      2.JNI函数签名返回值对应表,函数签名没有很好的掌握,导致花费了不少时间排查bug。

      3.使用自定义类,首先要能访问类的构造函数,当时没有调用(init),导致花费了很多时间。

	jclass  classTrackInfo = (*env)->FindClass(env,"com/coder80/scaner/Track_Info");
	// 获取Track_Info类的构造函数ID
	jmethodID midInit = (*env)->GetMethodID(env,classTrackInfo,"<init>", "()V");
	//构造Track_Info对象
	jobject objTrackInfo = (*env)->NewObject(env,classTrackInfo,midInit);


(类容较多,分为两篇博客进行介绍----JNI实例3---扫描SD卡中mp3文件,native函数中使用自定义的类)




    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3