嵌入式(标准C环境下)下通用的内存池的实现---C文件

  1. #include "avit_memory_pool.h"
  2. #include "avit_oc_print.h"
  3. static UINT32 peak_memory_use = 0;
  4. static UINT32 now_memory_use = 0;
  5. static BYTE* pool_adr = NULL;
  6. static MemNode* pool_link = NULL;
  7. static MemNode* memory_pool_first_fitting(UINT32 size);
  8. void memory_pool_dump()
  9. {
  10.     MemNode* temp_node = pool_link;
  11.     temp_node = pool_link;
  12.     while(TRUE)
  13.     {
  14.         if( temp_node == NULL ) break;
  15.         oc_println("[0x%08X][0x%08X][0x%08X][0x%08X][%d][%d]",
  16.             temp_node->last,
  17.             temp_node,
  18.             temp_node->next,
  19.             temp_node->addr,
  20.             temp_node->size,
  21.             temp_node->used
  22.             );
  23.         temp_node = temp_node->next ;       
  24.     }
  25. }
  26. UINT32 memory_pool_get_available_size()
  27. {
  28.     return (MEMORY_POOL_SIZE-now_memory_use);
  29. }
  30. UINT32 memory_pool_get_peak_use()
  31. {
  32.     return peak_memory_use;
  33. }
  34. UINT32 memory_pool_get_now_use()
  35. {
  36.     return now_memory_use;
  37. }
  38. INT32 memory_pool_init()
  39. {
  40.     if(!MEMORY_POOL_ENABLE) return J_SUCCESS;
  41.     memory_pool_release();
  42.     oc_println("memory pool initialized");
  43.     oc_println("memory pool size is %d",MEMORY_POOL_SIZE);
  44.     if(J_OSP_GetAvailableMemorySize() < MEMORY_POOL_SIZE )
  45.     {
  46.         oc_println("There is no enough memor for oc");
  47.         return J_FAILURE;
  48.     }
  49.     
  50.     // 分配池所要用到的内存
  51.     pool_adr = J_OSP_AllocateMemory(MEMORY_POOL_SIZE);
  52.     if(pool_adr == NULL) return J_FAILURE;
  53.     // 建立池的第一个结点
  54.     pool_link = (MemNode*)J_OSP_AllocateMemory(sizeof(MemNode));
  55.     pool_link->addr = pool_adr;
  56.     pool_link->used = FALSE;
  57.     pool_link->last = NULL;
  58.     pool_link->next = NULL;
  59.     pool_link->size = MEMORY_POOL_SIZE;
  60.     if(MEMORY_POOL_COUNTER_ENABLE)
  61.     {
  62.         peak_memory_use = 0;    
  63.         now_memory_use = 0;
  64.     }
  65.     return J_SUCCESS;
  66. }
  67. static MemNode* memory_pool_first_fitting(UINT32 size)
  68. {
  69.     MemNode* this_node = NULL;
  70.     MemNode* temp_node = pool_link; 
  71.     while(TRUE)
  72.     {
  73.         if(temp_node == NULL) break;
  74.         if( (temp_node->size >= size) && (temp_node->used == FALSE) )
  75.         {
  76.             this_node = temp_node;
  77.             break;
  78.         }
  79.         temp_node = temp_node->next;
  80.     }   
  81.     return this_node;
  82. }
  83. void* memory_pool_malloc(UINT32 size)
  84. {
  85.     // 目前采用首次拟合
  86.     MemNode* this_node = NULL;
  87.     UINT32 nee_size = size;
  88.     if(!MEMORY_POOL_ENABLE) return J_OSP_AllocateMemory(size);
  89.     if(size == 0)
  90.     {
  91.         oc_println("abnormal memeory malloc size is 0");
  92.         return NULL;
  93.     }
  94.     if( (nee_size % 4) != 0 )
  95.         nee_size += (4-(nee_size%4));
  96.     
  97.     this_node = memory_pool_first_fitting(nee_size);
  98.     if(this_node == NULL)
  99.     {
  100.         oc_println("malloc memeory faild,size is %d",size);
  101.         return NULL;
  102.     }
  103.     size = nee_size;
  104.     if(this_node->size == size)
  105.     {
  106.         this_node->used = TRUE;
  107.         if(MEMORY_POOL_COUNTER_ENABLE)
  108.         {
  109.             now_memory_use += size;
  110.             if(now_memory_use >= peak_memory_use) peak_memory_use = now_memory_use;
  111.         }
  112.         return (void*)this_node->addr;
  113.     }
  114.     // 操作链表关系
  115.     {       
  116.         MemNode* last_node = this_node->last;
  117.         MemNode* new_node = (MemNode *)J_OSP_AllocateMemory(sizeof(MemNode));
  118.         if( this_node == pool_link ) 
  119.             pool_link = new_node;
  120.         else
  121.             last_node->next = new_node;
  122.         // 处理 new node
  123.         new_node->addr = this_node->addr;
  124.         new_node->used = TRUE;
  125.         new_node->last = last_node;
  126.         new_node->next = this_node;
  127.         new_node->size = size;
  128.         // 处理 this node
  129.         this_node->addr += size;
  130.         this_node->last = new_node; 
  131.         this_node->size -= size;
  132.         if(MEMORY_POOL_COUNTER_ENABLE)
  133.         {
  134.             now_memory_use += size;
  135.             if(now_memory_use >= peak_memory_use) peak_memory_use = now_memory_use;
  136.         }
  137.         return (void*)new_node->addr;
  138.     }
  139. }
  140. void memory_pool_free(void* pAddr)
  141. {
  142.     // 找到 pAddr 所在的 memnode
  143.     MemNode* this_node = NULL;
  144.     MemNode* temp_node = pool_link;
  145.     if(!MEMORY_POOL_ENABLE)
  146.     {
  147.         J_OSP_FreeMemory(pAddr);
  148.         return;
  149.     }
  150.     while(TRUE)
  151.     {
  152.         if( temp_node == NULL ) break;
  153.         if( temp_node->addr == pAddr)
  154.         {
  155.             this_node = temp_node;
  156.             break;
  157.         }
  158.         temp_node = temp_node->next ;
  159.     }
  160.     if(this_node == NULL)
  161.     {
  162.         oc_println("abnormal memory free!!");
  163.         return;
  164.     }
  165.     this_node->used = FALSE;
  166.     if(MEMORY_POOL_COUNTER_ENABLE) now_memory_use -= this_node->size;                                   
  167.     // 处理链表关系
  168.     {
  169.         MemNode* last_node = this_node->last;       
  170.         MemNode* next_node = this_node->next;
  171.         
  172.         // 第一次合并,和前一个块(last_node)进行合并
  173.         if(last_node != NULL)
  174.         {
  175.             // 与 last_node 合并
  176.             if( last_node->used == FALSE)
  177.             {               
  178.                 last_node->size += this_node->size;
  179.                 last_node->next = next_node;
  180.                 if(next_node != NULL)
  181.                     next_node->last = last_node;
  182.                 // 释放 this_node
  183.                 J_OSP_FreeMemory(this_node);
  184.                 this_node = NULL;
  185.             }           
  186.         }       
  187.         // 第二次合并,需要判断前面合并过没
  188.         if(this_node == NULL)// 已经和前面合并过了
  189.         {
  190.             // 判断是否需要和下一个块合并
  191.             if(next_node != NULL)
  192.             {
  193.                 if(next_node->used == FALSE) // next node 是空闲的
  194.                 {
  195.                     // 处理 last node                 
  196.                     last_node->next = next_node->next;
  197.                     last_node->size += next_node->size;
  198.                     // 处理 next_node;
  199.                     if(next_node->next != NULL)                 
  200.                         next_node->next->last = last_node;                  
  201.                     // 清除next_node
  202.                     J_OSP_FreeMemory(next_node);
  203.                     next_node = NULL;
  204.                 }
  205.             }
  206.         }
  207.         else // 没合并过
  208.         {
  209.             // 判断是否需要和下一个块合并
  210.             if(next_node != NULL)
  211.             {
  212.                 if(next_node->used == FALSE) // next node 是空闲的
  213.                 {                   
  214.                     this_node->next = next_node->next;
  215.                     this_node->size += next_node->size;
  216.                     if(next_node->next != NULL)                 
  217.                         next_node->next->last = this_node;                  
  218.                     J_OSP_FreeMemory(next_node);
  219.                     next_node = NULL;                   
  220.                 }
  221.             }
  222.         }           
  223.     }
  224. }
  225. void memory_pool_release()
  226. {
  227.     if(!MEMORY_POOL_ENABLE) return;
  228.     memory_pool_clear();
  229.     // 清除第一个结点
  230.     if(pool_link != NULL)
  231.     {   
  232.         J_OSP_FreeMemory(pool_link);
  233.         pool_link = NULL;
  234.     }
  235.     if( pool_adr != NULL)
  236.     {
  237.         J_OSP_FreeMemory(pool_adr);
  238.         pool_adr = NULL;
  239.     }       
  240.     if(MEMORY_POOL_COUNTER_ENABLE)
  241.         oc_println("peak memory use %d",peak_memory_use);   
  242.     peak_memory_use = 0;    
  243.     now_memory_use = 0;
  244.     oc_println("memory pool released.");
  245. }
  246. void memory_pool_clear()
  247. {
  248.     // 释放池的管理内存,删到只剩下一个结点
  249.     UINT32 garbage_count = 0;
  250.     MemNode* temp = NULL;
  251.     if(pool_link == NULL) return;
  252.     if(pool_link->next == NULL) return;
  253.     while(TRUE)
  254.     {       
  255.         temp = pool_link;
  256.         pool_link = pool_link->next;        
  257.         J_OSP_FreeMemory(temp);
  258.         temp = NULL;
  259.         if(MEMORY_POOL_COUNTER_ENABLE) garbage_count++;                                 
  260.         if(pool_link->next == NULL) break;
  261.     }
  262.     pool_link->addr = pool_adr;
  263.     pool_link->used = FALSE;
  264.     pool_link->last = NULL;
  265.     pool_link->next = NULL;
  266.     pool_link->size = MEMORY_POOL_SIZE;
  267.     now_memory_use = 0;
  268.     if(MEMORY_POOL_COUNTER_ENABLE) oc_println("memory garbage count is %d",garbage_count);  
  269. }
 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式系统设计实战:基于飞思卡尔S12X微控制器》以飞思卡尔半导体公司(原摩托罗拉半导体部)16位S12X系列微控制器中MC9S12XS128为蓝本阐述嵌入式系统的软件与硬件设计。全书共11章,其中第1章阐述嵌入式系统的知识体系、学习误区与学习建议。第2章给出XS128硬件最小系统,并简要介绍S12XCPU(CPU12X)。第3章给出第一个样例程序及CodeWai·“or工程组织,完成第一个S12X工程的入门。第4章给出基于硬件构件的嵌入式系统开发方法。第5章阐述串行通信接口SCI,并给出第一个带中断的实例。1~5章介绍了学习一个新MCU完整要素(知识点)的入门。6~12章分别介绍GPIO的应用(键盘、LED及LCD)、定时器(含PWM)、串行外设接口SPI、Flash存储器在线编程、CAN总线、A/D转换及S12XS128其他模块等。附录给出相关资料。《嵌入式系统设计实战:基于飞思卡尔S12X微控制器》涉及的实例源程序、辅助资料、相关芯片资料及常用软件工具,可在北航出版社下载中心或苏州大学飞思卡尔嵌入式系统研发中心网站下载。《嵌入式系统设计实战:基于飞思卡尔S12X微控制器》可供大学有关专业的高年级学生和研究生用作教材或参考读物,也可供嵌入式系统开发与研究人员用作参考和进修资料。 第1章 概述 1 1.1 嵌入式系统定义、由来及特点 1 1.1.1 嵌入式系统的定义 1 1.1.2 嵌入式系统的由来及其与微控制器的关系 2 1.1.3 嵌入式系统的特点 3 1.2 嵌入式系统的知识体系、学习误区及学习建议 4 1.2.1 嵌入式系统的知识体系 4 1.2.2 嵌入式系统的学习误区 5 1.2.3 基础阶段的学习建议 8 1.3 嵌入式系统常用术语 10 1.3.1 与硬件相关的术语 10 1.3.2 与通信相关的术语 11 1.3.3 与功能模块及软件相关的术语 12 1.4 嵌入式系统常用的C语言基本语法 13 第2章 S12X系列MCU硬件最小系统及CPU12X 26 2.1 S12X系列MCU概述及型号标识 26 2.1.1 S12X系列MCU概述 26 2.1.2 S12X系列MCU型号标识 28 2.2 S12X系列MCU的功能及存储器映像 29 2.2.1 S12X系列MCU的功能 30 2.2.2 S12X系列MCU的存储器映像及特点 31 2.3 XS128的引脚功能及硬件最小系统 36 2.3.1 XS128(80引脚QFP封装)的引脚功能 37 2.3.2 XS128的硬件最小系统 40 2.3.3 硬件最小系统的焊接与测试步骤 43 2.4 CPU12X的内部寄存器 44 2.5 CPU12X的寻址方式 47 2.6 CPU12X指令系统概要 51 2.6.1 数据传送类指令 53 2.6.2 算术运算类指令 56 2.6.3 逻辑运算类与位操作类指令 60 2.6.4 程序控制类指令 63 2.6.5 其他类指令 71 2.7 CPU12X汇编语言基础 72 2.7.1 S12X汇编源程序格式 72 2.7.2 S12X汇编语言伪指令 74 第3章 第一个样例程序及CodeWarrior工程组织 77 3.1 通用I/O接口基本概念及连接方法一 77 3.2 XS128的GPIO寄存器与GPIO构件封装 79 3.2.1 XS128的GPIO寄存器 79 3.2.2 GPIO的简单编程方法 83 3.3 CodeWarrior开发环境与S08/S12/ColdFire三合一写入器 84 3.3.1 CodeWarrior开发环境简介与基本使用方法 85 3.3.2 S08/S12/ColdFire三合一写入器 86 3.3.3 MC9S12XS128硬件评估板 87 3.4 CW环境C语言工程文件的组织 87 3.4.1 工程文件的逻辑组织结构 88 3.4.2 工程文件的物理组织结构 90 3.4.3 系统启动及初始化相关文件 91 3.4.4 芯片初始化、主程序、中断程序及其他文件 98 3.4.5 机器码文件(s19文件)的简明解释 101 3.4.6 lst文件与map文件 103 3.4.7 如何在CW环境下新建一个S12工程 105 3.5 第一个C语言工程:控制小灯闪烁 105 3.5.1 GPIO构件设计 106 3.5.2 Light构件设计 113 3.5.3 Light测试工程主程序 115 3.5.4 理解第一个C工程的执行过程 116 3.6 第一个汇编语言工程:控制小灯闪烁 117 3.6.1 汇编工程文件的组织 118 3.6.2 Light构件汇编程序 122 3.6.3 Light测试工程主程序 124 3.6.4 理解第一个汇编工程的执行过程 126 第4章 基于硬件构件的嵌入式系统开发方法 129 4.1 嵌入式系统开发所遇到的若干问题 129 4.2 嵌入式硬件构件的基本思想与应用方法 130 4.3 基于硬件构件的嵌入式系统硬件电路设计 131 4.3.1 设计时需要考虑的基本问题 131 4.3.2 硬件构件化电路原理图绘制的简明规则 133 4.3.3 实验PCB板设计的简明规则 135 4.4 基于硬件构件的嵌入式底层软件构件的编程方法 139 4.4.1 嵌入式硬件构件和软件构件的层次模型 139 4.4.2 底层构件的实现方法与编程思想 140 4.4.3 硬件构件及底层软件构件的重用与移植方法 141 第5章 串行通信接口SCI 144 5.1 异步串行通信的通用基础知识 144 5.1.1 串行通信的基本概念 145 5.1.2 RS-232总线标准 146 5.1.3 TTL电平到RS-232电平转换电路 148 5.1.4 串行通信编程模型 149 5.2 SCI模块的编程寄存器 150 5.3 SCI编程实例 155 5.3.1 SCI初始化与收发编程的基本方法 156 5.3.2 SCI构件设计与测试实例 157 5.4 XS128的中断源与第一个带有中断的编程实例 166 5.4.1 中断与异常的通用知识 166 5.4.2 XS128的中断机制 166 5.4.3 XS128的中断编程方法 171 5.4.4 XS128的中断优先级编程实例 173 第6章 GPIO的应用实例:键盘、LED与LCD 175 6.1 键盘技术概述 175 6.1.1 键盘模型及接口 175 6.1.2 键盘编程的基本问题 177 6.1.3 键盘构件设计与测试实例 178 6.2 LED技术概述 184 6.2.1 扫描法LED显示编程原理 184 6.2.2 LED构件设计与测试实例 186 6.3 LCD技术概述 191 6.3.1 LCD的特点和分类 191 6.3.2 点阵字符型液晶显示模块 193 6.3.3 HD44780 193 6.3.4 LCD构件设计与测试实例 199 第7章 定时器相关模块 207 7.1 计数/定时器的基本工作原理 207 7.2 定时器模块的基本编程方法与实例 208 7.2.1 定时器模块计时功能的基本寄存器 210 7.2.2 定时器构件设计与测试实例 212 7.3 定时器模块输入捕捉功能的编程方法与实例 216 7.3.1 输入捕捉的基本含义 216 7.3.2 输入捕捉的寄存器 217 7.3.3 输入捕捉构件设计与测试实例 218 7.4 定时器模块输出比较功能的编程方法与实例 221 7.4.1 输出比较的基本知识 222 7.4.2 用于输出比较功能的相关寄存器 222 7.4.3 输出比较构件设计与测试实例 224 7.5 定时器模块脉冲累加功能的编程方法与实例 226 7.5.1 脉冲累加的基本知识 226 7.5.2 脉冲累加功能的相关寄存器 227 7.5.3 脉冲累加器构件设计 228 7.6 脉宽调制模块 231 7.6.1 PWM工作原理 231 7.6.2 XS128的PWM的特点及模块框图 232 7.6.3 脉宽调制模块PWM相关寄存器 233 7.6.4 PWM构件设计及测试实例 236 7.7 周期中断定时器模块PIT 243 7.7.1 PIT模块功能描述 243 7.7.2 PIT模块的编程寄存器 245 7.7.3 PIT构件设计与测试实例 248 第8章 A/D与SPI 252 8.1 A/D通用知识 252 8.1.1 A/D的基本问题 252 8.1.2 A/D转换器 253 8.1.3 A/D转换常用传感器简介 254 8.1.4 电阻型传感器采样电路设计 255 8.2 A/D模块的编程寄存器 257 8.3 A/D模块编程方法与实例 264 8.3.1 A/D模块基本编程方法 264 8.3.2 A/D构件设计与测试实例 265 8.4 SPI的基本工作原理 270 8.4.1 SPI基本概念 270 8.4.2 SPI的数据传输 272 8.4.3 SPI模块的时序 272 8.4.4 模拟SPI 276 8.5 SPI模块的编程寄存器 276 8.6 SPI构件设计与测试实例 282 第9章 Flash存储器在线编程 289 9.1 S12X系列MCU的Flash存储器的特点及分页机制 289 9.1.1 S12X系列MCU的Flash存储器的特点 290 9.1.2 XS128的Flash存储器分页机制 290 9.2 Flash存储器编程方法 295 9.2.1 Flash存储器编程的基本概念 295 9.2.2 Flash存储器的编程寄存器 296 9.2.3 FCCOB-NVM命令模式 300 9.2.4 Flash存储器的编程步骤 301 9.3 D-Flash在线编程 303 9.4 P-Flash在线编程 308 9.5 Flash存储器的保护特性和安全性 313 9.5.1 Flash存储器的配置区域 313 9.5.2 Flash存储器的保护特性 314 9.5.3 Flash存储器的安全性 317 第10章 CAN总线 321 10.1 CAN总线通用知识 321 10.1.1 CAN总线协议的历史概况 321 10.1.2 CAN硬件系统的典型电路 321 10.1.3 CAN总线的有关基本概念 324 10.1.4 帧结构 327 10.1.5 位时间 331 10.2 MSCAN模块简介 332 10.2.1 MSCAN特性 333 10.2.2 报文存储结构、标识符验收过滤与时钟系统 334 10.2.3 CAN模块的主要运行模式、低功耗选项、中断与响应 341 10.3 MSCAN模块的内存映射及寄存器定义 345 10.3.1 MSCAN模块内存映射 345 10.3.2 MSCAN模块寄存器 346 10.4 MSCAN模块双机通信测试实例 360 10.4.1 测试模型 360 10.4.2 编程要点 360 10.4.3 CAN模块底层构件设计 361 10.4.4 测试操作要点 374 10.5 MSCAN模块的自环通信实例 374 10.5.1 测试模型 374 10.5.2 编程要点及设计代码 374 第11章 系统时钟与其他功能模块 378 11.1 时钟与复位产生模块概述 378 11.1.1 锁相环技术 378 11.1.2 CRG模块框图 380 11.1.3 CRG模块的工作模式 381 11.1.4 XS128内部锁相环结构 383 11.2 XS128的CRG模块的初始化 384 11.2.1 XS128的CRG模块寄存器 384 11.2.2 初始化编程方法与实例 389 11.3 CRG模块的其他功能 392 11.3.1 CRG产生复位信号 392 11.3.2 中断 397 11.4 XS128的IRQ、XIRQ引脚、RTIBRK及SWI中断 398 11.4.1 IRQ与XIRQ引脚中断 398 11.4.2 实时中断 398 11.4.3 调试模块DBG与软件中断SWI指令 399 附录A XS128的映像寄存器 400 附录B S08/S12/ColdFireBDM简明使用方法 410 附录C 常见实践问题集锦 414 附录D XS128的C语言函数库 417 附录E XS128的中断源与中断向量表 421 参考文献 424
