Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of lwip-sys by
arch/sys_arch.c@18:8b8671ab556f, 2016-05-05 (annotated)
- Committer:
- mbed_official
- Date:
- Thu May 05 20:45:38 2016 +0100
- Revision:
- 18:8b8671ab556f
- Parent:
- 17:12e78a2462d0
Synchronized with git revision 860fdd282b0dc3631a6c46b39442d4ab5343e534
Full URL: https://github.com/mbedmicro/mbed/commit/860fdd282b0dc3631a6c46b39442d4ab5343e534/
rtx update to v4.79
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
emilmont | 6:2ace1ff71ae6 | 1 | /* Copyright (C) 2012 mbed.org, MIT License |
emilmont | 6:2ace1ff71ae6 | 2 | * |
emilmont | 6:2ace1ff71ae6 | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
emilmont | 6:2ace1ff71ae6 | 4 | * and associated documentation files (the "Software"), to deal in the Software without restriction, |
emilmont | 6:2ace1ff71ae6 | 5 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, |
emilmont | 6:2ace1ff71ae6 | 6 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
emilmont | 6:2ace1ff71ae6 | 7 | * furnished to do so, subject to the following conditions: |
emilmont | 6:2ace1ff71ae6 | 8 | * |
emilmont | 6:2ace1ff71ae6 | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
emilmont | 6:2ace1ff71ae6 | 10 | * substantial portions of the Software. |
emilmont | 6:2ace1ff71ae6 | 11 | * |
emilmont | 6:2ace1ff71ae6 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
emilmont | 6:2ace1ff71ae6 | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
emilmont | 6:2ace1ff71ae6 | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
emilmont | 6:2ace1ff71ae6 | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
emilmont | 6:2ace1ff71ae6 | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
emilmont | 6:2ace1ff71ae6 | 17 | */ |
emilmont | 6:2ace1ff71ae6 | 18 | #include <string.h> |
emilmont | 6:2ace1ff71ae6 | 19 | |
emilmont | 6:2ace1ff71ae6 | 20 | /* mbed includes */ |
mbed_official | 13:bca6d04bc6d3 | 21 | #include "mbed_error.h" |
emilmont | 6:2ace1ff71ae6 | 22 | #include "mbed_interface.h" |
emilmont | 6:2ace1ff71ae6 | 23 | #include "us_ticker_api.h" |
emilmont | 6:2ace1ff71ae6 | 24 | |
emilmont | 6:2ace1ff71ae6 | 25 | /* lwIP includes. */ |
emilmont | 6:2ace1ff71ae6 | 26 | #include "lwip/opt.h" |
emilmont | 6:2ace1ff71ae6 | 27 | #include "lwip/debug.h" |
emilmont | 6:2ace1ff71ae6 | 28 | #include "lwip/def.h" |
emilmont | 6:2ace1ff71ae6 | 29 | #include "lwip/sys.h" |
emilmont | 6:2ace1ff71ae6 | 30 | #include "lwip/mem.h" |
emilmont | 6:2ace1ff71ae6 | 31 | |
emilmont | 6:2ace1ff71ae6 | 32 | #if NO_SYS==1 |
emilmont | 6:2ace1ff71ae6 | 33 | #include "cmsis.h" |
emilmont | 6:2ace1ff71ae6 | 34 | |
emilmont | 6:2ace1ff71ae6 | 35 | /* Saved total time in ms since timer was enabled */ |
emilmont | 6:2ace1ff71ae6 | 36 | static volatile u32_t systick_timems; |
emilmont | 6:2ace1ff71ae6 | 37 | |
emilmont | 6:2ace1ff71ae6 | 38 | /* Enable systick rate and interrupt */ |
emilmont | 6:2ace1ff71ae6 | 39 | void SysTick_Init(void) { |
emilmont | 6:2ace1ff71ae6 | 40 | if (SysTick_Config(SystemCoreClock / 1000)) { |
emilmont | 6:2ace1ff71ae6 | 41 | while (1); /* Capture error */ |
emilmont | 6:2ace1ff71ae6 | 42 | } |
emilmont | 6:2ace1ff71ae6 | 43 | } |
emilmont | 6:2ace1ff71ae6 | 44 | |
emilmont | 6:2ace1ff71ae6 | 45 | /** \brief SysTick IRQ handler and timebase management |
emilmont | 6:2ace1ff71ae6 | 46 | * |
emilmont | 6:2ace1ff71ae6 | 47 | * This function keeps a timebase for the sysTick that can be |
emilmont | 6:2ace1ff71ae6 | 48 | * used for other functions. It also calls an external function |
emilmont | 6:2ace1ff71ae6 | 49 | * (SysTick_User) that must be defined outside this handler. |
emilmont | 6:2ace1ff71ae6 | 50 | */ |
emilmont | 6:2ace1ff71ae6 | 51 | void SysTick_Handler(void) { |
emilmont | 6:2ace1ff71ae6 | 52 | systick_timems++; |
emilmont | 6:2ace1ff71ae6 | 53 | } |
emilmont | 6:2ace1ff71ae6 | 54 | |
emilmont | 6:2ace1ff71ae6 | 55 | /* Delay for the specified number of milliSeconds */ |
emilmont | 6:2ace1ff71ae6 | 56 | void osDelay(uint32_t ms) { |
emilmont | 6:2ace1ff71ae6 | 57 | uint32_t to = ms + systick_timems; |
emilmont | 6:2ace1ff71ae6 | 58 | while (to > systick_timems); |
emilmont | 6:2ace1ff71ae6 | 59 | } |
emilmont | 6:2ace1ff71ae6 | 60 | |
emilmont | 6:2ace1ff71ae6 | 61 | /* Returns the current time in mS. This is needed for the LWIP timers */ |
emilmont | 6:2ace1ff71ae6 | 62 | u32_t sys_now(void) { |
emilmont | 6:2ace1ff71ae6 | 63 | return (u32_t) systick_timems; |
emilmont | 6:2ace1ff71ae6 | 64 | } |
emilmont | 6:2ace1ff71ae6 | 65 | |
emilmont | 6:2ace1ff71ae6 | 66 | #else |
emilmont | 6:2ace1ff71ae6 | 67 | /* CMSIS-RTOS implementation of the lwip operating system abstraction */ |
emilmont | 6:2ace1ff71ae6 | 68 | #include "arch/sys_arch.h" |
emilmont | 6:2ace1ff71ae6 | 69 | |
emilmont | 6:2ace1ff71ae6 | 70 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 71 | * Routine: sys_mbox_new |
emilmont | 6:2ace1ff71ae6 | 72 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 73 | * Description: |
emilmont | 6:2ace1ff71ae6 | 74 | * Creates a new mailbox |
emilmont | 6:2ace1ff71ae6 | 75 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 76 | * sys_mbox_t mbox -- Handle of mailbox |
emilmont | 6:2ace1ff71ae6 | 77 | * int queue_sz -- Size of elements in the mailbox |
emilmont | 6:2ace1ff71ae6 | 78 | * Outputs: |
emilmont | 6:2ace1ff71ae6 | 79 | * err_t -- ERR_OK if message posted, else ERR_MEM |
emilmont | 6:2ace1ff71ae6 | 80 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 81 | err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) { |
emilmont | 6:2ace1ff71ae6 | 82 | if (queue_sz > MB_SIZE) |
emilmont | 6:2ace1ff71ae6 | 83 | error("sys_mbox_new size error\n"); |
emilmont | 6:2ace1ff71ae6 | 84 | |
emilmont | 6:2ace1ff71ae6 | 85 | #ifdef CMSIS_OS_RTX |
emilmont | 6:2ace1ff71ae6 | 86 | memset(mbox->queue, 0, sizeof(mbox->queue)); |
emilmont | 6:2ace1ff71ae6 | 87 | mbox->def.pool = mbox->queue; |
emilmont | 6:2ace1ff71ae6 | 88 | mbox->def.queue_sz = queue_sz; |
emilmont | 6:2ace1ff71ae6 | 89 | #endif |
emilmont | 6:2ace1ff71ae6 | 90 | mbox->id = osMessageCreate(&mbox->def, NULL); |
emilmont | 6:2ace1ff71ae6 | 91 | return (mbox->id == NULL) ? (ERR_MEM) : (ERR_OK); |
emilmont | 6:2ace1ff71ae6 | 92 | } |
emilmont | 6:2ace1ff71ae6 | 93 | |
emilmont | 6:2ace1ff71ae6 | 94 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 95 | * Routine: sys_mbox_free |
emilmont | 6:2ace1ff71ae6 | 96 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 97 | * Description: |
emilmont | 6:2ace1ff71ae6 | 98 | * Deallocates a mailbox. If there are messages still present in the |
emilmont | 6:2ace1ff71ae6 | 99 | * mailbox when the mailbox is deallocated, it is an indication of a |
emilmont | 6:2ace1ff71ae6 | 100 | * programming error in lwIP and the developer should be notified. |
emilmont | 6:2ace1ff71ae6 | 101 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 102 | * sys_mbox_t *mbox -- Handle of mailbox |
emilmont | 6:2ace1ff71ae6 | 103 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 104 | void sys_mbox_free(sys_mbox_t *mbox) { |
emilmont | 6:2ace1ff71ae6 | 105 | osEvent event = osMessageGet(mbox->id, 0); |
emilmont | 6:2ace1ff71ae6 | 106 | if (event.status == osEventMessage) |
emilmont | 6:2ace1ff71ae6 | 107 | error("sys_mbox_free error\n"); |
emilmont | 6:2ace1ff71ae6 | 108 | } |
emilmont | 6:2ace1ff71ae6 | 109 | |
emilmont | 6:2ace1ff71ae6 | 110 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 111 | * Routine: sys_mbox_post |
emilmont | 6:2ace1ff71ae6 | 112 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 113 | * Description: |
emilmont | 6:2ace1ff71ae6 | 114 | * Post the "msg" to the mailbox. |
emilmont | 6:2ace1ff71ae6 | 115 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 116 | * sys_mbox_t mbox -- Handle of mailbox |
emilmont | 6:2ace1ff71ae6 | 117 | * void *msg -- Pointer to data to post |
emilmont | 6:2ace1ff71ae6 | 118 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 119 | void sys_mbox_post(sys_mbox_t *mbox, void *msg) { |
emilmont | 6:2ace1ff71ae6 | 120 | if (osMessagePut(mbox->id, (uint32_t)msg, osWaitForever) != osOK) |
emilmont | 6:2ace1ff71ae6 | 121 | error("sys_mbox_post error\n"); |
emilmont | 6:2ace1ff71ae6 | 122 | } |
emilmont | 6:2ace1ff71ae6 | 123 | |
emilmont | 6:2ace1ff71ae6 | 124 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 125 | * Routine: sys_mbox_trypost |
emilmont | 6:2ace1ff71ae6 | 126 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 127 | * Description: |
emilmont | 6:2ace1ff71ae6 | 128 | * Try to post the "msg" to the mailbox. Returns immediately with |
emilmont | 6:2ace1ff71ae6 | 129 | * error if cannot. |
emilmont | 6:2ace1ff71ae6 | 130 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 131 | * sys_mbox_t mbox -- Handle of mailbox |
emilmont | 6:2ace1ff71ae6 | 132 | * void *msg -- Pointer to data to post |
emilmont | 6:2ace1ff71ae6 | 133 | * Outputs: |
emilmont | 6:2ace1ff71ae6 | 134 | * err_t -- ERR_OK if message posted, else ERR_MEM |
emilmont | 6:2ace1ff71ae6 | 135 | * if not. |
emilmont | 6:2ace1ff71ae6 | 136 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 137 | err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { |
emilmont | 6:2ace1ff71ae6 | 138 | osStatus status = osMessagePut(mbox->id, (uint32_t)msg, 0); |
emilmont | 6:2ace1ff71ae6 | 139 | return (status == osOK) ? (ERR_OK) : (ERR_MEM); |
emilmont | 6:2ace1ff71ae6 | 140 | } |
emilmont | 6:2ace1ff71ae6 | 141 | |
emilmont | 6:2ace1ff71ae6 | 142 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 143 | * Routine: sys_arch_mbox_fetch |
emilmont | 6:2ace1ff71ae6 | 144 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 145 | * Description: |
emilmont | 6:2ace1ff71ae6 | 146 | * Blocks the thread until a message arrives in the mailbox, but does |
emilmont | 6:2ace1ff71ae6 | 147 | * not block the thread longer than "timeout" milliseconds (similar to |
emilmont | 6:2ace1ff71ae6 | 148 | * the sys_arch_sem_wait() function). The "msg" argument is a result |
emilmont | 6:2ace1ff71ae6 | 149 | * parameter that is set by the function (i.e., by doing "*msg = |
emilmont | 6:2ace1ff71ae6 | 150 | * ptr"). The "msg" parameter maybe NULL to indicate that the message |
emilmont | 6:2ace1ff71ae6 | 151 | * should be dropped. |
emilmont | 6:2ace1ff71ae6 | 152 | * |
emilmont | 6:2ace1ff71ae6 | 153 | * The return values are the same as for the sys_arch_sem_wait() function: |
emilmont | 6:2ace1ff71ae6 | 154 | * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a |
emilmont | 6:2ace1ff71ae6 | 155 | * timeout. |
emilmont | 6:2ace1ff71ae6 | 156 | * |
emilmont | 6:2ace1ff71ae6 | 157 | * Note that a function with a similar name, sys_mbox_fetch(), is |
emilmont | 6:2ace1ff71ae6 | 158 | * implemented by lwIP. |
emilmont | 6:2ace1ff71ae6 | 159 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 160 | * sys_mbox_t mbox -- Handle of mailbox |
emilmont | 6:2ace1ff71ae6 | 161 | * void **msg -- Pointer to pointer to msg received |
emilmont | 6:2ace1ff71ae6 | 162 | * u32_t timeout -- Number of milliseconds until timeout |
emilmont | 6:2ace1ff71ae6 | 163 | * Outputs: |
emilmont | 6:2ace1ff71ae6 | 164 | * u32_t -- SYS_ARCH_TIMEOUT if timeout, else number |
emilmont | 6:2ace1ff71ae6 | 165 | * of milliseconds until received. |
emilmont | 6:2ace1ff71ae6 | 166 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 167 | u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { |
emilmont | 6:2ace1ff71ae6 | 168 | u32_t start = us_ticker_read(); |
emilmont | 6:2ace1ff71ae6 | 169 | |
emilmont | 6:2ace1ff71ae6 | 170 | osEvent event = osMessageGet(mbox->id, (timeout != 0)?(timeout):(osWaitForever)); |
emilmont | 6:2ace1ff71ae6 | 171 | if (event.status != osEventMessage) |
emilmont | 6:2ace1ff71ae6 | 172 | return SYS_ARCH_TIMEOUT; |
emilmont | 6:2ace1ff71ae6 | 173 | |
emilmont | 6:2ace1ff71ae6 | 174 | *msg = (void *)event.value.v; |
emilmont | 6:2ace1ff71ae6 | 175 | |
emilmont | 6:2ace1ff71ae6 | 176 | return (us_ticker_read() - start) / 1000; |
emilmont | 6:2ace1ff71ae6 | 177 | } |
emilmont | 6:2ace1ff71ae6 | 178 | |
emilmont | 6:2ace1ff71ae6 | 179 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 180 | * Routine: sys_arch_mbox_tryfetch |
emilmont | 6:2ace1ff71ae6 | 181 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 182 | * Description: |
emilmont | 6:2ace1ff71ae6 | 183 | * Similar to sys_arch_mbox_fetch, but if message is not ready |
emilmont | 6:2ace1ff71ae6 | 184 | * immediately, we'll return with SYS_MBOX_EMPTY. On success, 0 is |
emilmont | 6:2ace1ff71ae6 | 185 | * returned. |
emilmont | 6:2ace1ff71ae6 | 186 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 187 | * sys_mbox_t mbox -- Handle of mailbox |
emilmont | 6:2ace1ff71ae6 | 188 | * void **msg -- Pointer to pointer to msg received |
emilmont | 6:2ace1ff71ae6 | 189 | * Outputs: |
emilmont | 6:2ace1ff71ae6 | 190 | * u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise, |
emilmont | 6:2ace1ff71ae6 | 191 | * return ERR_OK. |
emilmont | 6:2ace1ff71ae6 | 192 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 193 | u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { |
emilmont | 6:2ace1ff71ae6 | 194 | osEvent event = osMessageGet(mbox->id, 0); |
emilmont | 6:2ace1ff71ae6 | 195 | if (event.status != osEventMessage) |
emilmont | 6:2ace1ff71ae6 | 196 | return SYS_MBOX_EMPTY; |
emilmont | 6:2ace1ff71ae6 | 197 | |
emilmont | 6:2ace1ff71ae6 | 198 | *msg = (void *)event.value.v; |
emilmont | 6:2ace1ff71ae6 | 199 | |
emilmont | 6:2ace1ff71ae6 | 200 | return ERR_OK; |
emilmont | 6:2ace1ff71ae6 | 201 | } |
emilmont | 6:2ace1ff71ae6 | 202 | |
emilmont | 6:2ace1ff71ae6 | 203 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 204 | * Routine: sys_sem_new |
emilmont | 6:2ace1ff71ae6 | 205 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 206 | * Description: |
emilmont | 6:2ace1ff71ae6 | 207 | * Creates and returns a new semaphore. The "ucCount" argument specifies |
emilmont | 6:2ace1ff71ae6 | 208 | * the initial state of the semaphore. |
emilmont | 6:2ace1ff71ae6 | 209 | * NOTE: Currently this routine only creates counts of 1 or 0 |
emilmont | 6:2ace1ff71ae6 | 210 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 211 | * sys_sem_t sem -- Handle of semaphore |
emilmont | 6:2ace1ff71ae6 | 212 | * u8_t count -- Initial count of semaphore |
emilmont | 6:2ace1ff71ae6 | 213 | * Outputs: |
emilmont | 6:2ace1ff71ae6 | 214 | * err_t -- ERR_OK if semaphore created |
emilmont | 6:2ace1ff71ae6 | 215 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 216 | err_t sys_sem_new(sys_sem_t *sem, u8_t count) { |
emilmont | 6:2ace1ff71ae6 | 217 | #ifdef CMSIS_OS_RTX |
emilmont | 6:2ace1ff71ae6 | 218 | memset(sem->data, 0, sizeof(uint32_t)*2); |
emilmont | 6:2ace1ff71ae6 | 219 | sem->def.semaphore = sem->data; |
emilmont | 6:2ace1ff71ae6 | 220 | #endif |
emilmont | 6:2ace1ff71ae6 | 221 | sem->id = osSemaphoreCreate(&sem->def, count); |
emilmont | 6:2ace1ff71ae6 | 222 | if (sem->id == NULL) |
emilmont | 6:2ace1ff71ae6 | 223 | error("sys_sem_new create error\n"); |
emilmont | 6:2ace1ff71ae6 | 224 | |
emilmont | 6:2ace1ff71ae6 | 225 | return ERR_OK; |
emilmont | 6:2ace1ff71ae6 | 226 | } |
emilmont | 6:2ace1ff71ae6 | 227 | |
emilmont | 6:2ace1ff71ae6 | 228 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 229 | * Routine: sys_arch_sem_wait |
emilmont | 6:2ace1ff71ae6 | 230 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 231 | * Description: |
emilmont | 6:2ace1ff71ae6 | 232 | * Blocks the thread while waiting for the semaphore to be |
emilmont | 6:2ace1ff71ae6 | 233 | * signaled. If the "timeout" argument is non-zero, the thread should |
emilmont | 6:2ace1ff71ae6 | 234 | * only be blocked for the specified time (measured in |
emilmont | 6:2ace1ff71ae6 | 235 | * milliseconds). |
emilmont | 6:2ace1ff71ae6 | 236 | * |
emilmont | 6:2ace1ff71ae6 | 237 | * If the timeout argument is non-zero, the return value is the number of |
emilmont | 6:2ace1ff71ae6 | 238 | * milliseconds spent waiting for the semaphore to be signaled. If the |
emilmont | 6:2ace1ff71ae6 | 239 | * semaphore wasn't signaled within the specified time, the return value is |
emilmont | 6:2ace1ff71ae6 | 240 | * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore |
emilmont | 6:2ace1ff71ae6 | 241 | * (i.e., it was already signaled), the function may return zero. |
emilmont | 6:2ace1ff71ae6 | 242 | * |
emilmont | 6:2ace1ff71ae6 | 243 | * Notice that lwIP implements a function with a similar name, |
emilmont | 6:2ace1ff71ae6 | 244 | * sys_sem_wait(), that uses the sys_arch_sem_wait() function. |
emilmont | 6:2ace1ff71ae6 | 245 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 246 | * sys_sem_t sem -- Semaphore to wait on |
emilmont | 6:2ace1ff71ae6 | 247 | * u32_t timeout -- Number of milliseconds until timeout |
emilmont | 6:2ace1ff71ae6 | 248 | * Outputs: |
emilmont | 6:2ace1ff71ae6 | 249 | * u32_t -- Time elapsed or SYS_ARCH_TIMEOUT. |
emilmont | 6:2ace1ff71ae6 | 250 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 251 | u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { |
emilmont | 6:2ace1ff71ae6 | 252 | u32_t start = us_ticker_read(); |
emilmont | 6:2ace1ff71ae6 | 253 | |
emilmont | 6:2ace1ff71ae6 | 254 | if (osSemaphoreWait(sem->id, (timeout != 0)?(timeout):(osWaitForever)) < 1) |
emilmont | 6:2ace1ff71ae6 | 255 | return SYS_ARCH_TIMEOUT; |
emilmont | 6:2ace1ff71ae6 | 256 | |
emilmont | 6:2ace1ff71ae6 | 257 | return (us_ticker_read() - start) / 1000; |
emilmont | 6:2ace1ff71ae6 | 258 | } |
emilmont | 6:2ace1ff71ae6 | 259 | |
emilmont | 6:2ace1ff71ae6 | 260 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 261 | * Routine: sys_sem_signal |
emilmont | 6:2ace1ff71ae6 | 262 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 263 | * Description: |
emilmont | 6:2ace1ff71ae6 | 264 | * Signals (releases) a semaphore |
emilmont | 6:2ace1ff71ae6 | 265 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 266 | * sys_sem_t sem -- Semaphore to signal |
emilmont | 6:2ace1ff71ae6 | 267 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 268 | void sys_sem_signal(sys_sem_t *data) { |
emilmont | 6:2ace1ff71ae6 | 269 | if (osSemaphoreRelease(data->id) != osOK) |
emilmont | 6:2ace1ff71ae6 | 270 | mbed_die(); /* Can be called by ISR do not use printf */ |
emilmont | 6:2ace1ff71ae6 | 271 | } |
emilmont | 6:2ace1ff71ae6 | 272 | |
emilmont | 6:2ace1ff71ae6 | 273 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 274 | * Routine: sys_sem_free |
emilmont | 6:2ace1ff71ae6 | 275 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 276 | * Description: |
emilmont | 6:2ace1ff71ae6 | 277 | * Deallocates a semaphore |
emilmont | 6:2ace1ff71ae6 | 278 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 279 | * sys_sem_t sem -- Semaphore to free |
emilmont | 6:2ace1ff71ae6 | 280 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 281 | void sys_sem_free(sys_sem_t *sem) {} |
emilmont | 6:2ace1ff71ae6 | 282 | |
emilmont | 6:2ace1ff71ae6 | 283 | /** Create a new mutex |
emilmont | 6:2ace1ff71ae6 | 284 | * @param mutex pointer to the mutex to create |
emilmont | 6:2ace1ff71ae6 | 285 | * @return a new mutex */ |
emilmont | 6:2ace1ff71ae6 | 286 | err_t sys_mutex_new(sys_mutex_t *mutex) { |
emilmont | 6:2ace1ff71ae6 | 287 | #ifdef CMSIS_OS_RTX |
mbed_official | 18:8b8671ab556f | 288 | #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) |
mbed_official | 17:12e78a2462d0 | 289 | memset(mutex->data, 0, sizeof(int32_t)*4); |
mbed_official | 17:12e78a2462d0 | 290 | #else |
emilmont | 6:2ace1ff71ae6 | 291 | memset(mutex->data, 0, sizeof(int32_t)*3); |
mbed_official | 17:12e78a2462d0 | 292 | #endif |
emilmont | 6:2ace1ff71ae6 | 293 | mutex->def.mutex = mutex->data; |
emilmont | 6:2ace1ff71ae6 | 294 | #endif |
emilmont | 6:2ace1ff71ae6 | 295 | mutex->id = osMutexCreate(&mutex->def); |
emilmont | 6:2ace1ff71ae6 | 296 | if (mutex->id == NULL) |
emilmont | 6:2ace1ff71ae6 | 297 | return ERR_MEM; |
emilmont | 6:2ace1ff71ae6 | 298 | |
emilmont | 6:2ace1ff71ae6 | 299 | return ERR_OK; |
emilmont | 6:2ace1ff71ae6 | 300 | } |
emilmont | 6:2ace1ff71ae6 | 301 | |
emilmont | 6:2ace1ff71ae6 | 302 | /** Lock a mutex |
emilmont | 6:2ace1ff71ae6 | 303 | * @param mutex the mutex to lock */ |
emilmont | 6:2ace1ff71ae6 | 304 | void sys_mutex_lock(sys_mutex_t *mutex) { |
emilmont | 6:2ace1ff71ae6 | 305 | if (osMutexWait(mutex->id, osWaitForever) != osOK) |
emilmont | 6:2ace1ff71ae6 | 306 | error("sys_mutex_lock error\n"); |
emilmont | 6:2ace1ff71ae6 | 307 | } |
emilmont | 6:2ace1ff71ae6 | 308 | |
emilmont | 6:2ace1ff71ae6 | 309 | /** Unlock a mutex |
emilmont | 6:2ace1ff71ae6 | 310 | * @param mutex the mutex to unlock */ |
emilmont | 6:2ace1ff71ae6 | 311 | void sys_mutex_unlock(sys_mutex_t *mutex) { |
emilmont | 6:2ace1ff71ae6 | 312 | if (osMutexRelease(mutex->id) != osOK) |
emilmont | 6:2ace1ff71ae6 | 313 | error("sys_mutex_unlock error\n"); |
emilmont | 6:2ace1ff71ae6 | 314 | } |
emilmont | 6:2ace1ff71ae6 | 315 | |
emilmont | 6:2ace1ff71ae6 | 316 | /** Delete a mutex |
emilmont | 6:2ace1ff71ae6 | 317 | * @param mutex the mutex to delete */ |
emilmont | 6:2ace1ff71ae6 | 318 | void sys_mutex_free(sys_mutex_t *mutex) {} |
emilmont | 6:2ace1ff71ae6 | 319 | |
emilmont | 6:2ace1ff71ae6 | 320 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 321 | * Routine: sys_init |
emilmont | 6:2ace1ff71ae6 | 322 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 323 | * Description: |
emilmont | 6:2ace1ff71ae6 | 324 | * Initialize sys arch |
emilmont | 6:2ace1ff71ae6 | 325 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 326 | osMutexId lwip_sys_mutex; |
emilmont | 6:2ace1ff71ae6 | 327 | osMutexDef(lwip_sys_mutex); |
emilmont | 6:2ace1ff71ae6 | 328 | |
emilmont | 6:2ace1ff71ae6 | 329 | void sys_init(void) { |
emilmont | 7:b409691fb352 | 330 | us_ticker_read(); // Init sys tick |
emilmont | 6:2ace1ff71ae6 | 331 | lwip_sys_mutex = osMutexCreate(osMutex(lwip_sys_mutex)); |
emilmont | 6:2ace1ff71ae6 | 332 | if (lwip_sys_mutex == NULL) |
emilmont | 6:2ace1ff71ae6 | 333 | error("sys_init error\n"); |
emilmont | 6:2ace1ff71ae6 | 334 | } |
emilmont | 6:2ace1ff71ae6 | 335 | |
emilmont | 6:2ace1ff71ae6 | 336 | /*---------------------------------------------------------------------------* |
emilmont | 7:b409691fb352 | 337 | * Routine: sys_jiffies |
emilmont | 7:b409691fb352 | 338 | *---------------------------------------------------------------------------* |
emilmont | 7:b409691fb352 | 339 | * Description: |
emilmont | 7:b409691fb352 | 340 | * Used by PPP as a timestamp-ish value |
emilmont | 7:b409691fb352 | 341 | *---------------------------------------------------------------------------*/ |
emilmont | 7:b409691fb352 | 342 | u32_t sys_jiffies(void) { |
emilmont | 7:b409691fb352 | 343 | static u32_t jiffies = 0; |
emilmont | 7:b409691fb352 | 344 | jiffies += 1 + (us_ticker_read()/10000); |
emilmont | 7:b409691fb352 | 345 | return jiffies; |
emilmont | 7:b409691fb352 | 346 | } |
emilmont | 7:b409691fb352 | 347 | |
emilmont | 7:b409691fb352 | 348 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 349 | * Routine: sys_arch_protect |
emilmont | 6:2ace1ff71ae6 | 350 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 351 | * Description: |
emilmont | 6:2ace1ff71ae6 | 352 | * This optional function does a "fast" critical region protection and |
emilmont | 6:2ace1ff71ae6 | 353 | * returns the previous protection level. This function is only called |
emilmont | 6:2ace1ff71ae6 | 354 | * during very short critical regions. An embedded system which supports |
emilmont | 6:2ace1ff71ae6 | 355 | * ISR-based drivers might want to implement this function by disabling |
emilmont | 6:2ace1ff71ae6 | 356 | * interrupts. Task-based systems might want to implement this by using |
emilmont | 6:2ace1ff71ae6 | 357 | * a mutex or disabling tasking. This function should support recursive |
emilmont | 6:2ace1ff71ae6 | 358 | * calls from the same task or interrupt. In other words, |
emilmont | 6:2ace1ff71ae6 | 359 | * sys_arch_protect() could be called while already protected. In |
emilmont | 6:2ace1ff71ae6 | 360 | * that case the return value indicates that it is already protected. |
emilmont | 6:2ace1ff71ae6 | 361 | * |
emilmont | 6:2ace1ff71ae6 | 362 | * sys_arch_protect() is only required if your port is supporting an |
emilmont | 6:2ace1ff71ae6 | 363 | * operating system. |
emilmont | 6:2ace1ff71ae6 | 364 | * Outputs: |
emilmont | 6:2ace1ff71ae6 | 365 | * sys_prot_t -- Previous protection level (not used here) |
emilmont | 6:2ace1ff71ae6 | 366 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 367 | sys_prot_t sys_arch_protect(void) { |
emilmont | 6:2ace1ff71ae6 | 368 | if (osMutexWait(lwip_sys_mutex, osWaitForever) != osOK) |
emilmont | 6:2ace1ff71ae6 | 369 | error("sys_arch_protect error\n"); |
emilmont | 6:2ace1ff71ae6 | 370 | return (sys_prot_t) 1; |
emilmont | 6:2ace1ff71ae6 | 371 | } |
emilmont | 6:2ace1ff71ae6 | 372 | |
emilmont | 6:2ace1ff71ae6 | 373 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 374 | * Routine: sys_arch_unprotect |
emilmont | 6:2ace1ff71ae6 | 375 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 376 | * Description: |
emilmont | 6:2ace1ff71ae6 | 377 | * This optional function does a "fast" set of critical region |
emilmont | 6:2ace1ff71ae6 | 378 | * protection to the value specified by pval. See the documentation for |
emilmont | 6:2ace1ff71ae6 | 379 | * sys_arch_protect() for more information. This function is only |
emilmont | 6:2ace1ff71ae6 | 380 | * required if your port is supporting an operating system. |
emilmont | 6:2ace1ff71ae6 | 381 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 382 | * sys_prot_t -- Previous protection level (not used here) |
emilmont | 6:2ace1ff71ae6 | 383 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 384 | void sys_arch_unprotect(sys_prot_t p) { |
emilmont | 6:2ace1ff71ae6 | 385 | if (osMutexRelease(lwip_sys_mutex) != osOK) |
emilmont | 6:2ace1ff71ae6 | 386 | error("sys_arch_unprotect error\n"); |
emilmont | 6:2ace1ff71ae6 | 387 | } |
emilmont | 6:2ace1ff71ae6 | 388 | |
emilmont | 6:2ace1ff71ae6 | 389 | u32_t sys_now(void) { |
emilmont | 6:2ace1ff71ae6 | 390 | return us_ticker_read() / 1000; |
emilmont | 6:2ace1ff71ae6 | 391 | } |
emilmont | 6:2ace1ff71ae6 | 392 | |
emilmont | 6:2ace1ff71ae6 | 393 | void sys_msleep(u32_t ms) { |
emilmont | 6:2ace1ff71ae6 | 394 | osDelay(ms); |
emilmont | 6:2ace1ff71ae6 | 395 | } |
emilmont | 6:2ace1ff71ae6 | 396 | |
emilmont | 6:2ace1ff71ae6 | 397 | // Keep a pool of thread structures |
emilmont | 6:2ace1ff71ae6 | 398 | static int thread_pool_index = 0; |
emilmont | 6:2ace1ff71ae6 | 399 | static sys_thread_data_t thread_pool[SYS_THREAD_POOL_N]; |
emilmont | 6:2ace1ff71ae6 | 400 | |
emilmont | 6:2ace1ff71ae6 | 401 | /*---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 402 | * Routine: sys_thread_new |
emilmont | 6:2ace1ff71ae6 | 403 | *---------------------------------------------------------------------------* |
emilmont | 6:2ace1ff71ae6 | 404 | * Description: |
emilmont | 6:2ace1ff71ae6 | 405 | * Starts a new thread with priority "prio" that will begin its |
emilmont | 6:2ace1ff71ae6 | 406 | * execution in the function "thread()". The "arg" argument will be |
emilmont | 6:2ace1ff71ae6 | 407 | * passed as an argument to the thread() function. The id of the new |
emilmont | 6:2ace1ff71ae6 | 408 | * thread is returned. Both the id and the priority are system |
emilmont | 6:2ace1ff71ae6 | 409 | * dependent. |
emilmont | 6:2ace1ff71ae6 | 410 | * Inputs: |
emilmont | 6:2ace1ff71ae6 | 411 | * char *name -- Name of thread |
emilmont | 6:2ace1ff71ae6 | 412 | * void (*thread)(void *arg) -- Pointer to function to run. |
emilmont | 6:2ace1ff71ae6 | 413 | * void *arg -- Argument passed into function |
emilmont | 6:2ace1ff71ae6 | 414 | * int stacksize -- Required stack amount in bytes |
emilmont | 6:2ace1ff71ae6 | 415 | * int priority -- Thread priority |
emilmont | 6:2ace1ff71ae6 | 416 | * Outputs: |
emilmont | 6:2ace1ff71ae6 | 417 | * sys_thread_t -- Pointer to thread handle. |
emilmont | 6:2ace1ff71ae6 | 418 | *---------------------------------------------------------------------------*/ |
emilmont | 6:2ace1ff71ae6 | 419 | sys_thread_t sys_thread_new(const char *pcName, |
emilmont | 6:2ace1ff71ae6 | 420 | void (*thread)(void *arg), |
emilmont | 6:2ace1ff71ae6 | 421 | void *arg, int stacksize, int priority) { |
emilmont | 6:2ace1ff71ae6 | 422 | LWIP_DEBUGF(SYS_DEBUG, ("New Thread: %s\n", pcName)); |
emilmont | 6:2ace1ff71ae6 | 423 | |
emilmont | 6:2ace1ff71ae6 | 424 | if (thread_pool_index >= SYS_THREAD_POOL_N) |
emilmont | 6:2ace1ff71ae6 | 425 | error("sys_thread_new number error\n"); |
emilmont | 6:2ace1ff71ae6 | 426 | sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index]; |
emilmont | 6:2ace1ff71ae6 | 427 | thread_pool_index++; |
emilmont | 6:2ace1ff71ae6 | 428 | |
emilmont | 6:2ace1ff71ae6 | 429 | #ifdef CMSIS_OS_RTX |
emilmont | 6:2ace1ff71ae6 | 430 | t->def.pthread = (os_pthread)thread; |
emilmont | 6:2ace1ff71ae6 | 431 | t->def.tpriority = (osPriority)priority; |
emilmont | 6:2ace1ff71ae6 | 432 | t->def.stacksize = stacksize; |
mbed_official | 15:7d4b24b58e04 | 433 | t->def.stack_pointer = (uint32_t*)malloc(stacksize); |
emilmont | 6:2ace1ff71ae6 | 434 | if (t->def.stack_pointer == NULL) { |
emilmont | 6:2ace1ff71ae6 | 435 | error("Error allocating the stack memory"); |
emilmont | 6:2ace1ff71ae6 | 436 | } |
emilmont | 6:2ace1ff71ae6 | 437 | #endif |
emilmont | 6:2ace1ff71ae6 | 438 | t->id = osThreadCreate(&t->def, arg); |
emilmont | 6:2ace1ff71ae6 | 439 | if (t->id == NULL) |
emilmont | 6:2ace1ff71ae6 | 440 | error("sys_thread_new create error\n"); |
emilmont | 6:2ace1ff71ae6 | 441 | |
emilmont | 6:2ace1ff71ae6 | 442 | return t; |
emilmont | 6:2ace1ff71ae6 | 443 | } |
emilmont | 6:2ace1ff71ae6 | 444 | |
emilmont | 6:2ace1ff71ae6 | 445 | #endif |
emilmont | 6:2ace1ff71ae6 | 446 | |
mbed_official | 13:bca6d04bc6d3 | 447 | #ifdef LWIP_DEBUG |
emilmont | 6:2ace1ff71ae6 | 448 | |
emilmont | 6:2ace1ff71ae6 | 449 | /** \brief Displays an error message on assertion |
emilmont | 6:2ace1ff71ae6 | 450 | |
emilmont | 6:2ace1ff71ae6 | 451 | This function will display an error message on an assertion |
emilmont | 6:2ace1ff71ae6 | 452 | to the debug output. |
emilmont | 6:2ace1ff71ae6 | 453 | |
emilmont | 6:2ace1ff71ae6 | 454 | \param[in] msg Error message to display |
emilmont | 6:2ace1ff71ae6 | 455 | \param[in] line Line number in file with error |
emilmont | 6:2ace1ff71ae6 | 456 | \param[in] file Filename with error |
emilmont | 6:2ace1ff71ae6 | 457 | */ |
emilmont | 6:2ace1ff71ae6 | 458 | void assert_printf(char *msg, int line, char *file) { |
emilmont | 6:2ace1ff71ae6 | 459 | if (msg) |
emilmont | 6:2ace1ff71ae6 | 460 | error("%s:%d in file %s\n", msg, line, file); |
emilmont | 6:2ace1ff71ae6 | 461 | else |
emilmont | 6:2ace1ff71ae6 | 462 | error("LWIP ASSERT\n"); |
emilmont | 6:2ace1ff71ae6 | 463 | } |
emilmont | 6:2ace1ff71ae6 | 464 | |
emilmont | 6:2ace1ff71ae6 | 465 | #endif /* LWIP_DEBUG */ |