Exemplo n.º 1
0
/** \brief  Low level output of a packet. Never call this from an
 *          interrupt context, as it may block until TX descriptors
 *          become available.
 *
 *  \param[in] netif the lwip network interface structure for this netif
 *  \param[in] p the MAC packet to send (e.g. IP packet including MAC addresses and type)
 *  \return ERR_OK if the packet could be sent or an err_t value if the packet couldn't be sent
 */
static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p)
{
  struct k64f_enetdata *k64f_enet = netif->state;
  struct pbuf *q;
  struct pbuf *temp_pbuf;
  uint8_t *psend = NULL, *dst;

  temp_pbuf = pbuf_alloc(PBUF_RAW, p->tot_len + ENET_BUFF_ALIGNMENT, PBUF_RAM);
  if (NULL == temp_pbuf)
    return ERR_MEM;

  /* K64F note: the next line ensures that the RX buffer is properly aligned for the K64F
     RX descriptors (16 bytes alignment). However, by doing so, we're effectively changing
     a data structure which is internal to lwIP. This might not prove to be a good idea
     in the long run, but a better fix would probably involve modifying lwIP itself */
  psend = (uint8_t *)ENET_ALIGN((uint32_t)temp_pbuf->payload, ENET_BUFF_ALIGNMENT);

  for (q = p, dst = psend; q != NULL; q = q->next) {
    MEMCPY(dst, q->payload, q->len);
    dst += q->len;
  }

  /* Check if a descriptor is available for the transfer. */
  osStatus_t stat = osSemaphoreAcquire(k64f_enet->xTXDCountSem.id, 0);
  if (stat != osOK)
    return ERR_BUF;

  /* Get exclusive access */
  sys_mutex_lock(&k64f_enet->TXLockMutex);

  /* Save the buffer so that it can be freed when transmit is done */
  tx_buff[k64f_enet->tx_produce_index % ENET_TX_RING_LEN] = temp_pbuf;
  k64f_enet->tx_produce_index += 1;

  /* Setup transfers */
  g_handle.txBdCurrent->buffer = psend;
  g_handle.txBdCurrent->length = p->tot_len;
  g_handle.txBdCurrent->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);

  /* Increase the buffer descriptor address. */
  if (g_handle.txBdCurrent->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
    g_handle.txBdCurrent = g_handle.txBdBase;
  else
    g_handle.txBdCurrent++;

  /* Active the transmit buffer descriptor. */
  ENET->TDAR = ENET_TDAR_TDAR_MASK;

  LINK_STATS_INC(link.xmit);

  /* Restore access */
  sys_mutex_unlock(&k64f_enet->TXLockMutex);

  return ERR_OK;
}
Exemplo n.º 2
0
int32_t Semaphore::wait(uint32_t millisec) {
    osStatus_t stat = osSemaphoreAcquire(_id, millisec);
    switch (stat) {
        case osOK:
            return osSemaphoreGetCount(_id) + 1;
        case osErrorTimeout:
        case osErrorResource:
            return 0;
        case osErrorParameter:
        default:
            return -1;
    }
}
Exemplo n.º 3
0
int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
  osStatus_t status;
  uint32_t   count;

  status = osSemaphoreAcquire(semaphore_id, millisec);
  switch (status) {
    case osOK:
      count = osSemaphoreGetCount(semaphore_id);
      return ((int32_t)count + 1);
    case osErrorResource:
    case osErrorTimeout:
      return 0;
    default:
      break;
  }
  return -1;
}
Exemplo n.º 4
0
void Thread_Semaphore (void *argument)
{
  int32_t val;
 
  while (1) {
    ; // Insert thread code here...
 
    val = osSemaphoreAcquire (sid_Thread_Semaphore, 10);      // wait 10 mSec
    switch (val) {
    case osOK:
      ; // Use protected code here...
      osSemaphoreRelease (sid_Thread_Semaphore);              // Return a token back to a semaphore
      break;
    case osErrorResource:
      break;
    case osErrorParameter:
      break;
    default:
      break;
    }
 
    osThreadYield ();                                         // suspend thread
  }
}
Exemplo n.º 5
0
nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *netmask, const char *gw, const nsapi_ip_stack_t stack, bool block)
{
    // Check if we've already connected
    if (connected == NSAPI_STATUS_GLOBAL_UP) {
        return NSAPI_ERROR_IS_CONNECTED;
    } else if (connected == NSAPI_STATUS_CONNECTING) {
        return NSAPI_ERROR_ALREADY;
    }

    connected = NSAPI_STATUS_CONNECTING;
    blocking = block;

#if LWIP_DHCP
    if (stack != IPV6_STACK && dhcp) {
        dhcp_has_to_be_set = true;
    }
#endif

#if LWIP_IPV6
    if (stack != IPV4_STACK) {
        if (netif.hwaddr_len == 6) {
            netif_create_ip6_linklocal_address(&netif, 1/*from MAC*/);
        }
#if LWIP_IPV6_MLD
        /*
         * For hardware/netifs that implement MAC filtering.
         * All-nodes link-local is handled by default, so we must let the hardware know
         * to allow multicast packets in.
         * Should set mld_mac_filter previously. */
        if (netif.mld_mac_filter != NULL) {
            ip6_addr_t ip6_allnodes_ll;
            ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
            netif.mld_mac_filter(&netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
        }
#endif /* LWIP_IPV6_MLD */

#if LWIP_IPV6_AUTOCONFIG
        /* IPv6 address autoconfiguration not enabled by default */
        netif.ip6_autoconfig_enabled = 1;
#endif /* LWIP_IPV6_AUTOCONFIG */
    } else {
        // Disable rourter solicitations
        netif.rs_count = 0;
    }
#endif /* LWIP_IPV6 */

#if LWIP_IPV4
    if (stack != IPV6_STACK) {
        if (!dhcp && !ppp) {
            ip4_addr_t ip_addr;
            ip4_addr_t netmask_addr;
            ip4_addr_t gw_addr;

            if (!inet_aton(ip, &ip_addr) ||
                    !inet_aton(netmask, &netmask_addr) ||
                    !inet_aton(gw, &gw_addr)) {
                return NSAPI_ERROR_PARAMETER;
            }

            netif_set_addr(&netif, &ip_addr, &netmask_addr, &gw_addr);
        }
    }
#endif

    if (client_callback) {
        client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING);
    }

    if (ppp) {
        err_t err = ppp_lwip_connect(hw);
        if (err) {
            connected = NSAPI_STATUS_DISCONNECTED;
            if (client_callback) {
                client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED);
            }
            return err_remap(err);
        }
    }

    if (!netif_is_link_up(&netif)) {
        if (blocking) {
            if (osSemaphoreAcquire(linked, 15000) != osOK) {
                if (ppp) {
                    (void) ppp_lwip_disconnect(hw);
                }
                return NSAPI_ERROR_NO_CONNECTION;
            }
        }
    } else {
        nsapi_error_t ret = set_dhcp();
        if (ret != NSAPI_ERROR_OK) {
            return ret;
        }
    }

    if (!blocking) {
        // Done enough - as addresses are acquired, there will be
        // connected callbacks.
        // XXX shouldn't this be NSAPI_ERROR_IN_PROGRESS if in CONNECTING state?
        return NSAPI_ERROR_OK;
    }

    // If doesn't have address
    if (!LWIP::get_ip_addr(true, &netif)) {
        if (osSemaphoreAcquire(has_any_addr, DHCP_TIMEOUT * 1000) != osOK) {
            if (ppp) {
                (void) ppp_lwip_disconnect(hw);
            }
            return NSAPI_ERROR_DHCP_FAILURE;
        }
    }

#if PREF_ADDR_TIMEOUT
    if (stack != IPV4_STACK && stack != IPV6_STACK) {
        // If address is not for preferred stack waits a while to see
        // if preferred stack address is acquired
        if (!LWIP::get_ip_addr(false, &netif)) {
            osSemaphoreAcquire(has_pref_addr, PREF_ADDR_TIMEOUT * 1000);
        }
    }
#endif
#if BOTH_ADDR_TIMEOUT
    if (stack != IPV4_STACK && stack != IPV6_STACK) {
        // If addresses for both stacks are not available waits a while to
        // see if address for both stacks are acquired
        if (!(LWIP::get_ipv4_addr(&netif) && LWIP::get_ipv6_addr(&netif))) {
            osSemaphoreAcquire(has_both_addr, BOTH_ADDR_TIMEOUT * 1000);
        }
    }
#endif

    add_dns_addr(&netif);

    return NSAPI_ERROR_OK;
}