OS_MEM.C

1 /*
2 *************************************************************************************************
3 *                                    uC/OS-II实时控制内核
4 *                                       主要的包含文件
5 *                --内存管理项代码--
6 *
7 * 文 件: OS_MEM.C  内存管理项代码
8 * 作 者: Jean J. Labrosse
9 * 中文注解: 钟常慰 zhongcw @ 126.com 整理:lin-credible 译注版本:1.0 请尊重原版内容
10 *************************************************************************************************
11 */
12
13 #ifndef  OS_MASTER_FILE                      //是否已定义OS_MASTER_FILE主文件
14 #include "includes.h"                        //包含"includes.h"文件,部分C语言头文件的汇总打包文件
15 #endif                                       //定义结束
16
17 #if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) //若两个条件满足时,产生以下代码
18                                              //OS_MEM_EN允许 (1) 或者禁止 (0) 产生内存相关代码
19                                              //OS_MAX_MEM_PART 最多内存块的数目
20 *************************************************************************************************
21 *                     建立并初始化一块内存区(CREATE A MEMORY PARTITION)
22 *
23 * 描述: 建立并初始化一块内存区。一块内存区包含指定数目的大小确定的内存块。程序可以包含这些内存
24 *       块并在用完后释放回内存区。
25 *
26 * 参数: addr     建立的内存区的起始地址。内存区可以使用静态数组或在初始化时使用malloc()函数建立。
27 *
28 *       nblks    需要的内存块的数目。每一个内存区最少需要定义两个内存块。
29 *
30 *       blksize  每个内存块的大小,最少应该能够容纳一个指针。
31 *
32 *       err      是指向包含错误码的变量的指针。OSMemCreate()函数返回的错误码可能为下述几种:
33 *                OS_NO_ERR            成功建立内存区;
34 *                OS_MEM_INVALID_ADDR  非法地址,即地址为空指针;
35 *                OS_MEM_INVALID_PART  没有空闲的内存区;
36 *                OS_MEM_INVALID_BLKS  没有为每一个内存区建立至少2个内存块;
37 *                OS_MEM_INVALID_SIZE  内存块大小不足以容纳一个指针变量。
38 * 返回: 返回指向内存区控制块的指针。如果没有剩余内存区,OSMemCreate()函数返回空指针。
39 *
40 * 注意: 必须首先建立内存区,然后使用
41 *************************************************************************************************
42 */
43 //建立并初始化一块内存区(起始地址、需要的内存块数目、每块内存块大小、返回错误的指针)
44 OS_MEM  *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
45 {
46 #if OS_CRITICAL_METHOD == 3                  //中断函数被设定为模式3
47     OS_CPU_SR  cpu_sr;
48 #endif
49     OS_MEM    *pmem;                         //内存控制块指针
50     INT8U     *pblk;                         //每块内存块的起始地址
51     void     **plink;                        //链接起始地址
52     INT32U     i;                            //内存包含的内存区数量
53
54
55 #if OS_ARG_CHK_EN > 0                        //所有参数在指定的范围之内
56     if (addr == (void *)0) {                 //当内存起始地址为0时
57         *err = OS_MEM_INVALID_ADDR;          //错误显示为(非法地址,即地址为空指针,无效)
58         return ((OS_MEM *)0);
59     }
60     if (nblks < 2) {                          //每个内存分区至少有两个内存块
61         *err = OS_MEM_INVALID_BLKS;           //否则显示(没有为每一个内存区建立至少2个内存块)
62         return ((OS_MEM *)0);
63     }
64     if (blksize < sizeof(void *)) {           //每个内存块至少容得一个指针(链接指针)
65         *err = OS_MEM_INVALID_SIZE;           //否则显示(内存块大小不足以容纳一个指针变量)
66         return ((OS_MEM *)0);
67     }
68 #endif
69     OS_ENTER_CRITICAL();                      //关闭中断
70     pmem = OSMemFreeList;                     //内存控制块指针=空余内存控制块(链接)
71     if (OSMemFreeList != (OS_MEM *)0) {       //当内存链接控制块≠0,即有空余控制块
72         OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;  //指向下一个空余链接控制块
73     }
74     OS_EXIT_CRITICAL();                       //打开中断
75     if (pmem == (OS_MEM *)0) {                //判断是否有空余内存控制块(为1有)
76         *err = OS_MEM_INVALID_PART;           //没有空闲的内存区
77         return ((OS_MEM *)0);                 //返回Null,建立内存失败
78     }
79     plink = (void **)addr;                    //链接起始地址=内存分区起始地址
80     pblk  = (INT8U *)addr + blksize;          //每块内存的起始地址=内存分区起始地址+每块内存块大小
81     for (i = 0; i < (nblks - 1); i++) {       //循环体(需要的内存块数目(次数))?
82         *plink = (void *)pblk;                //链接起始地址(内容)=每块内存块的起始地址(内容)?
83         plink  = (void **)pblk;               //链接起始地址=内存块的起始地址指针(内容)?
84         pblk   = pblk + blksize;              //内存块的起始地址=自己+每块内存块大小?
85     }
86     *plink = (void *)0;                       //链接起始地址=0
87     OS_ENTER_CRITICAL();                      //关闭中断
88     pmem->OSMemAddr     = addr;               //内存区指针=分区起始地址
89     pmem->OSMemFreeList = addr;               //下一空余控制块=分区起始地址
90     pmem->OSMemNFree    = nblks;              //分区中内存块大小=需要的内存块数目
91     pmem->OSMemNBlks    = nblks;              //总的内存块数量=需要的内存块数目
92     pmem->OSMemBlkSize  = blksize;            //空余内存块数量=每块内存块大小
93     OS_EXIT_CRITICAL();                       //打开中断
94     *err   = OS_NO_ERR;                       //成功建立内存区
95     return (pmem);                            //返回(内存控制块指针)
96 }
97 /*$PAGE*/
98 /*
99 *************************************************************************************************
100 *                           从内存区分配一个内存块(GET A MEMORY BLOCK)
101 *
102 * 描述: 用于从内存区分配一个内存块。用户程序必须知道所建立的内存块的大小,同时用户程序必须在使
103 *       用完内存块后释放内存块。使用OSMemGet()函数释放内存块。可以多次调用OSMemGet()函数。
104 *
105 * 参数: pmem    是指向内存区控制块的指针,可以从OSMemCreate()函数返回得到。
106 *
107 *       err     是指向包含错误码的变量的指针。OSMemGet()函数返回的错误码可能为下述几种:
108 *               OS_NO_ERR             成功得到一个内存块;
109 *               OS_MEM_NO_FREE_BLKS   内存区已经没有空间分配给内存块;
110 *               OS_MEM_INVALID_PMEM   'pmem'是空指针。
111 *
112 * 返回: 返回指向内存区块的指针。如果没有空间分配给内存块,OSMemGet()函数返回空指针。
113 *
114 * 注意: 必须首先建立内存区,然后使用
115 *************************************************************************************************
116 */
117
118 void  *OSMemGet (OS_MEM *pmem, INT8U *err)  //从内存区分配一个内存块(内存区控制块的指针、错误指针)
119 {
120 #if OS_CRITICAL_METHOD == 3                           //中断函数被设定为模式3
121     OS_CPU_SR  cpu_sr;
122 #endif
123     void      *pblk;                                  //内存块的起始地址
124
125 #if OS_ARG_CHK_EN > 0                                 //所有的参数都是在指定的范围内
126     if (pmem == (OS_MEM *)0) {                        //指向内存区控制块的指针不能为空指针
127         *err = OS_MEM_INVALID_PMEM;                   //'pmem'是空指针
128         return ((OS_MEM *)0);                         //返回Null
129     }
130 #endif
131     OS_ENTER_CRITICAL();                              //关闭中断
132     if (pmem->OSMemNFree > 0) {                       //检查内存分区中是否有空余的内存块(必须大于0)
133         pblk                = pmem->OSMemFreeList;    //刷新空余内存块链接表
134         pmem->OSMemFreeList = *(void **)pblk;         //将链接表头指针后移1个元素
135         pmem->OSMemNFree--;                           //将空余内存块数减1
136         OS_EXIT_CRITICAL();                           //打开中断
137         *err = OS_NO_ERR;                             //成功得到一个内存块
138         return (pblk);                                //返回(内存块的起始地址)
139     }
140     OS_EXIT_CRITICAL();                               //打开中断
141     *err = OS_MEM_NO_FREE_BLKS;                       //内存区已经没有空间分配给内存块
142     return ((void *)0);                               //返回(没有空间分配给内存块)
143 }
144 /*$PAGE*/
145 /*
146 *************************************************************************************************
147 *                               释放一个内存块 (RELEASE  A MEMORY BLOCK)
148 *
149 * 描述: 释放一个内存块,内存块必须释放回原先申请的内存区。
150 *
151 * 参数: pmem   是指向内存区控制块的指针,可以从OSMemCreate()函数 返回得到。
152 *
153 *       pblk   是指向将被释放的内存块的指针。
154 *
155 * 返回: OS_NO_ERR            成功释放内存块;
156 *       OS_MEM_FULL          内存区已经不能再接受更多释放的内存块。这种情况说明用户程序出现
157 *                            了错误,释放了多于用OSMemGet()函数得到的内存块
158 *       OS_MEM_INVALID_PMEM  'pmem'是空指针;
159 *       OS_MEM_INVALID_PBLK  //指向将被释放的内存块的指针不能为空指针
160 *
161 * 注意: 1)必须首先建立内存区,然后使用;
162 *       2)内存块必须释放回原先申请的内存区。
163 *************************************************************************************************
164 */
165
166 INT8U  OSMemPut (OS_MEM  *pmem, void *pblk)
167 {                                     //释放一个内存块(内存区控制块的指针、被释放的内存块的指针)
168 #if OS_CRITICAL_METHOD == 3                           //中断函数被设定为模式3
169     OS_CPU_SR  cpu_sr;
170 #endif
171
172
173 #if OS_ARG_CHK_EN > 0                                 //所有的参数都是在指定的范围内
174     if (pmem == (OS_MEM *)0) {                        //指向内存区控制块的指针不能为空指针
175         return (OS_MEM_INVALID_PMEM);                 //'pmem'是空指针
176     }
177     if (pblk == (void *)0) {                          //指向将被释放的内存块的指针不能为空指针
178         return (OS_MEM_INVALID_PBLK);                 //'pblk'是空指针
179     }
180 #endif
181     OS_ENTER_CRITICAL();                              //关闭中断
182     if (pmem->OSMemNFree >= pmem->OSMemNBlks) {       //分区中内存块大小 >= 总的内存块数量(已满)
183         OS_EXIT_CRITICAL();                           //打开中断
184         return (OS_MEM_FULL);                         //内存区已经不能再接受更多释放的内存块
185     }
186                                      //如果未满,将释放的内存块插入到该分区的空余内存块链接表中
187     *(void **)pblk      = pmem->OSMemFreeList;
188     pmem->OSMemFreeList = pblk;                       //将链接表头指针指向被释放的内存块的指针
189     pmem->OSMemNFree++;                               //将分区中空余的内存块总数加1
190     OS_EXIT_CRITICAL();
191     return (OS_NO_ERR);                               //成功释放内存块
192 }
193 /*$PAGE*/
194 /*
195 *************************************************************************************************
196 *                      得到内存区的信息(QUERY MEMORY PARTITION)
197 *
198 * 描述: 得到内存区的信息。该函数返回OS_MEM结构包含的信息,但使用了一个新的OS_MEM_DATA的数据结
199 *       构。OS_MEM_DATA数据结构还包含了正被使用的内存块数目的域。
200 *
201 * 参数: pmem   是指向内存区控制块的指针,可以从OSMemCreate()函数 返回得到。
202 *
203 *       pdata  是指向OS_MEM_DATA数据结构的指针,该数据结构包含了以下的域:
204 *       Void OSAddr;         //指向内存区起始地址的指针
205 *       Void OSFreeList;     //指向空闲内存块列表起始地址的指针
206 *       INT32U  OSBlkSize;      //每个内存块的大小
207 *       INT32U  OSNBlks;        //该内存区的内存块总数
208 *       INT32U  OSNFree;        //空闲的内存块数目
209 *       INT32U  OSNUsed;        //使用的内存块数目
210
211 *
212 * 返回: OS_NO_ERR              存储块有效,返回用户应用程序;
213 *       OS_MEM_INVALID_PMEM    'pmem'是空指针;
214 *       OS_MEM_INVALID_PDATA    pdata是空指针。
215 *
216 * 注意: 1)必须首先建立内存区,然后使用;
217 *************************************************************************************************
218 */
219
220 #if OS_MEM_QUERY_EN > 0                               //允许生成 OSMemQuery()函数
221 INT8U  OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *pdata)
222 {                                         //查询内存区的信息(内存区控制块的指针、保存数据的指针)
223 #if OS_CRITICAL_METHOD == 3                           //中断函数被设定为模式3
224     OS_CPU_SR  cpu_sr;
225 #endif
226
227 #if OS_ARG_CHK_EN > 0                                 //所有的参数都是在指定的范围内
228     if (pmem == (OS_MEM *)0) {                        //指向内存区控制块的指针不能为空指针
229         return (OS_MEM_INVALID_PMEM);                 //'pmem'是空指针
230     }
231     if (pdata == (OS_MEM_DATA *)0) {                  //指向数据存储的指针不能为空指针
232         return (OS_MEM_INVALID_PDATA);                //pdata是空指针
233     }
234 #endif
235     OS_ENTER_CRITICAL();                                   //关闭中断
236     pdata->OSAddr     = pmem->OSMemAddr;                   //保存内存区起始地址的指针
237     pdata->OSFreeList = pmem->OSMemFreeList;               //保存空闲内存块列表起始地址的指针
238     pdata->OSBlkSize  = pmem->OSMemBlkSize;                //保存内存块的大小
239     pdata->OSNBlks    = pmem->OSMemNBlks;                  //保存该内存区的内存块总数
240     pdata->OSNFree    = pmem->OSMemNFree;                  //保存空闲的内存块数目
241     OS_EXIT_CRITICAL();                                    //代开中断
242     pdata->OSNUsed    = pdata->OSNBlks - pdata->OSNFree;   //保存正在使用的内存块总数
243     return (OS_NO_ERR);                                    //返回(存储块有效,返回用户应用程序)
244 }
245 #endif                                                     // OS_MEM_QUERY_EN
246 /*$PAGE*/
247 /*
248 *************************************************************************************************
249 *                    初始化内存分区(INITIALIZE MEMORY PARTITION MANAGER)
250 *
251 * 描述: 这个函数是通过uC/OS-II初始化内存分区. 你的请求不能调用这个函数
252 *
253 * 参数: 无
254 *
255 * 返回: 无
256 *
257 * 注意: 这个函数是uC/OS-II函数,你不同调用它
258 *************************************************************************************************
259 */
260
261 void  OS_MemInit (void)                                    //初始化内存分区
262 {
263 #if OS_MAX_MEM_PART == 1                                   //最多内存块的数目为1时
264     OSMemFreeList                = (OS_MEM *)&OSMemTbl[0]; //内存块链接表=内存块首地址
265     OSMemFreeList->OSMemFreeList = (void *)0;              //内存块链接表=0
266     OSMemFreeList->OSMemAddr     = (void *)0;              //内存区起始地址的指针=0
267     OSMemFreeList->OSMemNFree    = 0;                      //空闲的内存块数目=0
268     OSMemFreeList->OSMemNBlks    = 0;                      //该内存区的内存块总数=0
269     OSMemFreeList->OSMemBlkSize  = 0;                      //内存块的大小=0
270 #endif
271
272 #if OS_MAX_MEM_PART >= 2                                   //最多内存块的数目为多个时
273     OS_MEM *pmem;                                         //定义内存区控制块的指针
274     INT16U   i;                                            //定义分区的内存数量
275
276
277     pmem = (OS_MEM *)&OSMemTbl[0];                    //内存区控制块的指针=内存控制块(MCB)首地址
278     for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) {     //设定循环初始化(i次)
279         pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; //内存块链接表=内存块地址(对应的分区)
280         pmem->OSMemAddr     = (void *)0;              //内存区起始地址的指针=0
281         pmem->OSMemNFree    = 0;                      //空闲的内存块数目=0
282         pmem->OSMemNBlks    = 0;                      //该内存区的内存块总数=0
283         pmem->OSMemBlkSize  = 0;                      //内存块的大小=0
284         pmem++;
285     }
286     pmem->OSMemFreeList = (void *)0;                  //初始化最后的内存块链接表
287     pmem->OSMemAddr     = (void *)0;                  //内存区起始地址的指针=0
288     pmem->OSMemNFree    = 0;                          //空闲的内存块数目=0
289     pmem->OSMemNBlks    = 0;                          //该内存区的内存块总数=0
290     pmem->OSMemBlkSize  = 0;                          //内存块的大小=0
291
292     OSMemFreeList       = (OS_MEM *)&OSMemTbl[0];     //回到开始的内存块链接表
293 #endif
294 }
295 #endif                                                //OS_MEM.C文件结束
296 ******************************************结束****************************************************
297
时间: 2024-09-20 00:07:01

