Blame view

app/app-prime-modbus/lib/common/tmmap.c 4.31 KB
8c2952457   김태훈   응용 프로그램 추가
1
2
3
  /**    
      @file     tmmap.c
      @date     2009/07/06
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
4
5
      @author   오재경 freefrug@falinux.com  FALinux.Co.,Ltd.
      @brief    mmap 를 다루는 함수를 객체화 하였다.
8c2952457   김태훈   응용 프로그램 추가
6
                
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
7
      @todo     테스트 함수를 아직 만들지 않았다.
8c2952457   김태훈   응용 프로그램 추가
8
9
10
11
12
      @bug     
      @remark  
      @warning 
  */
  //
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
13
14
  //  저작권    에프에이리눅스(주)
  //            외부공개 금지
8c2952457   김태훈   응용 프로그램 추가
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  //
  //----------------------------------------------------------------------------
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <string.h>
  #include <fcntl.h>
  #include <sys/ioctl.h>
  #include <sys/time.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/poll.h>
  #include <sys/mman.h> 
  
  
  #include <tlist.h>
  #include <tmmap.h>
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
33
  /// mmap 를 위한 개별 관리 구조체
8c2952457   김태훈   응용 프로그램 추가
34
35
  typedef struct {
  	
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
36
37
38
39
  	int            dev;         // /dev/mem 파일핸들
  	unsigned long  phys;        // 물리주소
  	unsigned long  size;        // 크기
  	int            base_ofs;    // 베이스 주소가 4K 정렬이 되지 않았을때 사용
8c2952457   김태훈   응용 프로그램 추가
40
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
41
  	void          *virt;        // 할당받은 메모리포인터
8c2952457   김태훈   응용 프로그램 추가
42
43
  	
  } mmap_alloc_t;
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
44
  static tlist *ma_list = NULL;   /// mmap 관리 리스트
8c2952457   김태훈   응용 프로그램 추가
45
46
47
  
  
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
48
  /** @brief   mmap 생성함수
8c2952457   김태훈   응용 프로그램 추가
49
50
51
52
53
54
55
56
57
58
      @param   base
      @param   size
  *///----------------------------------------------------------------------------
  void  *tmmap_alloc( unsigned long phys_base, unsigned long size )
  {       
  	int            dev_mem;
  	int            base_ofs;
  	void          *mmap_mem;
  	mmap_alloc_t  *ma;
  	
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
59
  	// 관리 리스트를 생성한다.
8c2952457   김태훈   응용 프로그램 추가
60
61
62
63
64
  	if ( NULL == ma_list )
  	{
  		ma_list = tlist_create();	
  	}
  	
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
65
  	// 4K 정렬 주소로 변경한다.
8c2952457   김태훈   응용 프로그램 추가
66
67
68
  	base_ofs   = phys_base & (PAGE_SIZE-1);
  	phys_base &= ~(PAGE_SIZE-1);
  	
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
69
  	// 4K 단위의 메모리를 할당받는다.
8c2952457   김태훈   응용 프로그램 추가
70
71
72
73
74
75
76
77
78
  	size = PAGE_SIZE * ( (size + base_ofs + (PAGE_SIZE-1))/(PAGE_SIZE) );
  	
  	dev_mem = open( "/dev/mem", O_RDWR|O_SYNC );
  	if (0 > dev_mem)
  	{
  		printf( "open error /dev/mem
  " );
  		return NULL;
  	}
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
79
80
81
82
83
84
  	// mmap 로 맵핑한다.
  	mmap_mem = mmap( 0,                                // 커널에서 알아서 할당요청
                       size,                             // 할당 크기
                       PROT_READ|PROT_WRITE, MAP_SHARED, // 할당 속성
                       dev_mem,                          // 파일 핸들
                       phys_base );                      // 매핑 대상의 물리주소	
8c2952457   김태훈   응용 프로그램 추가
85
86
87
88
89
90
91
92
  	
  	
  	if ( !mmap_mem )
  	{
  		printf( "mmap error !!!
  " );
  		return NULL;
  	}
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
93
  	// 개별 관리를 위한 구조체를 할당한다.
8c2952457   김태훈   응용 프로그램 추가
94
95
96
97
98
99
  	ma = (mmap_alloc_t  *)malloc( sizeof(mmap_alloc_t) );
  	ma->dev      = dev_mem;
  	ma->phys     = phys_base;
  	ma->size     = size;
  	ma->virt     = mmap_mem;
  	ma->base_ofs = base_ofs;
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
100
  	// 관리 리스트에 등록한다.
8c2952457   김태훈   응용 프로그램 추가
101
102
103
104
105
  	tlist_add( ma_list, (void *)ma );
  
  	return mmap_mem + base_ofs;
  }
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
106
107
108
  /** @brief   mmap로 획드한 메모리 포인터를 이용하여 관리 구조체를 얻는다.
      @param   virt   mmap 로 획드한 메모리 포인터
      @return  인덱스
8c2952457   김태훈   응용 프로그램 추가
109
110
111
112
113
114
115
116
117
118
119
120
121
  *///----------------------------------------------------------------------------
  static int tmmap_get_index( void *virt )
  {
  	mmap_alloc_t  *ma;
  	int  idx, count;
  	
  	if ( ma_list )
  	{
  		count = tlist_getcount( ma_list );
  		for (idx=0; idx<count; idx++ )
  		{
  			ma = (mmap_alloc_t *)tlist_get( ma_list, idx );
  			
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
122
  			// 가상메모리가 동일한 주소인지 확인한다.
8c2952457   김태훈   응용 프로그램 추가
123
124
125
126
127
128
129
130
131
132
  			if( (ma->virt + ma->base_ofs) == virt )
  			{
  				return idx;
  			}
  		}
  	}
  	
  	return -1;
  }
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
133
134
  /** @brief   mmap  포인터를 해제한다.
      @param   mem   mmap 로 획드한 메모리 포인터
8c2952457   김태훈   응용 프로그램 추가
135
136
137
138
139
140
141
142
  *///----------------------------------------------------------------------------
  void  tmmap_free( void *mem )
  {
  	int  idx;
  	mmap_alloc_t  *ma;
  		
  	if ( ma_list && mem )
  	{
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
143
  		// 해당하는 아이템을 찾아 메모리를 해제한다.
8c2952457   김태훈   응용 프로그램 추가
144
145
146
147
148
149
150
151
152
153
154
  		idx = tmmap_get_index( mem );
  		if ( 0 <= idx )
  		{
  			ma = (mmap_alloc_t *)tlist_get( ma_list, idx );
  			
  			munmap( ma->virt, ma->size );	
  			close ( ma->dev );
  			
  			free( (void *)ma );
  			tlist_delete( ma_list, idx );
  		} 
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
155
  		// 아이템이 없다면 관리자도 해제한다.
8c2952457   김태훈   응용 프로그램 추가
156
157
158
159
160
161
162
163
  		if ( 0 >= tlist_getcount( ma_list ) )
  		{
  			tlist_free( ma_list );
  			ma_list = NULL;
  		}
  
  	}
  }