当前位置:  编程技术>移动开发
本页文章导读:
    ▪iomemory地址被强占(一)        iomemory地址被抢占(一)最近做的一个项目,系统启动时发现有warning,并打印出了一堆dump stack。 看了下代码,发现是在esai的probe函数中调用request_mem_region时失败代码走到了错误处理的部分。 错.........
    ▪ struts2开发环境筹建模板        struts2开发环境搭建模板 jar包: struts.xml ......
    ▪ 运用代码为textview设置drawableLeft       使用代码为textview设置drawableLeft原问题来自于CSDN问答频道,更多见:http://ask.csdn.net/questions/903 原问题描述: xml中的textView: <TextView android:id="@+id/bookTitle" android:layout_width="match_pa.........

[1]iomemory地址被强占(一)
    来源: 互联网  发布时间: 2014-02-18
iomemory地址被抢占(一)

最近做的一个项目,系统启动时发现有warning,并打印出了一堆dump stack。
看了下代码,发现是在esai的probe函数中调用request_mem_region时失败代码走到了错误处理的部分。
错误处理中disable了一个clock,warning的内容是说该clock没enable就disable了。

从代码看,存在两个问题:
1、request_mem_region为什么会失败。
2、为什么在disable clock之前没有enable。

先看看request_mem_region为什么会失败。
经大牛指点,request_mem_region失败,应该是因为申请的一块内存,部分/全部已被占用,所以导致申请失败。
为了看看申请的内存是否与其他io申请的内存释放有冲突,将/proc/iomem文件cat出来,发现esai申请的内存与ssi-0申请的内存重叠。
对照cpu的reference manual,发现esai很守规矩,使用的是memory map中给自己指定的memory范围;而ssi-0没使用memory map中指定的内存范围,抢占了esai的内存范围。
找到esai base address和ssi-0(对应的是硬件ssi-1) base address定义,发现定义没问题,与memory map中一致。
在esai和ssi的probe函数中加log,发现首先是ssi-1申请了正确的内存,ssi-2也申请了正确的内存,接下来ssi-0申请的内存范围是esai的内存范围。
因为ssi在esai前面进行的probe,导致esai申请内存时,内存已经被ssi-0申请了去,所以失败。
可疑点是,ssi的顺序为什么是1、2、0,而不是0、1、2。
看了board文件中添加resource的地方,发现是先添加了ssi 1、2、3,然后添加了esai。
跟了下添加ssi resource的代码,发现知道的序号其实用作了数组下标,数组下标都是从0开始的,这儿为什么是1、2、3?
是不是添加ssi 1\2\3的时候,1、2没问题,由于ssi只有0\1\2,添加3的时候,抢占了esai的位置。
将board中的ssi 1\2\3改为0\1\2,果然问题解决。

若只是止步于此,少了些乐趣。
不仅要知其然,也要知其所以然。

先看看request_mem_region的实现。

 

#define request_mem_region(start, n, name) __request_region(&iomem_resource, (start), (n), (name), 0)


看看iomem_resource的定义:

struct resource iomem_resource = {
	.name	= "PCI mem",
	.start	= 0,
	.end	= -1,
	.flags	= IORESOURCE_MEM,
};


resource type有以下几种类型:

#define IORESOURCE_IO		0x00000100
#define IORESOURCE_MEM		0x00000200
#define IORESOURCE_IRQ		0x00000400
#define IORESOURCE_DMA		0x00000800
#define IORESOURCE_BUS		0x00001000


看看__request_region的实现:

/**
 * __request_region - create a new busy resource region
 * @parent: parent resource descriptor
 * @start: resource start address
 * @n: resource region size
 * @name: reserving caller's ID string
 * @flags: IO resource flags
 */
