Ethernet for Nucleo and Disco board STM32F746 works with gcc and arm. IAC is untested

Dependents:   STM32F746_iothub_client_sample_mqtt DISCO-F746NG_Ethernet Nucleo_F746ZG_Ethernet thethingsiO-DISCO_F746NG-mqtt ... more

Committer:
DieterGraef
Date:
Thu Jun 23 09:04:23 2016 +0000
Revision:
1:28ba13dd96f7
Parent:
0:d26c1b55cfca
corrected MAC issue. The MAC is now 02:00:00:xx:xx:xx where xx is the sum over the unique device register

Who changed what in which revision?

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