ucos学习笔记02--内存复制的操作
2008-10-10 01:21
495 查看
//ucos笔记--关于数据复制
//任务之间的通信的两个结构体之间数据复制问题
//两个结构体的原型如下:
typedef struct {
INT16U OSCnt; /* Semaphore count */
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */
INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */
} OS_SEM_DATA;
typedef struct {
INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_???) */
INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */
INT16U OSEventCnt; /* Semaphore Count (not used if other EVENT type) */
void *OSEventPtr; /* Pointer to message or queue structure */
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */
} OS_EVENT;
/*
OS_EVENT是事件控制块原型,OS_SEM_DATA是信号量在OSSemQuery里面用到的,用来获取事件控制块中有用的信息。在OSSemQuery函数里面,用了一个循环(新版本的ucos把这个循环改为了一条条赋值语句,因为循环次数最大是8次,为了减少循环的额外开销......)。但是这里其实是可以用强制类型转换简单一个赋值语句就可以搞定的。
*/
typedef struct {
OS_SEM_DATA OSEVENTSemdata;
INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_???) */
void *OSEventPtr; /* Pointer to message or queue structure */
} OS_EVENT;
//结构体无法直接做赋值操作,可以使用一个内存copy函数,返回目的地址
//=========================================
//考虑到了内存重叠的问题,不过在正常使用的时候这样的问题应该不会存在
void *memcopy(void * pvfrom, void *pvto, size_t size)//源码见下面
//如果那个变量不是放在结构体头的话,就需要知道这个成员的偏移地址
//用宏算出结构体成员的偏移地址
#define member_offset(struct_t, member) (int)(&((struct_t *)(0)->member))
/*
做内存复制,实现对OS_SEM_DATA的获取,故ucos里的函数INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)可以这样实现:
*/
INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)
{
memcopy(pdata, pevent, sizeof(OS_EVENT));
}
/*
也许效率没直接读取、赋值来的快,但是程序会比较简洁。
并且内存复制这一部分可以用内嵌汇编实现,效率问题可根据MCU特性做取舍:单纯的读写内存,某些mcu比较高效。
*/
//==========================================
//附内存复制函数的测试程序代码
#include <stdio.h>
#include <stdlib.h>
#define member_offset(struct_t, member) (int)(&(((struct_t *)(0))->member))
typedef unsigned char byte;
typedef struct st1
{
byte a;
int b;
float c;
}st_1;
typedef struct st2
{
struct st1 st1_v;
int x;
}st_2;
//==================================
void *memcopy(void *pvfrom, void *pvto, int size);
int main(void)
{
struct st1 *p_st1 = (struct st1 *)malloc(sizeof(st_1));
struct st2 st2_v1={{11,12,1.2345},13};
struct st1 *pt = p_st1;
memcopy((void *)(&st2_v1), (void *)pt, sizeof(st_1));
printf("%d/n", p_st1->a);
printf("%d/n", p_st1->b);
printf("%f/n", p_st1->c);
}
void *memcopy(void * pvfrom, void *pvto, int size)
{
byte *ptfrom = (byte *)pvfrom;
byte *ptto = (byte *)pvto;
printf("size is %d/n",size);
#if 1
while(size-->0)
{
*(ptto++) = *(ptfrom++);
}
#else//#if 1
//====在网上看到的,说这里需要考虑内存重叠问题,不过看不出什么时候会这样,除非故意的,比如插入排序?
if((ptfrom<ptto) && ((ptfrom+size-1)>ptto))
{
for(int i=size-1; i>=0;i--)
{
*(ptto+i) = *(ptfrom+i);
}
}
else
{
for(int i=0; i<size;i++)
{
*(ptto+i) = *(ptfrom+i);
}
}
#endif//#if 1
return ptto;
}
//任务之间的通信的两个结构体之间数据复制问题
//两个结构体的原型如下:
typedef struct {
INT16U OSCnt; /* Semaphore count */
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */
INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */
} OS_SEM_DATA;
typedef struct {
INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_???) */
INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */
INT16U OSEventCnt; /* Semaphore Count (not used if other EVENT type) */
void *OSEventPtr; /* Pointer to message or queue structure */
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */
} OS_EVENT;
/*
OS_EVENT是事件控制块原型,OS_SEM_DATA是信号量在OSSemQuery里面用到的,用来获取事件控制块中有用的信息。在OSSemQuery函数里面,用了一个循环(新版本的ucos把这个循环改为了一条条赋值语句,因为循环次数最大是8次,为了减少循环的额外开销......)。但是这里其实是可以用强制类型转换简单一个赋值语句就可以搞定的。
*/
typedef struct {
OS_SEM_DATA OSEVENTSemdata;
INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_???) */
void *OSEventPtr; /* Pointer to message or queue structure */
} OS_EVENT;
//结构体无法直接做赋值操作,可以使用一个内存copy函数,返回目的地址
//=========================================
//考虑到了内存重叠的问题,不过在正常使用的时候这样的问题应该不会存在
void *memcopy(void * pvfrom, void *pvto, size_t size)//源码见下面
//如果那个变量不是放在结构体头的话,就需要知道这个成员的偏移地址
//用宏算出结构体成员的偏移地址
#define member_offset(struct_t, member) (int)(&((struct_t *)(0)->member))
/*
做内存复制,实现对OS_SEM_DATA的获取,故ucos里的函数INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)可以这样实现:
*/
INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)
{
memcopy(pdata, pevent, sizeof(OS_EVENT));
}
/*
也许效率没直接读取、赋值来的快,但是程序会比较简洁。
并且内存复制这一部分可以用内嵌汇编实现,效率问题可根据MCU特性做取舍:单纯的读写内存,某些mcu比较高效。
*/
//==========================================
//附内存复制函数的测试程序代码
#include <stdio.h>
#include <stdlib.h>
#define member_offset(struct_t, member) (int)(&(((struct_t *)(0))->member))
typedef unsigned char byte;
typedef struct st1
{
byte a;
int b;
float c;
}st_1;
typedef struct st2
{
struct st1 st1_v;
int x;
}st_2;
//==================================
void *memcopy(void *pvfrom, void *pvto, int size);
int main(void)
{
struct st1 *p_st1 = (struct st1 *)malloc(sizeof(st_1));
struct st2 st2_v1={{11,12,1.2345},13};
struct st1 *pt = p_st1;
memcopy((void *)(&st2_v1), (void *)pt, sizeof(st_1));
printf("%d/n", p_st1->a);
printf("%d/n", p_st1->b);
printf("%f/n", p_st1->c);
}
void *memcopy(void * pvfrom, void *pvto, int size)
{
byte *ptfrom = (byte *)pvfrom;
byte *ptto = (byte *)pvto;
printf("size is %d/n",size);
#if 1
while(size-->0)
{
*(ptto++) = *(ptfrom++);
}
#else//#if 1
//====在网上看到的,说这里需要考虑内存重叠问题,不过看不出什么时候会这样,除非故意的,比如插入排序?
if((ptfrom<ptto) && ((ptfrom+size-1)>ptto))
{
for(int i=size-1; i>=0;i--)
{
*(ptto+i) = *(ptfrom+i);
}
}
else
{
for(int i=0; i<size;i++)
{
*(ptto+i) = *(ptfrom+i);
}
}
#endif//#if 1
return ptto;
}
相关文章推荐
- WinApi学习笔记-内存的复制,填充,输出等操作
- Delphi的学习笔记八——内存操作函数
- Python学习笔记02-列表与操作列表
- linux内存操作--ioremap和mmap学习笔记
- Lucene学习笔记-内存与文件索引的简单操作
- mongodb 学习笔记 02 -- CURD操作
- Java学习笔记——File类文件管理及IO读写、复制操作
- Git学习笔记02_仓库操作
- learning jQuery 学习笔记十三(+jQuery 1.4.1 API)-- DOM操作-基于命令改变页面 ----复制元素及其它
- MySQL学习笔记--主从复制故障重置操作
- Hadoop学习笔记之(二):实验Hadoop的文件块复制删除操作感受强大的容灾性
- 韩顺平_PHP程序员玩转算法公开课(第一季)02_单链表在内存中存在形式剖析_学习笔记_源代码图解_PPT文档整理
- linux内存操作--ioremap和mmap学习笔记
- Delphi的学习笔记八——内存操作函数
- 【Linux】LDD学习笔记——操作硬件——IO内存
- 【EF学习笔记05】----------操作内存中的数据
- MongoDB学习笔记02:基本操作
- 【jQuery学习笔记---------DOM操作复制元素】
- Java IO学习笔记(五):内存操作流
- Java学习笔记——File类文件管理及IO读写、复制操作