struct resource * __request_region(struct resource *parent,
				   resource_size_t start, resource_size_t n,
				   const char *name, int flags)
{
	// 定义并初始化一个wait queue
	/*
	#define DECLARE_WAITQUEUE(name, tsk)					\
	wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
	*/
	/*
	#define __WAITQUEUE_INITIALIZER(name, tsk) {				\
	.private	= tsk,						\
	.func		= default_wake_function,			\
	.task_list	= { NULL, NULL } }
	*/
	DECLARE_WAITQUEUE(wait, current);
	
	/*
/*
 * Resources are tree-like, allowing
 * nesting etc..
 */
struct resource {
	resource_size_t start;
	resource_size_t end;
	const char *name;
	unsigned long flags;
	struct resource *parent, *sibling, *child;
};
	*/
	/*
/**
 * kzalloc - allocate memory. The memory is set to zero.
 * @size: how many bytes of memory are required.
 * @flags: the type of memory to allocate (see kmalloc).
 */
static inline void *kzalloc(size_t size, gfp_t flags)
{
	return kmalloc(size, flags | __GFP_ZERO);
}
	*/
	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);

	if (!res)
		return NULL;

	res->name = name;
	res->start = start;
	res->end = start + n - 1;
	res->flags = IORESOURCE_BUSY;
	res->flags |= flags;

	write_lock(&resource_lock);

	for (;;) {
		struct resource *conflict;

		// 检查申请的内存与其他内存是否冲突
		/×
/* Return the conflict entry if you can't request it */
static struct resource * __request_resource(struct resource *root, struct resource *new)
{
	resource_size_t start = new->start;
	resource_size_t end = new->end;
	struct resource *tmp, **p;

	// 头比尾大,自相矛盾
	if (end < start)
		return root;
	// 头还在根的头前面,越界了
	if (start < root->start)
		return root;
	// 尾在根的尾后面,也越界了
	if (end > root->end)
		return root;
	// 从下面的循环看,root的所有child应该是从低地址到高地址依次排开,并通过他们的sibling进行关联。
	// 刚开始,p指向root的最大孩子,也就是地址最低的,并判断其与new是否冲突。
	// 若不冲突,通过最大孩子的sibling成员,找到它的下一个兄弟,并判断其与new是否冲突。
	// 这样依次判断下去,直到找到了一个空child,或者找到的找到的child的start还在new的end之后,也即完全在new之后。
	p = &root->child;
	for (;;) {
		tmp = *p;
		if (!tmp || tmp->start > end) {
			new->sibling = tmp;
			*p = new;
			new->parent = root;
			return NULL;
		}
		p = &tmp->sibling;
		if (tmp->end < start)
			continue;
		return tmp;
	}
}
		×/
		conflict = __request_resource(parent, res);
		if (!conflict)
			break;
		// 若有冲突,但冲突的不是根,并且conflict的标志并没有说是busy,也就是说并没有被占用,则说明new落在了原来根的一个child的范围内。
		// 也就是说conflict其实是new的根,那就将conflict赋值为new的根,再次进行冲突检测。
		if (conflict != parent) {
			parent = conflict;
			if (!(conflict->flags & IORESOURCE_BUSY))
				continue;
		}
		// 如果有冲突,并且conflict和new都是可软件多路复用的,则说明暂时是被别人占用了,
		// 要做到就是把锁释放了,并等待内存被释放
		if (conflict->flags & flags & IORESOURCE_MUXED) {
			/*
/*
 * This is compatibility stuff for IO resources.
 *
 * Note how this, unlike the above, knows about
 * the IO flag meanings (busy etc).
 *
 * request_region creates a new busy region.
 *
 * check_region returns non-zero if the area is already busy.
 *
 * release_region releases a matching busy region.
 */

static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);

void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
{
	unsigned long flags;

	wait->flags &= ~WQ_FLAG_EXCLUSIVE;
	spin_lock_irqsave(&q->lock, flags);
	__add_wait_queue(q, wait);
	spin_unlock_irqrestore(&q->lock, flags);
}

static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
	list_add(&new->task_list, &head->task_list);
}
			*/
			add_wait_queue(&muxed_resource_wait, &wait);
			// 释放锁
			write_unlock(&resource_lock);
			// TASK_INTERRUPTIBLE是可以被信号和wake_up()唤醒的,当信号到来时,进程会被设置为可运行。
			// TASK_UNINTERRUPTIBLE只能被wake_up()唤醒。
			set_current_state(TASK_UNINTERRUPTIBLE);
			/*
asmlinkage void __sched schedule(void)
{
	struct task_struct *tsk = current;

	sched_submit_work(tsk);
	__schedule();
}

static inline void sched_submit_work(struct task_struct *tsk)
{
	if (!tsk->state)
		return;
	/*
	 * If we are going to sleep and we have plugged IO queued,
	 * make sure to submit it to avoid deadlocks.
	 */
	if (blk_needs_flush_plug(tsk))
		blk_schedule_flush_plug(tsk);
}
			*/
			// 调度函数,不能简单的一笔带过
			schedule();
			remove_wait_queue(&muxed_resource_wait, &wait);
			write_lock(&resource_lock);
			continue;
		}
		/* Uhhuh, that didn't work out.. */
		kfree(res);
		res = NULL;
		break;
	}
	write_unlock(&resource_lock);
	return res;
}


