POK(kernelpart)
|
00001 /* 00002 * POK header 00003 * 00004 * The following file is a part of the POK project. Any modification should 00005 * made according to the POK licence. You CANNOT use this file or a part of 00006 * this file is this part of a file for your own project 00007 * 00008 * For more information on the POK licence, please see our LICENCE FILE 00009 * 00010 * Please follow the coding guidelines described in doc/CODING_GUIDELINES 00011 * 00012 * Copyright (c) 2007-2009 POK team 00013 * 00014 * Created by julien on Thu Jan 15 23:34:13 2009 00015 */ 00016 00024 #if defined (POK_NEEDS_PORTS_SAMPLING) || defined (POK_NEEDS_PORTS_QUEUEING) 00025 #include <types.h> 00026 #include <libc.h> 00027 #include <core/time.h> 00028 #include <middleware/port.h> 00029 #include <middleware/queue.h> 00030 00031 extern pok_port_t pok_ports[POK_CONFIG_NB_PORTS]; 00032 extern pok_queue_t pok_queue; 00033 extern uint8_t pok_current_partition; 00034 00035 pok_port_size_t pok_port_available_size (uint8_t pid) 00036 { 00037 if (pok_ports[pid].full == TRUE) 00038 { 00039 return 0; 00040 } 00041 00042 if (pok_ports[pid].off_b < pok_ports[pid].off_e) 00043 { 00044 return (pok_ports[pid].off_b - pok_ports[pid].off_e); 00045 } 00046 else 00047 { 00048 return (pok_ports[pid].size - pok_ports[pid].off_e + pok_ports[pid].off_b); 00049 } 00050 } 00051 00052 pok_port_size_t pok_port_consumed_size (uint8_t pid) 00053 { 00054 if (pok_ports[pid].empty == TRUE) 00055 { 00056 return 0; 00057 } 00058 00059 if (pok_ports[pid].off_b < pok_ports[pid].off_e ) 00060 { 00061 return (pok_ports[pid].off_e - pok_ports[pid].off_b); 00062 } 00063 else 00064 { 00065 return (pok_ports[pid].size - pok_ports[pid].off_b + pok_ports[pid].off_e); 00066 } 00067 } 00068 00069 00070 pok_ret_t pok_port_get (const uint32_t pid, void *data, const pok_port_size_t size) 00071 { 00072 00073 #ifdef POK_NEEDS_PORTS_QUEUEING 00074 pok_port_size_t tmp_size; 00075 pok_port_size_t tmp_size2; 00076 #endif 00077 00078 switch (pok_ports[pid].kind) 00079 { 00080 00081 #ifdef POK_NEEDS_PORTS_QUEUEING 00082 case POK_PORT_KIND_QUEUEING: 00083 if (pok_ports[pid].empty == TRUE) 00084 { 00085 return POK_ERRNO_EINVAL; 00086 } 00087 00088 if (pok_ports[pid].size < size) 00089 { 00090 return POK_ERRNO_SIZE; 00091 } 00092 00093 if ((pok_ports[pid].off_b + size) > pok_ports[pid].size) 00094 { 00095 tmp_size = pok_ports[pid].size - pok_ports[pid].off_b; 00096 memcpy (data, &pok_queue.data[pok_ports[pid].index + pok_ports[pid].off_b], tmp_size); 00097 tmp_size2 = size - tmp_size; 00098 memcpy (data + tmp_size, &pok_queue.data[pok_ports[pid].index], tmp_size2); 00099 } 00100 else 00101 { 00102 memcpy (data, &pok_queue.data[pok_ports[pid].index + pok_ports[pid].off_b], size); 00103 } 00104 00105 pok_ports[pid].off_b = (pok_ports[pid].off_b + size) % pok_ports[pid].size; 00106 00107 if (pok_ports[pid].off_b == pok_ports[pid].off_e) 00108 { 00109 pok_ports[pid].empty = TRUE; 00110 pok_ports[pid].full = FALSE; 00111 } 00112 00113 return POK_ERRNO_OK; 00114 break; 00115 #endif 00116 00117 #ifdef POK_NEEDS_PORTS_SAMPLING 00118 case POK_PORT_KIND_SAMPLING: 00119 if (pok_ports[pid].empty == TRUE) 00120 { 00121 return POK_ERRNO_EMPTY; 00122 } 00123 00124 if (size > pok_ports[pid].size) 00125 { 00126 return POK_ERRNO_SIZE; 00127 } 00128 00129 memcpy (data, &pok_queue.data[pok_ports[pid].index + pok_ports[pid].off_b], size); 00130 00131 return POK_ERRNO_OK; 00132 break; 00133 #endif 00134 00135 default: 00136 return POK_ERRNO_EINVAL; 00137 } 00138 } 00139 00140 pok_ret_t pok_port_write (const uint8_t pid, const void *data, const pok_port_size_t size) 00141 { 00142 #ifdef POK_NEEDS_PORTS_QUEUEING 00143 pok_port_size_t tmp_size; 00144 pok_port_size_t tmp_size2; 00145 #endif 00146 00147 switch (pok_ports[pid].kind) 00148 { 00149 #ifdef POK_NEEDS_PORTS_QUEUEING 00150 case POK_PORT_KIND_QUEUEING: 00151 if (pok_ports[pid].full == TRUE) 00152 { 00153 return POK_ERRNO_SIZE; 00154 } 00155 00156 if (size > pok_ports[pid].size) 00157 { 00158 return POK_ERRNO_SIZE; 00159 } 00160 00161 if ((pok_ports[pid].off_e + size) > pok_ports[pid].size) 00162 { 00163 tmp_size = pok_ports[pid].size - pok_ports[pid].off_e; 00164 memcpy (&pok_queue.data[pok_ports[pid].index + pok_ports[pid].off_e], data, tmp_size); 00165 00166 tmp_size2 = size - tmp_size; 00167 memcpy (&pok_queue.data[pok_ports[pid].index], data + tmp_size, tmp_size2); 00168 } 00169 else 00170 { 00171 memcpy (&pok_queue.data[pok_ports[pid].index + pok_ports[pid].off_e], data, size); 00172 } 00173 00174 pok_ports[pid].off_e = (pok_ports[pid].off_e + size) % pok_ports[pid].size; 00175 00176 if (pok_ports[pid].off_e == pok_ports[pid].off_b) 00177 { 00178 pok_ports[pid].full = TRUE; 00179 } 00180 00181 pok_ports[pid].empty = FALSE; 00182 00183 return POK_ERRNO_OK; 00184 00185 break; 00186 #endif 00187 00188 #ifdef POK_NEEDS_PORTS_SAMPLING 00189 case POK_PORT_KIND_SAMPLING: 00190 00191 if (size > pok_ports[pid].size) 00192 { 00193 return POK_ERRNO_SIZE; 00194 } 00195 00196 memcpy (&pok_queue.data[pok_ports[pid].index + pok_ports[pid].off_e], data, size); 00197 00198 pok_ports[pid].empty = FALSE; 00199 pok_ports[pid].last_receive = POK_GETTICK (); 00200 00201 return POK_ERRNO_OK; 00202 00203 break; 00204 #endif 00205 00206 default: 00207 return POK_ERRNO_EINVAL; 00208 } 00209 } 00210 00211 00212 /* 00213 * This function is designed to transfer data from one port to another 00214 * It is called when we transfer all data from one partition to the 00215 * others. 00216 */ 00217 pok_ret_t pok_port_transfer (const uint8_t pid_dst, const uint8_t pid_src) 00218 { 00219 pok_port_size_t len = 0; 00220 pok_port_size_t src_len_consumed = 0; 00221 00222 if (pok_ports[pid_src].empty == TRUE) 00223 { 00224 return POK_ERRNO_EMPTY; 00225 } 00226 00227 if (pok_ports[pid_src].kind == POK_PORT_KIND_QUEUEING) 00228 { 00229 len = pok_port_available_size (pid_dst); 00230 } 00231 else 00232 { 00233 if (pok_ports[pid_src].size != pok_ports[pid_dst].size) 00234 { 00235 return POK_ERRNO_SIZE; 00236 } 00237 00238 len = pok_ports[pid_src].size; 00239 } 00240 00241 if (pok_ports[pid_src].kind == POK_PORT_KIND_QUEUEING) 00242 { 00243 src_len_consumed = pok_port_consumed_size (pid_src); 00244 00245 if (src_len_consumed == 0) 00246 { 00247 return POK_ERRNO_SIZE; 00248 } 00249 00250 if (len > src_len_consumed) 00251 { 00252 len = src_len_consumed; 00253 } 00254 /* 00255 * Here, we check the size of data produced in the source port. 00256 * If there is more free space in the destination port, the size 00257 * of copied data will be the occupied size in the source port. 00258 */ 00259 } 00260 00261 if (len == 0) 00262 { 00263 return POK_ERRNO_SIZE; 00264 } 00265 /* 00266 * Len is the size to copy. If size is null, it's better to return 00267 * directly 00268 */ 00269 00270 memcpy (&pok_queue.data[pok_ports[pid_dst].index + pok_ports[pid_dst].off_e], &pok_queue.data[pok_ports[pid_src].index + pok_ports[pid_src].off_b], len); 00271 00272 if (pok_ports[pid_src].kind == POK_PORT_KIND_QUEUEING) 00273 { 00274 pok_ports[pid_dst].off_e = (pok_ports[pid_dst].off_e + len) % pok_ports[pid_dst].size; 00275 pok_ports[pid_src].off_b = (pok_ports[pid_src].off_b + len) % pok_ports[pid_src].size; 00276 00277 if (pok_ports[pid_src].off_b == pok_ports[pid_src].off_e) 00278 { 00279 pok_ports[pid_src].empty = TRUE; 00280 pok_ports[pid_src].full = FALSE; 00281 } 00282 } 00283 else 00284 { 00285 pok_ports[pid_src].empty = TRUE; 00286 } 00287 00288 pok_ports[pid_src].full = FALSE; 00289 pok_ports[pid_dst].empty = FALSE; 00290 00291 return POK_ERRNO_OK; 00292 } 00293 00294 bool_t pok_own_port (const uint8_t partition, const uint8_t port) 00295 { 00296 if (port > POK_CONFIG_NB_PORTS) 00297 { 00298 return FALSE; 00299 } 00300 00301 #ifdef POK_CONFIG_PARTITIONS_PORTS 00302 if ((((uint8_t[]) POK_CONFIG_PARTITIONS_PORTS)[port]) == partition) 00303 { 00304 return TRUE; 00305 } 00306 #endif 00307 00308 return FALSE; 00309 } 00310 00311 #endif