/** \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; }
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; } }
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; }
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 } }
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; }