您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

286 行
8.2 KiB

  1. /*
  2. * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. * 3. The name of the author may not be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  17. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  19. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  20. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  21. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  24. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  25. * OF SUCH DAMAGE.
  26. *
  27. * This file is part of the lwIP TCP/IP stack.
  28. *
  29. * Author: Adam Dunkels <adam@sics.se>
  30. *
  31. */
  32. /* Porting by Michael Vysotsky <michaelvy@hotmail.com> August 2011 */
  33. #define SYS_ARCH_GLOBALS
  34. /* lwIP includes. */
  35. #include "lwip/debug.h"
  36. #include "lwip/def.h"
  37. #include "lwip/lwip_sys.h"
  38. #include "lwip/mem.h"
  39. #include "includes.h"
  40. #include "delay.h"
  41. #include "arch/sys_arch.h"
  42. #include "malloc.h"
  43. //当消息指针为空时,指向一个常量pvNullPointer所指向的值.
  44. //在UCOS中如果OSQPost()中的msg==NULL会返回一条OS_ERR_POST_NULL
  45. //错误,而在lwip中会调用sys_mbox_post(mbox,NULL)发送一条空消息,我们
  46. //在本函数中把NULL变成一个常量指针0Xffffffff
  47. const void * const pvNullPointer = (mem_ptr_t*)0xffffffff;
  48. //创建一个消息邮箱
  49. //*mbox:消息邮箱
  50. //size:邮箱大小
  51. //返回值:ERR_OK,创建成功
  52. // 其他,创建失败
  53. err_t sys_mbox_new(sys_mbox_t *mbox, int size)
  54. {
  55. if(size>MAX_QUEUE_ENTRIES)size=MAX_QUEUE_ENTRIES; //消息队列最多容纳MAX_QUEUE_ENTRIES消息数目
  56. mbox->pQ=OSQCreate(&(mbox->pvQEntries[0]),size); //使用UCOS创建一个消息队列
  57. LWIP_ASSERT("OSQCreate",mbox->pQ!=NULL);
  58. if(mbox->pQ!=NULL)return ERR_OK; //返回ERR_OK,表示消息队列创建成功 ERR_OK=0
  59. else return ERR_MEM; //消息队列创建错误
  60. }
  61. //释放并删除一个消息邮箱
  62. //*mbox:要删除的消息邮箱
  63. void sys_mbox_free(sys_mbox_t *mbox)
  64. {
  65. u8_t ucErr;
  66. (void)OSQDel(mbox->pQ,OS_DEL_ALWAYS,&ucErr);
  67. LWIP_ASSERT( "OSQDel ",ucErr == OS_ERR_NONE );
  68. mbox=NULL;
  69. }
  70. //向消息邮箱中发送一条消息(必须发送成功)
  71. //*mbox:消息邮箱
  72. //*msg:要发送的消息
  73. void sys_mbox_post(sys_mbox_t *mbox,void *msg)
  74. {
  75. if(msg==NULL)msg=(void*)&pvNullPointer;//当msg为空时 msg等于pvNullPointer指向的值
  76. while(OSQPost(mbox->pQ,msg)!=OS_ERR_NONE);//死循环等待消息发送成功
  77. }
  78. //尝试向一个消息邮箱发送消息
  79. //此函数相对于sys_mbox_post函数只发送一次消息,
  80. //发送失败后不会尝试第二次发送
  81. //*mbox:消息邮箱
  82. //*msg:要发送的消息
  83. //返回值:ERR_OK,发送OK
  84. // ERR_MEM,发送失败
  85. err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
  86. {
  87. if(msg==NULL)msg=(void*)&pvNullPointer;//当msg为空时 msg等于pvNullPointer指向的值
  88. if((OSQPost(mbox->pQ, msg))!=OS_ERR_NONE)return ERR_MEM;
  89. return ERR_OK;
  90. }
  91. //等待邮箱中的消息
  92. //*mbox:消息邮箱
  93. //*msg:消息
  94. //timeout:超时时间,如果timeout为0的话,就一直等待
  95. //返回值:当timeout不为0时如果成功的话就返回等待的时间,
  96. // 失败的话就返回超时SYS_ARCH_TIMEOUT
  97. u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
  98. {
  99. u8_t ucErr;
  100. u32_t ucos_timeout,timeout_new;
  101. void *temp;
  102. if(timeout!=0)
  103. {
  104. ucos_timeout=(timeout*OS_TICKS_PER_SEC)/1000; //转换为节拍数,因为UCOS延时使用的是节拍数,而LWIP是用ms
  105. if(ucos_timeout<1)ucos_timeout=1;//至少1个节拍
  106. }else ucos_timeout = 0;
  107. timeout = OSTimeGet(); //获取系统时间
  108. temp=OSQPend(mbox->pQ,(u16_t)ucos_timeout,&ucErr); //请求消息队列,等待时限为ucos_timeout
  109. if(msg!=NULL)
  110. {
  111. if(temp==(void*)&pvNullPointer)*msg = NULL; //因为lwip发送空消息的时候我们使用了pvNullPointer指针,所以判断pvNullPointer指向的值
  112. else *msg=temp; //就可知道请求到的消息是否有效
  113. }
  114. if(ucErr==OS_ERR_TIMEOUT)timeout=SYS_ARCH_TIMEOUT; //请求超时
  115. else
  116. {
  117. LWIP_ASSERT("OSQPend ",ucErr==OS_ERR_NONE);
  118. timeout_new=OSTimeGet();
  119. if (timeout_new>timeout) timeout_new = timeout_new - timeout;//算出请求消息或使用的时间
  120. else timeout_new = 0xffffffff - timeout + timeout_new;
  121. timeout=timeout_new*1000/OS_TICKS_PER_SEC + 1;
  122. }
  123. return timeout;
  124. }
  125. //尝试获取消息
  126. //*mbox:消息邮箱
  127. //*msg:消息
  128. //返回值:等待消息所用的时间/SYS_ARCH_TIMEOUT
  129. u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
  130. {
  131. return sys_arch_mbox_fetch(mbox,msg,1);//尝试获取一个消息
  132. }
  133. //检查一个消息邮箱是否有效
  134. //*mbox:消息邮箱
  135. //返回值:1,有效.
  136. // 0,无效
  137. int sys_mbox_valid(sys_mbox_t *mbox)
  138. {
  139. sys_mbox_t *m_box=mbox;
  140. u8_t ucErr;
  141. int ret;
  142. OS_Q_DATA q_data;
  143. memset(&q_data,0,sizeof(OS_Q_DATA));
  144. ucErr=OSQQuery (m_box->pQ,&q_data);
  145. ret=(ucErr<2&&(q_data.OSNMsgs<q_data.OSQSize))?1:0;
  146. return ret;
  147. }
  148. //设置一个消息邮箱为无效
  149. //*mbox:消息邮箱
  150. void sys_mbox_set_invalid(sys_mbox_t *mbox)
  151. {
  152. mbox = NULL;
  153. }
  154. //创建一个信号量
  155. //*sem:创建的信号量
  156. //count:信号量值
  157. //返回值:ERR_OK,创建OK
  158. // ERR_MEM,创建失败
  159. err_t sys_sem_new(sys_sem_t * sem, u8_t count)
  160. {
  161. u8_t err;
  162. *sem=OSSemCreate((u16_t)count);
  163. if(*sem==NULL)return ERR_MEM;
  164. OSEventNameSet(*sem,"LWIP Sem",&err);
  165. LWIP_ASSERT("OSSemCreate ",*sem != NULL );
  166. return ERR_OK;
  167. }
  168. //等待一个信号量
  169. //*sem:要等待的信号量
  170. //timeout:超时时间
  171. //返回值:当timeout不为0时如果成功的话就返回等待的时间,
  172. // 失败的话就返回超时SYS_ARCH_TIMEOUT
  173. u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
  174. {
  175. u8_t ucErr;
  176. u32_t ucos_timeout, timeout_new;
  177. if( timeout!=0)
  178. {
  179. ucos_timeout = (timeout * OS_TICKS_PER_SEC) / 1000;//转换为节拍数,因为UCOS延时使用的是节拍数,而LWIP是用ms
  180. if(ucos_timeout < 1)
  181. ucos_timeout = 1;
  182. }else ucos_timeout = 0;
  183. timeout = OSTimeGet();
  184. OSSemPend (*sem,(u16_t)ucos_timeout, (u8_t *)&ucErr);
  185. if(ucErr == OS_ERR_TIMEOUT)timeout=SYS_ARCH_TIMEOUT;//请求超时
  186. else
  187. {
  188. timeout_new = OSTimeGet();
  189. if (timeout_new>=timeout) timeout_new = timeout_new - timeout;
  190. else timeout_new = 0xffffffff - timeout + timeout_new;
  191. timeout = (timeout_new*1000/OS_TICKS_PER_SEC + 1);//算出请求消息或使用的时间(ms)
  192. }
  193. return timeout;
  194. }
  195. //发送一个信号量
  196. //sem:信号量指针
  197. void sys_sem_signal(sys_sem_t *sem)
  198. {
  199. OSSemPost(*sem);
  200. }
  201. //释放并删除一个信号量
  202. //sem:信号量指针
  203. void sys_sem_free(sys_sem_t *sem)
  204. {
  205. u8_t ucErr;
  206. (void)OSSemDel(*sem,OS_DEL_ALWAYS,&ucErr );
  207. if(ucErr!=OS_ERR_NONE)LWIP_ASSERT("OSSemDel ",ucErr==OS_ERR_NONE);
  208. *sem = NULL;
  209. }
  210. //查询一个信号量的状态,无效或有效
  211. //sem:信号量指针
  212. //返回值:1,有效.
  213. // 0,无效
  214. int sys_sem_valid(sys_sem_t *sem)
  215. {
  216. OS_SEM_DATA sem_data;
  217. return (OSSemQuery (*sem,&sem_data) == OS_ERR_NONE )? 1:0;
  218. }
  219. //设置一个信号量无效
  220. //sem:信号量指针
  221. void sys_sem_set_invalid(sys_sem_t *sem)
  222. {
  223. *sem=NULL;
  224. }
  225. //arch初始化
  226. void sys_init(void)
  227. {
  228. //这里,我们在该函数,不做任何事情
  229. }
  230. extern OS_STK * TCPIP_THREAD_TASK_STK;//TCP IP内核任务堆栈,在lwip_comm函数定义
  231. //创建一个新进程
  232. //*name:进程名称
  233. //thred:进程任务函数
  234. //*arg:进程任务函数的参数
  235. //stacksize:进程任务的堆栈大小
  236. //prio:进程任务的优先级
  237. sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
  238. {
  239. OS_CPU_SR cpu_sr;
  240. if(strcmp(name,TCPIP_THREAD_NAME)==0)//创建TCP IP内核任务
  241. {
  242. OS_ENTER_CRITICAL(); //进入临界区
  243. OSTaskCreate(thread,arg,(OS_STK*)&TCPIP_THREAD_TASK_STK[stacksize-1],prio);//创建TCP IP内核任务
  244. OS_EXIT_CRITICAL(); //退出临界区
  245. }
  246. return 0;
  247. }
  248. //lwip延时函数
  249. //ms:要延时的ms数
  250. void sys_msleep(u32_t ms)
  251. {
  252. delay_ms(ms);
  253. }
  254. //获取系统时间,LWIP1.4.1增加的函数
  255. //返回值:当前系统时间(单位:毫秒)
  256. u32_t sys_now(void)
  257. {
  258. u32_t ucos_time, lwip_time;
  259. ucos_time=OSTimeGet(); //获取当前系统时间 得到的是UCOS的节拍数
  260. lwip_time=(ucos_time*1000/OS_TICKS_PER_SEC+1);//将节拍数转换为LWIP的时间MS
  261. return lwip_time; //返回lwip_time;
  262. }