当前位置:  编程技术>移动开发
本页文章导读:
    ▪Java 不同进制数变换        Java 不同进制数转换 Java 不同进制数转换 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import jav.........
    ▪ Oauth有关资源        Oauth相关资源 oauth-signposthttp://code.google.com/p/oauth-signpost/新浪apihttp://open.weibo.com/development回调要与客户端填写一致,就这么简单android service之打不死的小强http://www.eoeandroid.com/thread-8195-1-1.html.........
    ▪ MTK内存储器管理       MTK内存管理   MTK 内存管理 分类: MTK2011-03-16 16:27 1372人阅读 评论(0) 收藏 举报 MTK 手机用的操作系统是 nucleus, 这是一个rtfs(实时操作系统),这个rtfs本身是不带内存管理功能,所以MTK.........

[1]Java 不同进制数变换
    来源: 互联网  发布时间: 2014-02-18
Java 不同进制数转换

Java 不同进制数转换

import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.io.Serializable;  
import java.security.MessageDigest;  
import java.security.NoSuchAlgorithmException;  
  
public final class Converts {  
  
 public final static char[] BToA = "0123456789abcdef".toCharArray() ;  
 private Converts() {  
 }  
  
 /** 
  * 把16进制字符串转换成字节数组 
  * @param hex 
  * @return 
  */  
 public static byte[] hexStringToByte(String hex) {  
  int len = (hex.length() / 2);  
  byte[] result = new byte[len];  
  char[] achar = hex.toCharArray();  
  for (int i = 0; i < len; i++) {  
   int pos = i * 2;  
   result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));  
  }  
  return result;  
 }  
  
 private static byte toByte(char c) {  
  byte b = (byte) "0123456789ABCDEF".indexOf(c);  
  return b;  
 }  
  
 /** 
  * 把字节数组转换成16进制字符串 
  * @param bArray 
  * @return 
  */  
 public static final String bytesToHexString(byte[] bArray) {  
  StringBuffer sb = new StringBuffer(bArray.length);  
  String sTemp;  
  for (int i = 0; i < bArray.length; i++) {  
   sTemp = Integer.toHexString(0xFF & bArray[i]);  
   if (sTemp.length() < 2)  
    sb.append(0);  
   sb.append(sTemp.toUpperCase());  
  }  
  return sb.toString();  
 }  
  
 /** 
  * 把字节数组转换为对象 
  * @param bytes 
  * @return 
  * @throws IOException 
  * @throws ClassNotFoundException 
  */  
 public static final Object bytesToObject(byte[] bytes) throws IOException, ClassNotFoundException {  
  ByteArrayInputStream in = new ByteArrayInputStream(bytes);  
  ObjectInputStream oi = new ObjectInputStream(in);  
  Object o = oi.readObject();  
  oi.close();  
  return o;  
 }  
  
 /** 
  * 把可序列化对象转换成字节数组 
  * @param s 
  * @return 
  * @throws IOException 
  */  
 public static final byte[] objectToBytes(Serializable s) throws IOException {  
  ByteArrayOutputStream out = new ByteArrayOutputStream();  
  ObjectOutputStream ot = new ObjectOutputStream(out);  
  ot.writeObject(s);  
  ot.flush();  
  ot.close();  
  return out.toByteArray();  
 }  
   
 public static final String objectToHexString(Serializable s) throws IOException{  
  return bytesToHexString(objectToBytes(s));  
 }  
   
 public static final Object hexStringToObject(String hex) throws IOException, ClassNotFoundException{  
  return bytesToObject(hexStringToByte(hex));  
 }  
   
 /** 
  * @函数功能: BCD码转为10进制串(阿拉伯数据) 
  * @输入参数: BCD码 
  * @输出结果: 10进制串 
  */  
 public static String bcd2Str(byte[] bytes){  
  StringBuffer temp=new StringBuffer(bytes.length*2);  
  
  for(int i=0;i>>4));  
   temp.append((byte)(bytes[i]& 0x0f));  
  }  
  return temp.toString().substring(0,1).equalsIgnoreCase("0")?temp.toString().substring(1):temp.toString();  
 }  
  
 /** 
  * @函数功能: 10进制串转为BCD码 
  * @输入参数: 10进制串 
  * @输出结果: BCD码 
  */  
 public static byte[] str2Bcd(String asc) {  
  int len = asc.length();  
  int mod = len % 2;  
  
  if (mod != 0) {  
   asc = "0" + asc;  
   len = asc.length();  
  }  
  
  byte abt[] = new byte[len];  
  if (len >= 2) {  
   len = len / 2;  
  }  
  
  byte bbt[] = new byte[len];  
  abt = asc.getBytes();  
  int j, k;  
  
  for (int p = 0; p < asc.length()/2; p++) {  
   if ( (abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {  
    j = abt[2 * p] - '0';  
   } else if ( (abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {  
    j = abt[2 * p] - 'a' + 0x0a;  
   } else {  
    j = abt[2 * p] - 'A' + 0x0a;  
   }  
  
   if ( (abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {  
    k = abt[2 * p + 1] - '0';  
   } else if ( (abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {  
    k = abt[2 * p + 1] - 'a' + 0x0a;  
   }else {  
    k = abt[2 * p + 1] - 'A' + 0x0a;  
   }  
  
   int a = (j << 4) + k;  
   byte b = (byte) a;  
   bbt[p] = b;  
  }  
  return bbt;  
 }  
   
 public static String BCD2ASC(byte[] bytes) {  
  StringBuffer temp = new StringBuffer(bytes.length * 2);  
  
  for (int i = 0; i < bytes.length; i++) {  
   int h = ((bytes[i] & 0xf0) >>> 4);  
   int l = (bytes[i] & 0x0f);     
   temp.append(BToA[h]).append( BToA[l]);  
  }  
  return temp.toString() ;  
 }  
   
 /** 
  * MD5加密字符串,返回加密后的16进制字符串 
  * @param origin 
  * @return 
  */  
 public static String MD5EncodeToHex(String origin) {   
     return bytesToHexString(MD5Encode(origin));  
   }  
   
 /** 
  * MD5加密字符串,返回加密后的字节数组 
  * @param origin 
  * @return 
  */  
 public static byte[] MD5Encode(String origin){  
  return MD5Encode(origin.getBytes());  
 }  
   
 /** 
  * MD5加密字节数组,返回加密后的字节数组 
  * @param bytes 
  * @return 
  */  
 public static byte[] MD5Encode(byte[] bytes){  
  MessageDigest md=null;  
  try {  
   md = MessageDigest.getInstance("MD5");  
   return md.digest(bytes);  
  } catch (NoSuchAlgorithmException e) {  
   e.printStackTrace();  
   return new byte[0];  
  }  
    
 }  
}  

    
[2] Oauth有关资源
    来源: 互联网  发布时间: 2014-02-18
Oauth相关资源
oauth-signpost
http://code.google.com/p/oauth-signpost/

新浪api
http://open.weibo.com/development


回调要与客户端填写一致,就这么简单


android service之打不死的小强
http://www.eoeandroid.com/thread-8195-1-1.html

    
[3] MTK内存储器管理
    来源: 互联网  发布时间: 2014-02-18
MTK内存管理

  MTK 内存管理
分类: MTK2011-03-16 16:27 1372人阅读 评论(0) 收藏 举报

MTK 手机用的操作系统是 nucleus, 这是一个rtfs(实时操作系统),这个rtfs本身是不带内存管理功能,所以MTK自己写的内存管理。

(nucleus在系统初始化完毕时,会调用Application_Initialize,参数就是可使用内存的起始地址)

大体上来分,MTK内存可以分为3种:

control buffer 
 平常使用的OslMalloc就是这个内存。

 这个内存内部实现是按块来划分的(pool),具体的配置可以custom_config.c 文件里的custom_config_ctrl_buff_info()里看到

 里面的size 指定了这个块的大小,no_of_buff 指定了有多少个这样的块。

 按块来管理内存,可以有效地控制内存的碎片,管理也相对简单,可能会造成内存的一些浪费

 对于手机这种需要长时间运行不重起的设备来说,还是很有必要的。

 MTK 默认最大块的大小为 2048byte,也就是2k。这就是说用OslMalloc 分配内存默认最大能分配到2k,

 这个可以看custom_config_ctrl_buff_info()配置可以看到。

 可以通过修改里面的配置来改变这个值,不过一般不这么做,因为MTK提供了其他的内存管理方式

#define OslMalloc(nob)  get_ctrl_buffer(nob)
#define OslMfree(frp)   free_ctrl_buffer(frp)

少于2K 使用get_ctrl_buffer。
大于2K 使用adm

system buffer 
 system buffer 平时我们用不到,听名字也是系统使用的。

 主要是提供 run-time usage,是一块 semi-static memory(什么意思?)

     比如 block of task, task stack ,control block of control buffer ,buffer pool等等

     在 custom_config.c里面配置 ,主要有两个宏 GLOBAL_MEM_SIZE  和 GLOBAL_DEBUG_MEM_SIZE
     两个 static 数组 static kal_uint32 System_Mem_Pool[GLOBAL_MEM_SIZE/sizeof(kal_uint32)];  
     和                     static kal_uint32 Debug_Mem_Pool[GLOBAL_DEBUG_MEM_SIZE/sizeof(kal_uint32)];

     为了满足时间要求,也就是要求快速分配,系统内存又分为 internal system memory 和 system memory
     前者link 到 internal SRAM ,后者link 到 external SRAM

app buffer 
 app的内存是使用通过MTK 提供的一种ADM(application dynamic memory)机制来实现,ADM 主要的功能是通过管理一个数组来实现内存的分配。

 ADM 也是通过内存块(pool)来实现的,具体无法看到其代码。app通过这个adm这个机制,可以更加灵活的使用内存,比如分配大内存(大于2k)等等

 主要函数


 创建 adm
 KAL_ADM_ID kal_adm_create(void *mem_addr, kal_uint32 size, kal_uint32 *subpool_size, kal_bool islogging);

 删除函数
 kal_status kal_adm_delete(KAL_ADM_ID adm_id);

 分配函数 
 extern void *kal_adm_internal_alloc(KAL_ADM_ID adm_id, kal_uint32 size, char *filename, kal_uint32 line);
 #define kal_adm_alloc(adm_id, size) kal_adm_internal_alloc(adm_id, size, __FILE__, __LINE__)

 释放函数
 extern void kal_adm_free(KAL_ADM_ID adm_id, void *mem_addr);

在 MTK 内存管理简单总结  中,大体说了MTK的三种内存分配方式,对于第三种,也就是app buffer,是比较丰富的一种。

在 MTK 平台中也有许多具体的实现。在代码里搜索一下 kal_adm_create 就可以发现有许多地方使用了。

看一个比较典型的使用:

在文件app_mem.c里,有两个memory pool,一个是用于应用之间共享内存,另一个是用于屏幕内存。

第一种内存,主要是用于各种应用之间共享内存(以下简称ASM),这样可以节省内存,MTK实现了一种机制,可以在多个应用之间共享内存

当当前应用想获得的共享内存不足时,MTK会通知后台应用释放相应的内存。这套机制在AppMemMgr.c里面实现。

先看一下初始化该内存次池函数

void applib_mem_ap_init(void (*stop_finish_callback_by_MMI)(kal_uint32 app_id, kal_uint32 string_id, kal_bool result))

这个函数带有一个参数,这个参数是一个函数指针,该回调函数有3个参数,app_id,(应用id),string_id 和 result。

这个回调函数比较特别,是当一个后台应用 被 要求释放内存,释放完毕后调用的。

为什么要搞这么一个函数,因为一些应用比较复杂,释放内存的同时需要关闭一些资源,而这些动作是异步的,

等这些异步发的操作多完成时,调用一些函数,告诉ASM,内存释放完毕。

具体实现:通过 调用 kal_adm_create 来创建一个内存池,然后保存了一些回调函数,没有什么特别的地方,

内存池的大小 是 APPLIB_MEM_AP_POOL_SIZE 来确定的,可以通过修改 app_asm_pool_union 来修改内存池的大小。

应用分配内存

void *applib_mem_ap_alloc(kal_uint32 app_id, kal_uint32 mem_size)

应用通过上面的函数来获得ASM的内存,参数一 app_id,是当前分配内存的id,这个id需要自己定义,并且注册(下文说明),

参数二是实际需要分配的内存大小。

具体实现:先mem_size 进行了处理,让其四字节对齐。然后通过 kal_adm_alloc 获得内存,不过这个内存加上了一个头结构和尾结构,

(头和尾都加入了特殊字符,再释放时进行检查,这个可以判断内存是否越界)。然后把这个内存插入到list的头部。

昨天说到了内存的分配。下面看一下内存释放

主要进行了3步:

static void applib_mem_ap_free_int(void *mem_ptr)
{
    /*----------------------------*/
    /* Local Variables                                                */
    /*----------------------------*/
    applib_mem_header_struct *header, *prev_node, *remove_node;
    applib_mem_footer_struct *footer;

    /*----------------------------*/
    /* Code Body                                                      */
    /*----------------------------*/
    if (g_applib_mem_cntx.app_pool_id)    /* Normal mode */
    {
        ASSERT(mem_ptr && APPLIB_MEM_ALIGNED_4(mem_ptr));
        
        header = ((applib_mem_header_struct*) mem_ptr) - 1;
        footer = (applib_mem_footer_struct*) (((char*)mem_ptr) + header->chunk_size);

        ASSERT(APPLIB_MEM_COMP_PATTERN(header->guard_pattern, APPLIB_MEM_HEADER_PATTERN1) && 
               APPLIB_MEM_COMP_PATTERN(footer->guard_pattern, APPLIB_MEM_FOOTER_PATTERN1));

        /* 
         * Remove the block from linked list 
         *
         * It is not a fast algorithm, we can improve it by using double linked list, 
         * but we choose simpler design because
         * 1. Typically total allocation count is small
         * 2. We don't want to increase space overheads
         * 3. We don't want to access KAL ADM internal data structure
         */
        prev_node = &g_applib_mem_cntx.app_head;    
        ASSERT(prev_node->next);
        for (remove_node = prev_node->next;
             remove_node; 
             prev_node = remove_node, remove_node = prev_node->next)
        {
            if (remove_node == header)
            {
                break;
            }
        }
        ASSERT(remove_node);
        prev_node->next = remove_node->next;
        
        /* Set guard pattern */
        APPLIB_MEM_SET_PATTERN(header->guard_pattern, APPLIB_MEM_HEADER_PATTERN2);    
        APPLIB_MEM_SET_PATTERN(footer->guard_pattern, APPLIB_MEM_FOOTER_PATTERN2);

        /* Release the block */
    #ifdef APPLIB_MEM_USE_ADM
        kal_adm_free(g_applib_mem_cntx.app_pool_id, header);
    #else 
        free(header);
    #endif

        ASSERT(g_applib_mem_cntx.app_alloc_count > 0);
        g_applib_mem_cntx.app_alloc_count--;
    }
    else /* Full pool mode */
    {
        ASSERT(mem_ptr == g_applib_mem_ap_pool && g_applib_mem_cntx.app_alloc_count == 1);
        g_applib_mem_cntx.app_alloc_count = 0;
        g_applib_mem_cntx.app_id_of_full_pool = APPLIB_MEM_AP_ID_DUMMY; /* 0 */
        
    #ifdef APPLIB_MEM_USE_ADM    
        g_applib_mem_cntx.app_pool_id = kal_adm_create(
                                            g_applib_mem_ap_pool,
                                            APPLIB_MEM_AP_POOL_SIZE,
                                            (kal_uint32*) g_applib_mem_pool_chunk_size,
                                            KAL_FALSE);
    #else /* APPLIB_MEM_USE_ADM */
        g_applib_mem_cntx.app_pool_id = APPLIB_DUMMY_POOL_ID;
    #endif /* APPLIB_MEM_USE_ADM */
    }
}

取得内存的头部和尾部,(调试版本可以判断内存是否越界) 
从链表中删除这个节点 
调用 kal_adm_free 释放内存 
在MTK 内存管理简单总结 2 提到调用 applib_mem_ap_alloc 分配内存是需要一个应用id,这个id是需要自己增加,

而且在调用这个函数之前必须 调用 applib_mem_ap_register 注册这个id。需要注意的是最后一个参数,是一个回调函数,

这个回调函数是在共享内存不够使用时,ASM会调用这个函数,告诉应用需要释放共享内存,供其它应用使用。

增加 id  在 app_mem.h 的 applib_mem_ap_id_enum 里面,只要添加一个id就可以。

同样 屏幕内存也是通过ADM来管理,屏幕内存 是用来 创建 layer 用的,在MTK的某个版本开始,创建layer的内存是有要求的,

需要applib_mem_screen_alloc 分配的内存。

 

void *Malloc(uint32 dwSize)
{
#ifdef WIN32
 return (void *)malloc(dwSize);
#else
 return (void *)med_alloc_ext_mem(dwSize);
#endif
 
}

 

如何在MTK上分配一块较大的内存?
本文来自:我爱研发网(52RD.com) - R&D大本营
详细出处:http://www.52rd.com/bbs/Archive_Thread.asp?SID=89009&TID=2
如过分配比较大内存,慎用 OslMalloc 其对应内存池比较小,并且对单次分配内存大小有限制
建议用 med_alloc_ext_mem
其对应内存池大小 #define MED_EXT_MEM_SIZE (sizeof(med_ext_mem_union)) 
如果需要还可以增大

MTK是如何申请内存空间的???
本文来自:我爱研发网(52RD.com) - R&D大本营
详细出处:http://www.52rd.com/bbs/Archive_Thread.asp?SID=187949&TID=3
1 oslmalloc
用于control buffer申请,size有限制,一般使用于较小buffer(通常0 - 2k)的申请。
2 app_malloc
ASM机制。用于应用共享内存的申请,需要注册ID,如有内存冲突,系统会提示停掉正在使用的APP,供用户选择停止。
3 scr_malloc
用于屏幕buffer申请,模板内部使用。
4 med_ext_malloc 
用于申请较大块内存(2k - ?),从MED pool中。申请释放都比较简单,不用注册ID,但是注意free函数参数,需要对应2级指针。
med_free_ext_mem( (void **) &tempBuf );


MTK内存动态申请释放
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/feelinghappy/archive/2010/02/22/5317615.aspx
1. OslMalloc OslMfree 
为一个般的程序分配内存,用来保存一般性的数据,效率高,不能分配太大内存,else程序会挂掉

2. media_get_ext_buffer  media_free_ext_buffer 
可以分配较大内存,与OslMalloc 有着数量级区别,比如读一个比较大的文件操作时,要分配的buffer就要这个 ,这个不是在堆上分配的,和寄存器有关系

3. gui_malloc gui_free 
一般是用来合并图层,保存图层,MTK默认只分配了一个图层的空间,如果你用到了多层的话,就得另外分配内存了,就用这个
1. OslMalloc OslMfree 
  这两个函数就是直接define 的 ctrl buffer的函数 作用分配内存和malloc free功能类似 
  实际上是用一块内存池中分配和释放内存,具体实现是在ctrl_buff_pool.c里面做的

2. media_get_ext_buffer  media_free_ext_buffer 
  因为task之间的函数不便互相调用,MDI等task在分配内存的时候会使用这对函数,实际实现时通过给MOD_SAP发送request buffer消息来获取内存

3. gui_malloc gui_free 
  这对函数和第一对函数的实现时完全一样的 只是提供给不同的module使用而已

还有,我在网上看到一个名词“Ctrl Buffer机制”,这个到底是什么东东? 
Ctrl buffer机制实际上就是MTK内部的内存池管理机制的一种,对上面的感觉和malloc free一样,但是内存的数量是固定的,比如1024的buffer一般来说只有2个或者4个 低端版本甚至只有一个

 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/manlt/archive/2010/09/30/5916738.aspx

============================================================================

MTK 内存管理简单总结
http://blog.csdn.net/yanwuxufeng/archive/2010/07/12/5730092.aspx
MTK 内存管理简单总结 2
http://blog.csdn.net/yanwuxufeng/archive/2010/07/13/5733138.aspx
MTK 内存管理简单总结 3
http://blog.csdn.net/yanwuxufeng/archive/2010/07/14/5735911.aspx
MTK 内存管理简单总结 4
http://blog.csdn.net/yanwuxufeng/archive/2010/07/16/5740999.aspx
MTK 内存管理简单总结 5
http://blog.csdn.net/yanwuxufeng/archive/2010/07/17/5743273.aspx


    
最新技术文章:
▪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