bug信息:
10-16 17:27:20.250: D/AndroidRuntime(14662): Shutting down VM
10-16 17:27:20.250: W/dalvikvm(14662): threadid=1: thread exiting with uncaught exception (group=0x40a5e228)
10-16 17:27:20.250: E/AndroidRuntime(14662): FATAL EXCEPTION: main
10-16 17:27:20.250: E/AndroidRuntime(14662): java.lang.IllegalArgumentException: parameter must be a descendant of this view
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.ViewGroup.offsetRectBetweenParentAndChild(ViewGroup.java:4460)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.ViewGroup.offsetDescendantRectToMyCoords(ViewGroup.java:4397)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.widget.HorizontalScrollView.isWithinDeltaOfScreen(HorizontalScrollView.java:1054)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.widget.HorizontalScrollView.onSizeChanged(HorizontalScrollView.java:1415)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.View.setFrame(View.java:11442)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.View.layout(View.java:11353)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.ViewGroup.layout(ViewGroup.java:4531)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.View.layout(View.java:11359)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.ViewGroup.layout(ViewGroup.java:4531)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.View.layout(View.java:11359)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.ViewGroup.layout(ViewGroup.java:4531)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.View.layout(View.java:11359)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.ViewGroup.layout(ViewGroup.java:4531)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1665)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2695)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.os.Handler.dispatchMessage(Handler.java:99)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.os.Looper.loop(Looper.java:154)
10-16 17:27:20.250: E/AndroidRuntime(14662): at android.app.ActivityThread.main(ActivityThread.java:4974)
10-16 17:27:20.250: E/AndroidRuntime(14662): at java.lang.reflect.Method.invokeNative(Native Method)
10-16 17:27:20.250: E/AndroidRuntime(14662): at java.lang.reflect.Method.invoke(Method.java:511)
10-16 17:27:20.250: E/AndroidRuntime(14662): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-16 17:27:20.250: E/AndroidRuntime(14662): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-16 17:27:20.250: E/AndroidRuntime(14662): at dalvik.system.NativeStart.main(Native Method)
场景描述:
用listview写的一个书架,点击超出一屏区域的书本进入阅读模块,在返回时会抛出如上崩溃信息,若是未超出屏幕区域的书本则不会崩溃。
分析与解决:
parameter must be a descendant of this view 是说这个parameter必须是这个view的子孙...
因为我的listview外面嵌套的有一个HorizontalScrollView所以很有可能就是它们两个冲突导致的,跟踪查看HorizontalScrollView的源码及分析日志信息,出现这个bug的前提条件:当listview向下滚动了再返回时会调用HorizontalScrollView的onSizeChanged()方法,在onSizeChanged()方法中调用了findfocus方法得到返回的界面中当前拥有焦点的view。从上面那句话话可以看出关键点就在这个view上,如果它是HorizontalScrollView 的子孙程序就不会崩溃了,所以让程序返回时焦点直接落在某一指定view上就可以了。我这时是让listview一直拥有焦点,覆写了它的isFocused方法让它一直返回true,问题就解决了!!
进入内核根目录:
CMDLINE="console=ttySAC0 mem=64M"
选择General setup-->
(*)Initial RAM filesystem and RAM disk (...) suppor
Initramfs source file(s) ==>路径:/usr/forlinux/root/rootfs
先看datasheet:
硬件是支持的,再看驱动:linux-2.6.32.2\drivers\serial\samsung.c中
if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) ulcon |= S3C2410_LCON_PODD; else ulcon |= S3C2410_LCON_PEVEN; } else { ulcon |= S3C2410_LCON_PNONE; }
目前的驱动中并没有提space,mark校验,原来如此,这个驱动必须得改了!!!
先大概说得几处改:
①:termios.h中看有没有CMSPAR 没有的话加上!
# define CMSPAR 010000000000 /* mark or space (stick) parity */
经过搜索发现是有的,这个可以用了,看看驱动中有没有办法直接判断它!
159 #define CMSPAR 010000000000 /* mark or space (stick) parity */http://lxr.free-electrons.com/source/arch/arm/include/asm/termbits.h?v=2.6.32;a=arm#L159
②:
32 #include <linux/module.h> 33 #include <linux/ioport.h> 34 #include <linux/io.h> 35 #include <linux/platform_device.h> 36 #include <linux/init.h> 37 #include <linux/sysrq.h> 38 #include <linux/console.h> 39 #include <linux/tty.h> 40 #include <linux/tty_flip.h> 41 #include <linux/serial_core.h> 42 #include <linux/serial.h> 43 #include <linux/delay.h> 44 #include <linux/clk.h> 45 #include <linux/cpufreq.h> 46 47 #include <asm/irq.h> 48 49 #include <mach/hardware.h> 50 #include <mach/map.h> 51 52 #include <plat/regs-serial.h>
③:
在/arch/arm/plat-s3c/include/plat/regs-serial.h找到这么一段定义:
65 #define S3C2410_LCON_PNONE (0x0) //对应无校验 66 #define S3C2410_LCON_PEVEN (0x5 << 3) //对应偶校验 67 #define S3C2410_LCON_PODD (0x4 << 3) //对应奇校验 68 #define S3C2410_LCON_PMASK (0x7 << 3) //对应SPACE校验(这个名字实在纠结,叫PSPACE多好!)
?MARK校验哪里去了呢??还应该有一个:
#define S3C2410_LCON_PMARK (0x6 << 3) //对应MARK校验
这个分析就算齐了,再加上判断:
if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) { if(termios->c_cflag & CMSPAR) ulcon |= S3C2410_LCON_PMARK; //MARK else ulcon |= S3C2410_LCON_PODD; //ODD } else { if ((termios->c_cflag & CMSPAR)) ulcon |= S3C2410_LCON_PMASK; //SPACE else ulcon |= S3C2410_LCON_PEVEN; //EVEN } }
这样这四种校验就都有了~~明天实验!!!
========================================================================================
2012年10月18日18:35:16:结果好悲催呀!!!
TFTP from server 192.168.1.229; our IP address is 192.168.1.230
Filename 'zImage.img'.
Load address: 0x30008000
Loading: T #################################################################
#################################################################
#################################################################
#################################################################
#
done
Bytes transferred = 3828524 (3a6b2c hex)
## Booting kernel from Legacy Image at 30008000 ...
Image Name: kangear
Created: 2012-10-18 1:44:02 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3828460 Bytes = 3.7 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
内核都启动不了了,我晕,再编译一次!!试试
2012年10月18日18:49:54:
这有用到:S3C2410_LCON_PMASK
1340 switch (ulcon & S3C2410_LCON_PMASK) { 1341 case S3C2410_LCON_PEVEN: 1342 *parity = 'e'; 1343 break; 1344 1345 case S3C2410_LCON_PODD: 1346 *parity = 'o'; 1347 break; 1348 1349 case S3C2410_LCON_PNONE: 1350 default: 1351 *parity = 'n'; 1352 }
先不管了,先编译再说吧!
=========================================================================
2012年10月18日19:41:42:
可以运行了,不过还是和以前的一样,我索性把 odd 默认成 mark看它还行不行!!!
if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) { //if(termios->c_cflag & CMSPAR) ulcon |= S3C2410_LCON_PMARK; //else // ulcon |= S3C2410_LCON_PODD; }else{ //if(termios->c_cflag & CMSPAR) ulcon |= S3C2410_LCON_PMASK; //else // ulcon |= S3C2410_LCON_PEVEN; } } else { ulcon |= S3C2410_LCON_PNONE; }
============================================================================
2012年10月18日20:04:35:
if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) { //if(termios->c_cflag & CMSPAR) ulcon |= S3C2410_LCON_PMASK; //else // ulcon |= S3C2410_LCON_PODD; }else{ //if(termios->c_cflag & CMSPAR) ulcon |= S3C2410_LCON_PMARK; //else // ulcon |= S3C2410_LCON_PEVEN; } } else { ulcon |= S3C2410_LCON_PNONE; }
配上完整测试程序:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <errno.h> main() { int fd; int i; int len; int n = 0; char b[1]={0x03}; char read_buf[256]; char write_buf[256]; struct termios opt; fd = open("/dev/ttySAC1", O_RDWR | O_NOCTTY); //默认为阻塞读方式 if(fd == -1) { perror("open serial 0\n"); exit(0); } tcgetattr(fd, &opt); cfsetispeed(&opt, B9600); cfsetospeed(&opt, B9600); if(tcsetattr(fd, TCSANOW, &opt) != 0 ) { perror("tcsetattr error"); return -1; } opt.c_cflag &= ~CSIZE; opt.c_cflag |= CS8; opt.c_cflag &= ~CSTOPB; opt.c_cflag &= ~PARENB; opt.c_cflag &= ~INPCK; opt.c_cflag |= (CLOCAL | CREAD); opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); opt.c_oflag &= ~OPOST; opt.c_oflag &= ~(ONLCR | OCRNL); //添加的 opt.c_iflag &= ~(ICRNL | INLCR); opt.c_iflag &= ~(IXON | IXOFF | IXANY); //添加的 // //===================================== // //space opt.c_cflag |= PARENB | CS8 | CMSPAR | PARODD; // //===================================== //===================================== //mark // opt.c_cflag |= PARENB | CS8 | CMSPAR ; // opt.c_cflag &= ~PARODD; //===================================== opt.c_cc[VTIME] = 0; opt.c_cc[VMIN] = 0; tcflush(fd, TCIOFLUSH); printf("configure complete\n"); if(tcsetattr(fd, TCSANOW, &opt) != 0) { perror("serial error"); return -1; } printf("start send and receive data\n"); while(1) { n = 0; len = 0; printf("hw\n"); bzero(read_buf, sizeof(read_buf)); //类似于memset bzero(write_buf, sizeof(write_buf)); write(fd,b,sizeof b); usleep(50000); } }
(无论发是0x01,0x03都不能进入单片机中断) 这样可以了,呀呀呀呀……………………………………………………………………
这样不太好,还是尽量改为通用的!去掉注释再看看:
================================================================================
2012年10月18日21:28:54:我无法忍受了,mark校验通过了,space怎么也不行,我重新定义一个:
#define S3C2410_LCON_PSPACE (0x7 << 3) //对应SPACE校验
===============================================================================
2012年10月18日21:32:24:上一个先不说,先来个这个:
if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) { //if(termios->c_cflag & CMSPAR) ulcon |= S3C2410_LCON_PMASK; //else // ulcon |= S3C2410_LCON_PODD; }else{ if(termios->c_cflag & CMSPAR) ulcon |= S3C2410_LCON_PMARK; else ulcon |= S3C2410_LCON_PEVEN; } } else { ulcon |= S3C2410_LCON_PNONE; }
说明:ODD校验强制转为SPACE校验!等会说结果……
2012年10月18日21:36:31:结果出来了,这样可以!!!PMASK也行,可以怎么老进入到ODD校验中去呢???
==============================================================================
算了,暂时不深入研究了,奇校验,偶校验在设计中用不到,控制台用 “无校验”,其它用“校验和”,一般没人用奇校验,偶校验就分别将其强制转化为 space,mark校验!!!!(2012年10月18日21:41:36)==================================================================================================================
2012年10月18日22:23:08:
最后定:
①:linux-2.6.32.2\drivers\serial\samsung.c
if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) { ulcon |= S3C2410_LCON_PMASK; }else{ ulcon |= S3C2410_LCON_PMARK; } } else { ulcon |= S3C2410_LCON_PNONE; }
②:linux-2.6.32.2/arch/arm/plat-s3c/include/plat/regs-serial.h
完!65 #define S3C2410_LCON_PNONE (0x0) 66 #define S3C2410_LCON_PEVEN (0x5 << 3) 67 #define S3C2410_LCON_PODD (0x4 << 3) 68 #define S3C2410_LCON_PMASK (0x7 << 3) 69 #define S3C2410_LCON_PMARK (0X6 << 3) //add by kangear for mark stick 70 #define S3C2410_LCON_STOPB (1<<2) 71 #define S3C2410_LCON_IRM (1<<6)
附上linux测试程序:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <errno.h> #include <string.h> main() { int fd; int i; int len; int n = 0; char b[1]={0x03}; char read_buf[256]; char write_buf[256]; struct termios opt; fd = open("/dev/ttySAC1", O_RDWR | O_NOCTTY); //默认为阻塞读方式 if(fd == -1) { perror("open serial 0\n"); exit(0); } tcgetattr(fd, &opt); cfsetispeed(&opt, B9600); cfsetospeed(&opt, B9600); if(tcsetattr(fd, TCSANOW, &opt) != 0 ) { perror("tcsetattr error"); return -1; } opt.c_cflag &= ~CSIZE; opt.c_cflag |= CS8; opt.c_cflag &= ~CSTOPB; opt.c_cflag &= ~PARENB; opt.c_cflag &= ~INPCK; opt.c_cflag |= (CLOCAL | CREAD); opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); opt.c_oflag &= ~OPOST; opt.c_oflag &= ~(ONLCR | OCRNL); //添加的 opt.c_iflag &= ~(ICRNL | INLCR); opt.c_iflag &= ~(IXON | IXOFF | IXANY); //添加的 // //===================================== // //space // opt.c_cflag |= PARENB | CS8 | CMSPAR ; // //===================================== //===================================== //mark opt.c_cflag |= PARENB | CS8 | CMSPAR ; opt.c_cflag &= ~PARODD; //===================================== opt.c_cc[VTIME] = 0; opt.c_cc[VMIN] = 0; tcflush(fd, TCIOFLUSH); printf("configure complete\n"); if(tcsetattr(fd, TCSANOW, &opt) != 0) { perror("serial error"); return -1; } printf("start send and receive data\n"); while(1) { n = 0; len = 0; printf("hw\n"); bzero(read_buf, sizeof(read_buf)); //类似于memset bzero(write_buf, sizeof(write_buf)); write(fd,b,sizeof b); usleep(50000); } }