上面有将wait添加到queue,在__release_region中调用了wake_up用来唤醒等待的进程。

/**
 * __release_region - release a previously reserved resource region
 * @parent: parent resource descriptor
 * @start: resource start address
 * @n: resource region size
 *
 * The described resource region must match a currently busy region.
 */
void __release_region(struct resource *parent, resource_size_t start,
			resource_size_t n)
{
	struct resource **p;
	resource_size_t end;

	p = &parent->child;
	end = start + n - 1;

	write_lock(&resource_lock);

	for (;;) {
		struct resource *res = *p;

		if (!res)
			break;
		if (res->start <= start && res->end >= end) {
			if (!(res->flags & IORESOURCE_BUSY)) {
				p = &res->child;
				continue;
			}
			if (res->start != start || res->end != end)
				break;
			*p = res->sibling;
			write_unlock(&resource_lock);
			if (res->flags & IORESOURCE_MUXED)
				wake_up(&muxed_resource_wait);
			kfree(res);
			return;
		}
		p = &res->sibling;
	}

	write_unlock(&resource_lock);

	printk(KERN_WARNING "Trying to free nonexistent resource "
		"<%016llx-%016llx>\n", (unsigned long long)start,
		(unsigned long long)end);
}


 


    
[2] struts2开发环境筹建模板
    来源: 互联网  发布时间: 2014-02-18
struts2开发环境搭建模板

jar包:




struts.xml

  • <?xml version="1.0" encoding="UTF-8"?>  
  • <!DOCTYPE struts PUBLIC  
  •     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
  •     "http://struts.apache.org/dtds/struts-2.3.dtd">  
  • <struts>  
  •   
  • </struts>  


  • web.xml

  • <?xml version="1.0" encoding="UTF-8"?>  
  • <web-app version="2.5"   
  •     xmlns="http://java.sun.com/xml/ns/javaee"   
  •     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  •     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  •     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  •       
  •       
  •     <!-- 添加启动struts2MVC框架的过滤器 -->  
  •     <filter>  
  •       <filter-name>struts2</filter-name>  
  •       <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  •     </filter>  
  •       
  •     <filter-mapping>  
  •         <filter-name>struts2</filter-name>  
  •         <url-pattern>/*</url-pattern>  
  •     </filter-mapping>  
  •       
  •   <welcome-file-list>  
  •     <welcome-file>index.jsp</welcome-file>  
  •   </welcome-file-list>  
  • </web-app> 

  •     
    [3] 运用代码为textview设置drawableLeft
        来源: 互联网  发布时间: 2014-02-18
    使用代码为textview设置drawableLeft

    原问题来自于CSDN问答频道,更多见:http://ask.csdn.net/questions/903

    原问题描述:

    xml中的textView:

    <TextView
            android:id="@+id/bookTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:drawableLeft="@drawable/checkmark"
            android:gravity="center_vertical"
            android:text
            android:textSize="24dip"
            android:maxLines="1"
    
            android:ellipsize="end"/>


    如程序中所见我在xml中设置了 DrawableLeft。
    我想在代码中改变drawable。
    有什么方法可以使用代码为textview设置drawableLeft呢?

    public void  setCompoundDrawables  (Drawable left, Drawable top, Drawable right, Drawable bottom);


    类似调用方法如下:

    1.在XML中使用

    android:drawableLeft="@drawable/icon"


    2.代码中动态变化

    Drawable drawable= getResources().getDrawable(R.drawable.drawable);
    /// 这一步必须要做,否则不会显示.
    drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
    myTextview.setCompoundDrawables(drawable,null,null,null);


    也或参考另一个函数

    public void setCompoundDrawablesWithIntrinsicBounds (Drawable left,
    Drawable top, Drawable right, Drawable bottom)


     


        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    数据库 iis7站长之家
    ▪根据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