sys_arch.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. #include <rtthread.h>
  2. #include "lwip/debug.h"
  3. #include "lwip/sys.h"
  4. #include "lwip/opt.h"
  5. #include "lwip/stats.h"
  6. #include "lwip/err.h"
  7. #include "arch/sys_arch.h"
  8. #include <string.h>
  9. #define LWIP_THREAD_MAGIC 0x1919
  10. void sys_init(void)
  11. {
  12. /* nothing to do in RT-Thread */
  13. return;
  14. }
  15. /* ====================== Semaphore ====================== */
  16. err_t sys_sem_new(sys_sem_t *sem, u8_t count)
  17. {
  18. static unsigned short counter = 0;
  19. char tname[RT_NAME_MAX];
  20. sys_sem_t tmpsem;
  21. rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_SEM_NAME, counter);
  22. #if SYS_DEBUG
  23. {
  24. struct rt_thread *thread;
  25. thread = rt_thread_self();
  26. LWIP_DEBUGF(SYS_DEBUG, ("%s, Create sem: %s \n",thread->name, tname));
  27. }
  28. #endif
  29. counter++;
  30. tmpsem = rt_sem_create(tname, count, RT_IPC_FLAG_FIFO);
  31. if( tmpsem == RT_NULL )
  32. return ERR_MEM;
  33. else
  34. {
  35. *sem = tmpsem;
  36. return ERR_OK;
  37. }
  38. }
  39. void sys_sem_free(sys_sem_t *sem)
  40. {
  41. #if SYS_DEBUG
  42. {
  43. struct rt_thread *thread;
  44. thread = rt_thread_self();
  45. LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete sem: %s \n",thread->name,
  46. (*sem)->parent.parent.name));
  47. }
  48. #endif
  49. rt_sem_delete(*sem);
  50. }
  51. void sys_sem_signal(sys_sem_t *sem)
  52. {
  53. #if SYS_DEBUG
  54. {
  55. struct rt_thread *thread;
  56. thread = rt_thread_self();
  57. LWIP_DEBUGF(SYS_DEBUG, ("%s, Release signal: %s , %d\n",thread->name,
  58. (*sem)->parent.parent.name, (*sem)->value));
  59. }
  60. #endif
  61. rt_sem_release(*sem);
  62. }
  63. u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
  64. {
  65. rt_err_t ret;
  66. s32_t t;
  67. u32_t tick;
  68. /* get the begin tick */
  69. tick = rt_tick_get();
  70. #if SYS_DEBUG
  71. {
  72. struct rt_thread *thread;
  73. thread = rt_thread_self();
  74. LWIP_DEBUGF(SYS_DEBUG, ("%s, Wait sem: %s , %d\n",thread->name,
  75. (*sem)->parent.parent.name, (*sem)->value));
  76. }
  77. #endif
  78. if(timeout == 0)
  79. t = RT_WAITING_FOREVER;
  80. else
  81. {
  82. /* convirt msecond to os tick */
  83. if (timeout < (1000/RT_TICK_PER_SECOND))
  84. t = 1;
  85. else
  86. t = timeout / (1000/RT_TICK_PER_SECOND);
  87. }
  88. ret = rt_sem_take(*sem, t);
  89. if (ret == -RT_ETIMEOUT)
  90. return SYS_ARCH_TIMEOUT;
  91. else
  92. {
  93. if (ret == RT_EOK)
  94. ret = 1;
  95. }
  96. /* get elapse msecond */
  97. tick = rt_tick_get() - tick;
  98. /* convert tick to msecond */
  99. tick = tick * (1000/RT_TICK_PER_SECOND);
  100. if (tick == 0)
  101. tick = 1;
  102. return tick;
  103. }
  104. #ifndef sys_sem_valid
  105. /** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */
  106. int sys_sem_valid(sys_sem_t *sem)
  107. {
  108. return (int)(*sem);
  109. }
  110. #endif
  111. #ifndef sys_sem_set_invalid
  112. /** Set a semaphore invalid so that sys_sem_valid returns 0 */
  113. void sys_sem_set_invalid(sys_sem_t *sem)
  114. {
  115. *sem = RT_NULL;
  116. }
  117. #endif
  118. /* ====================== Mutex ====================== */
  119. /** Create a new mutex
  120. * @param mutex pointer to the mutex to create
  121. * @return a new mutex */
  122. err_t sys_mutex_new(sys_mutex_t *mutex)
  123. {
  124. static unsigned short counter = 0;
  125. char tname[RT_NAME_MAX];
  126. sys_mutex_t tmpmutex;
  127. rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MUTEX_NAME, counter);
  128. #if SYS_DEBUG
  129. {
  130. struct rt_thread *thread;
  131. thread = rt_thread_self();
  132. LWIP_DEBUGF(SYS_DEBUG, ("%s, Create mutex: %s \n",thread->name, tname));
  133. }
  134. #endif
  135. counter++;
  136. tmpmutex = rt_mutex_create(tname, RT_IPC_FLAG_FIFO);
  137. if( tmpmutex == RT_NULL )
  138. return ERR_MEM;
  139. else
  140. {
  141. *mutex = tmpmutex;
  142. return ERR_OK;
  143. }
  144. }
  145. /** Lock a mutex
  146. * @param mutex the mutex to lock */
  147. void sys_mutex_lock(sys_mutex_t *mutex)
  148. {
  149. #if SYS_DEBUG
  150. {
  151. struct rt_thread *thread;
  152. thread = rt_thread_self();
  153. LWIP_DEBUGF(SYS_DEBUG, ("%s, Wait mutex: %s , %d\n",thread->name,
  154. (*mutex)->parent.parent.name, (*mutex)->value));
  155. }
  156. #endif
  157. rt_mutex_take(*mutex, RT_WAITING_FOREVER);
  158. return;
  159. }
  160. /** Unlock a mutex
  161. * @param mutex the mutex to unlock */
  162. void sys_mutex_unlock(sys_mutex_t *mutex)
  163. {
  164. #if SYS_DEBUG
  165. {
  166. struct rt_thread *thread;
  167. thread = rt_thread_self();
  168. LWIP_DEBUGF(SYS_DEBUG, ("%s, Release signal: %s , %d\n",thread->name,
  169. (*mutex)->parent.parent.name, (*mutex)->value));
  170. }
  171. #endif
  172. rt_mutex_release(*mutex);
  173. }
  174. /** Delete a semaphore
  175. * @param mutex the mutex to delete */
  176. void sys_mutex_free(sys_mutex_t *mutex)
  177. {
  178. #if SYS_DEBUG
  179. {
  180. struct rt_thread *thread;
  181. thread = rt_thread_self();
  182. LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete sem: %s \n",thread->name,
  183. (*mutex)->parent.parent.name));
  184. }
  185. #endif
  186. rt_mutex_delete(*mutex);
  187. }
  188. #ifndef sys_mutex_valid
  189. /** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */
  190. int sys_mutex_valid(sys_mutex_t *mutex)
  191. {
  192. return (int)(*mutex);
  193. }
  194. #endif
  195. #ifndef sys_mutex_set_invalid
  196. /** Set a mutex invalid so that sys_mutex_valid returns 0 */
  197. void sys_mutex_set_invalid(sys_mutex_t *mutex)
  198. {
  199. *mutex = RT_NULL;
  200. }
  201. #endif
  202. /* ====================== Mailbox ====================== */
  203. err_t sys_mbox_new(sys_mbox_t *mbox, int size)
  204. {
  205. static unsigned short counter = 0;
  206. char tname[RT_NAME_MAX];
  207. sys_mbox_t tmpmbox;
  208. rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MBOX_NAME, counter);
  209. #if SYS_DEBUG
  210. {
  211. struct rt_thread *thread;
  212. thread = rt_thread_self();
  213. LWIP_DEBUGF(SYS_DEBUG, ("%s, Create mbox: %s \n",thread->name, tname));
  214. }
  215. #endif
  216. counter++;
  217. tmpmbox = rt_mb_create(tname, size, RT_IPC_FLAG_FIFO);
  218. if( tmpmbox != RT_NULL )
  219. {
  220. *mbox = tmpmbox;
  221. return ERR_OK;
  222. }
  223. else
  224. return ERR_MEM;
  225. }
  226. void sys_mbox_free(sys_mbox_t *mbox)
  227. {
  228. #if SYS_DEBUG
  229. {
  230. struct rt_thread *thread;
  231. thread = rt_thread_self();
  232. LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete mbox: %s\n",thread->name,
  233. (*mbox)->parent.parent.name));
  234. }
  235. #endif
  236. rt_mb_delete(*mbox);
  237. return;
  238. }
  239. /** Post a message to an mbox - may not fail
  240. * -> blocks if full, only used from tasks not from ISR
  241. * @param mbox mbox to posts the message
  242. * @param msg message to post (ATTENTION: can be NULL) */
  243. void sys_mbox_post(sys_mbox_t *mbox, void *msg)
  244. {
  245. #if SYS_DEBUG
  246. {
  247. struct rt_thread *thread;
  248. thread = rt_thread_self();
  249. LWIP_DEBUGF(SYS_DEBUG, ("%s, Post mail: %s ,0x%x\n",thread->name,
  250. (*mbo)x->parent.parent.name, (rt_uint32_t)msg));
  251. }
  252. #endif
  253. if (rt_mb_send(*mbox, (rt_uint32_t)msg) != RT_EOK)
  254. rt_kprintf("TODO: FIX THIS!! mbox overflow");
  255. return;
  256. }
  257. err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
  258. {
  259. #if SYS_DEBUG
  260. {
  261. struct rt_thread *thread;
  262. thread = rt_thread_self();
  263. LWIP_DEBUGF(SYS_DEBUG, ("%s, Post mail: %s ,0x%x\n",thread->name,
  264. (*mbox)->parent.parent.name, (rt_uint32_t)msg));
  265. }
  266. #endif
  267. if (rt_mb_send(*mbox, (rt_uint32_t)msg) == RT_EOK)
  268. return ERR_OK;
  269. return ERR_MEM;
  270. }
  271. /** Wait for a new message to arrive in the mbox
  272. * @param mbox mbox to get a message from
  273. * @param msg pointer where the message is stored
  274. * @param timeout maximum time (in milliseconds) to wait for a message
  275. * @return time (in milliseconds) waited for a message, may be 0 if not waited
  276. or SYS_ARCH_TIMEOUT on timeout
  277. * The returned time has to be accurate to prevent timer jitter! */
  278. u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
  279. {
  280. rt_err_t ret;
  281. s32_t t;
  282. u32_t tick;
  283. /* get the begin tick */
  284. tick = rt_tick_get();
  285. if(timeout == 0)
  286. t = RT_WAITING_FOREVER;
  287. else
  288. {
  289. /* convirt msecond to os tick */
  290. if (timeout < (1000/RT_TICK_PER_SECOND))
  291. t = 1;
  292. else
  293. t = timeout / (1000/RT_TICK_PER_SECOND);
  294. }
  295. ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, t);
  296. if(ret == -RT_ETIMEOUT)
  297. return SYS_ARCH_TIMEOUT;
  298. else
  299. {
  300. if (ret == RT_EOK)
  301. ret = 1;
  302. }
  303. #if SYS_DEBUG
  304. {
  305. struct rt_thread *thread;
  306. thread = rt_thread_self();
  307. LWIP_DEBUGF(SYS_DEBUG, ("%s, Fetch mail: %s , 0x%x\n",thread->name,
  308. mbox->parent.parent.name, *(rt_uint32_t **)msg));
  309. }
  310. #endif
  311. /* get elapse msecond */
  312. tick = rt_tick_get() - tick;
  313. /* convert tick to msecond */
  314. tick = tick * (1000/RT_TICK_PER_SECOND);
  315. if (tick == 0)
  316. tick = 1;
  317. return tick;
  318. }
  319. /** Wait for a new message to arrive in the mbox
  320. * @param mbox mbox to get a message from
  321. * @param msg pointer where the message is stored
  322. * @param timeout maximum time (in milliseconds) to wait for a message
  323. * @return 0 (milliseconds) if a message has been received
  324. * or SYS_MBOX_EMPTY if the mailbox is empty */
  325. u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
  326. {
  327. int ret;
  328. ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, 0);
  329. if(ret == -RT_ETIMEOUT)
  330. return SYS_ARCH_TIMEOUT;
  331. else
  332. {
  333. if (ret == RT_EOK)
  334. ret = 1;
  335. }
  336. #if SYS_DEBUG
  337. {
  338. struct rt_thread *thread;
  339. thread = rt_thread_self();
  340. LWIP_DEBUGF(SYS_DEBUG, ("%s, Fetch mail: %s , 0x%x\n",thread->name,
  341. (*mbox)->parent.parent.name, *(rt_uint32_t **)msg));
  342. }
  343. #endif
  344. return ret;
  345. }
  346. #ifndef sys_mbox_valid
  347. /** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */
  348. int sys_mbox_valid(sys_mbox_t *mbox)
  349. {
  350. return (int)(*mbox);
  351. }
  352. #endif
  353. #ifndef sys_mbox_set_invalid
  354. /** Set an mbox invalid so that sys_mbox_valid returns 0 */
  355. void sys_mbox_set_invalid(sys_mbox_t *mbox)
  356. {
  357. *mbox = RT_NULL;
  358. }
  359. #endif
  360. /* ====================== System ====================== */
  361. sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
  362. {
  363. rt_thread_t t;
  364. /* create thread */
  365. t = rt_thread_create(name, thread, arg, stacksize, prio, 20);
  366. RT_ASSERT(t != RT_NULL);
  367. /* startup thread */
  368. rt_thread_startup(t);
  369. return t;
  370. }
  371. sys_prot_t sys_arch_protect(void)
  372. {
  373. /* disable interrupt */
  374. return rt_hw_interrupt_disable();
  375. }
  376. void sys_arch_unprotect(sys_prot_t pval)
  377. {
  378. /* enable interrupt */
  379. rt_hw_interrupt_enable(pval);
  380. return;
  381. }
  382. void sys_arch_assert(const char* file, int line)
  383. {
  384. rt_kprintf("\nAssertion: %d in %s, thread %s\n", line, file,
  385. rt_thread_self()->name);
  386. RT_ASSERT(0);
  387. }