OS_MEM.C的相关文章

探索ucos-ii之路(一)--内核目录结构和内核组成

UCOS-ii2.5.2内核目录结构和组成   1.uCOS-II Source->source:(与处理器类型无关的代码) [cpp] view plain copy print? *********************************************************************************   *   OS_CORE.C                       系统初始化,开启多任务环境等的代码          ***********

《Python自动化运维:技术与最佳实践》一2.3 发送电子邮件模块smtplib

2.3 发送电子邮件模块smtplib 电子邮件是最流行的互联网应用之一.在系统管理领域,我们常常使用邮件来发送告警信息.业务质量报表等,方便运维人员第一时间了解业务的服务状态.本节通过Python的smtplib模块来实现邮件的发送功能,模拟一个smtp客户端,通过与smtp服务器交互来实现邮件发送的功能,这可以理解成Foxmail的发邮件功能,在第一次使用之前我们需要配置smtp主机地址.邮箱账号及密码等信息,Python 2.3或更高版本默认自带smtplib模块,无需额外安装.下面详细进

uCOS_II.C

  Lin-credible!  Linux内核读不懂,先读读 uCOS的中文注释的源码!  1 /* 2 ************************************************************************************************* 3 * uC/OS-II实时控制内核 4 * 主要的包含文件 5 * 6 * 7 * 文 件: uCOS_II.C 包含主要uC/OS-II构造文件 8 * 作 者: Jean J. Labros

python使用电子邮件模块smtplib的方法_python

Smptp类定义:smtplib.SMTP(host[,port[,local_hostname[,,timeout]]]),作为SMTP的构造函数,功能是与smtp服务器建立连接,在连接成功后,就可以向服务器发送相关请求,比如登陆,校验,发送,退出等.host参数为远程smtp主机地址,比如stmp.163.com;port为连接端口,默认为25:local_hostname的作用是在本地的FQDN(完整的域名)发送HELO/EHLO指令,timeout为连接或尝试在多数秒超时,SMTP类具有