基于单片机的MP3播放器设计[1] 音频信号数字化后所面临的一个不容忽视的问题是:巨大的数据量给存储和传输带来 的压力。因此音频压缩技术在广播专业领域、网络传输及多媒体使用中受到广泛关注, 成为音频信号处理的关键技术之一。MPEG(Moving Picture Experts Group)运动图像专家组,在1992年底制定了第一个世界范围的Hi-Fi(High- Fidelity)质量的音频编码标准MPEG-1。MPEG- 1分为三种不同的方式,称为Layer1、Layer2和Layer3。序号越高,复杂性越大,但是可 提供更好的编码效率,特别是在低比特率时。MP3就是MPEG-1 Layer3,是基于感知编码的算法,目前在CD音质的声音压缩方面,是一种通用的方法。 使用MP3标准对于音频数据编码既可以获得较大的音频数据压缩比,又可以得到较好的音 乐回放质量。MP3的解码器结构复杂,涉及到大量的数学计算,对处理器和内存的要求相 当高。目前,AT89C51处理器以其高性价比,丰富的外设资源,越来越受到各种嵌入式研 发人员的青睐[5- 7]。基于以上背景,我在此次设计中提出了AT89C51SND1C微处理器的软件解码方案,在 降低硬件成本的基础上保证高质量的播放效果。 1.2.2 课题研究的意义 MP3音频播放器的最合理工作速度为30Mips,而一个典型的视频媒体播放器的理想速 度则为175Mips,所以提高MP3的工作速度,以及改善MP3的音质是最关键的,也是亟待解 决的问题。 MP3是一种典型的嵌入式设备,而现在市场上比较常见的是闪存式MP3。由于闪存式M P3的容量限制,使它存储歌曲数目较少,在功能上也很难实现多样化。而硬盘式MP3的多 功能及大容量,也必将受到不少消费者的喜爱。 另外一个原因是近年来,嵌入式系统和单片机开发的有机结合,已广泛被使用于网络 通信、工业控制、机顶盒、PDA等诸多领域[8]。本文提出了一种基于单片机的MP3播放器 的设计方案,这就进一步的体现了该设计的灵活性。目前该设计方案已经实现,实践证 明,此播放器拥有市面MP3所有的全部功能并能够很好的运行。 MP3播放器一般分成3个部分:CPU、MP3硬件解码器存储器。其中可以将前两部分集成 在一起,即带MP3硬件解码器的CPU;或将后两部分集成在一起,即集成硬件解码、D/A 转换及音频输入。存储器可以是Flash存储器或硬盘。通过用MP3编码技术,可以得到大 约12:1压缩的有损音乐信号。尽管MP3音乐是有损的,它在压缩过程中对功率谱较弱的 信号有所丢失,但它同CD原声区别不大,不影响一般音乐爱好者对音乐的欣赏。MP3大大 缩小了声音文件的长度,使音乐的存储和传输更方便。 2 MP3的编解码过程 2.1 MP3的工作原理 一个完整MP3播放器要分几个部分:中央处理器、解码器、存储设备、主机通讯端口 、音频D/A和功放、显示界面和控制键、其中中央处理器和解码器是整个系统地核心。这 里的中央处理器我们通常成为MCU(单片微处理器),简称单片机。它运行MP3的整个控 制程序,也称为fireware(或者固件程序)。控制MP3的各个部件的工作:从存储设备读 取数据送到解码器解码;和主机连接时完成和主机的数据交换;接收控制按键的操作; 显示系统运行状态等任务。解码器是芯片中的一个硬件模块,或者说是硬件解码(有的 MP3播放机是软件解码,由高速中央处理器完成)。它可以直接完成各种格式MP3数据流 的解码操作,并输出PCM或I2S格式的数字音频信号[10]。 存储设备是MP3播放机的重要部分,通常的MP3随身听都是采用半导体存储器(FLASH MEMORY)或者硬盘(HDD)作为储存设备的[11]。它通过接收储存主机通讯端口传来的 数据(通常以文件形式),回放的时候MCU读取存储器中的数据并送到解码器。数据的存 储是要有一定格式的,众所周知,PC管理磁盘数据是以文件形式,MP3亦不例外,最常用 的办法就是直接利用PC的文件系统来管理存储器,微软操作系统采用的是FAT文件系统, 这也是最广泛使用的一种[12]。播放机其中一个任务就是要实现FAT文件系统,即可以从 FAT文件系统支持的磁盘中按文件名访问并读出其中的数据。 主机通讯端口是MP3播放机和PC机交换数据的途径,PC通过该端口操作MP3播放机存储 设备中的数据,拷贝、删除、复制文件等操作。目前最广泛使用的是USB总线,并且遵循 微软定义的大容量移动存储协议规范,将MP3播放机作为主机的一个移动存储设备。这里 需要遵循几个规范:USB通信协议、大容量移动存储器规范和SCSI协议[13-15]。 音频DAC是将数字音频信号转换成模拟音频信号,以推动耳机、功放等模拟音响设备 。这里要介绍一下数字音频信号。数字音频信号是
### 回答1: glib-2.26.1是一个开源的C语言库,提供了一系列的数据结构、算法、线程支持和基本功能。它是GNOME桌面环境的重要组成部分,被广泛用于开发Linux操作系统上的桌面应用程序。 glib-2.26.1的核心特点之一是提供了高效的数据结构。它包括链表、数组、哈希表等常用的数据结构,这些数据结构的实现都经过了优化,能够在各种复杂的场景中快速高效地进行数据操作。另外,glib-2.26.1还提供了一套功能强大的字符串处理函数,方便开发者对字符串进行操作,比如拷贝、连接、替换等。 此外,glib-2.26.1还提供了线程支持。它提供了一套封装了底层系统调用的线程库,方便开发者创建、管理和同步多线程应用程序。开发者可以使用glib-2.26.1的线程库实现并发执行的任务,提高应用程序的效率。 除了数据结构和线程支持,glib-2.26.1还提供了一些基本功能,如内存管理、错误处理、事件循环等。内存管理模块提供了内存分配和释放的函数,帮助开发者更安全地使用内存资源。错误处理模块提供了一组用于报告和处理错误的函数,方便开发者进行错误处理。事件循环模块则提供了一个用于处理各种事件的框架,开发者可以使用该框架实现事件驱动的应用程序。 总的来说,glib-2.26.1是一个功能丰富、高效、稳定的C语言库,被广泛应用于Linux操作系统上的桌面应用开发中。它提供了丰富的数据结构、线程支持和基本功能,为开发者提供了方便和快捷的开发工具,可以大大提高应用程序的开发效率和性能。 ### 回答2: glib-2.26.1是一个开源的通用性高的C语言库。它提供了许多数据结构、算法和函数,用于处理常见的编程任务。glib-2.26.1是GLib系列库的一个版本,由GNOME开发,并在许多GNU/Linux发行版中广泛使用。 glib-2.26.1包含了许多功能强大的模块。其中,最重要的是GObject,它是一个面向对象的框架。GObject提供了类、接口、属性、信号等概念,使得C语言可以以面向对象的方式进行编程。它还包含了一组方便的宏,用于定义和管理对象的生命周期。 另一个重要的模块是GLib的容器,如数组、链表、哈希表和二叉树等。这些容器提供了高效的数据结构,可用于存储和操作数据。此外,glib-2.26.1还提供了字符串处理、内存管理、文件操作、线程管理等功能。 glib-2.26.1还有许多其他特性,如国际化支持、消息传递机制、命令行解析等。它还提供了一些工具,如调试器、性能分析等。通过这些特性,开发人员可以更轻松地构建高效、可靠的应用程序。 总之,glib-2.26.1是一个非常实用的库,可以帮助开发人员加快开发速度,提高应用程序的质量。无论是开发桌面应用还是嵌入式系统,glib-2.26.1都是一个强大的选择。 ### 回答3: glib-2.26.1是一个常见的开源软件库,主要用于在C编程语言中提供一些通用的功能。它是GLib库的一个版本,由GNOME项目开发和维护。 GLib库旨在为开发者提供一些常用的数据结构和算法,以及一些系统和平台相关的功能。通过GLib,开发者可以更方便地编写可移植性强的程序。GLib库的主要特点如下: 1. 数据结构:GLib提供了一些常见的数据结构,如链表、队列、哈希表等,使得开发者能够更高效地处理数据。 2. 字符串处理:GLib提供了一些字符串处理的函数,如字符串拼接、查找、替换等,方便开发者对字符串进行操作和处理。 3. 文件操作:GLib包含了一些文件操作的函数,如读写文件、创建目录、遍历文件等,方便开发者对文件进行操作。 4. 内存管理:GLib提供了一些内存管理的函数,如动态内存分配、释放等,有效地管理和优化程序的内存使用。 5. 线程支持:GLib提供了一些线程相关的函数,如创建线程、线程同步等,方便开发者编写多线程的程序。 6. 输入输出支持:GLib提供了一些输入输出相关的函数,如读取和写入文件、网络通信等,使得程序能够更好地与外部环境交互。 总的来说,glib-2.26.1是一个功能丰富的开源软件库,为开发者提供了一些常用的功能和工具,方便开发者编写高效、可靠且可移植性强的程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值