rt_err_t rt_data_queue_push(struct rt_data_queue *queue, const void *data_ptr, rt_size_t data_size, rt_int32_t timeout) { rt_uint16_t mask; rt_ubase_t level; rt_thread_t thread; rt_err_t result; RT_ASSERT(queue != RT_NULL); result = RT_EOK; thread = rt_thread_self(); mask = queue->size - 1; level = rt_hw_interrupt_disable(); while (queue->put_index - queue->get_index == queue->size) { queue->waiting_lwm = RT_TRUE; /* queue is full */ if (timeout == 0) { result = -RT_ETIMEOUT; goto __exit; } /* current context checking */ RT_DEBUG_NOT_IN_INTERRUPT; /* reset thread error number */ thread->error = RT_EOK; /* suspend thread on the push list */ rt_thread_suspend(thread); rt_list_insert_before(&(queue->suspended_push_list), &(thread->tlist)); /* start timer */ if (timeout > 0) { /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(level); /* do schedule */ rt_schedule(); /* thread is waked up */ result = thread->error; level = rt_hw_interrupt_disable(); if (result != RT_EOK) goto __exit; } queue->queue[queue->put_index & mask].data_ptr = data_ptr; queue->queue[queue->put_index & mask].data_size = data_size; queue->put_index += 1; if (!rt_list_isempty(&(queue->suspended_pop_list))) { /* there is at least one thread in suspended list */ /* get thread entry */ thread = rt_list_entry(queue->suspended_pop_list.next, struct rt_thread, tlist); /* resume it */ rt_thread_resume(thread); rt_hw_interrupt_enable(level); /* perform a schedule */ rt_schedule(); return result; }
/** * This function will allocate a block from memory pool * * @param mp the memory pool object * @param time the waiting time * * @return the allocated memory block or RT_NULL on allocated failed */ void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time) { rt_uint8_t *block_ptr; register rt_base_t level; struct rt_thread *thread; /* disable interrupt */ level = rt_hw_interrupt_disable(); if (mp->block_free_count) { /* memory block is available. decrease the free block counter */ mp->block_free_count --; /* get block from block list */ block_ptr = mp->block_list; mp->block_list = *(rt_uint8_t **)block_ptr; /* point to memory pool */ *(rt_uint8_t **)block_ptr = (rt_uint8_t *)mp; } else { /* memory block is unavailable. */ if (time == 0) { /* enable interrupt */ rt_hw_interrupt_enable(level); return RT_NULL; } else { RT_DEBUG_NOT_IN_INTERRUPT; /* get current thread */ thread = rt_thread_self(); /* need suspend thread */ rt_thread_suspend(thread); rt_list_insert_after(&(mp->suspend_thread), &(thread->tlist)); mp->suspend_thread_count ++; if (time > 0) { /* init thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(level); /* do a schedule */ rt_schedule(); if (thread->error != RT_EOK) return RT_NULL; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* decrease free block */ mp->block_free_count --; /* get block from block list */ block_ptr = mp->block_list; mp->block_list = *(rt_uint8_t **)block_ptr; /* point to memory pool */ *(rt_uint8_t **)block_ptr = (rt_uint8_t *)mp; } } /* enable interrupt */ rt_hw_interrupt_enable(level); RT_OBJECT_HOOK_CALL(rt_mp_alloc_hook, (mp, (rt_uint8_t *)(block_ptr + sizeof(rt_uint8_t *)))); return (rt_uint8_t *)(block_ptr + sizeof(rt_uint8_t *)); }
/* FIXME(Heyong): add for print the system infos when sys abort */ static void _rtt_statistics() { rt_uint32_t total; rt_uint32_t used; rt_uint32_t max_used; struct rt_thread *thread; struct rt_list_node *node; rt_uint8_t *ptr; rt_base_t level; struct rt_object_information *information; information = rt_object_get_information(RT_Object_Class_Thread); RT_ASSERT(information != RT_NULL); struct rt_list_node *list = &(information->object_list); level = rt_hw_interrupt_disable(); for (node = list->next; node != list; node = node->next) { thread = rt_list_entry(node, struct rt_thread, list); //if(thread) thread->total_tick = 0; } rt_hw_interrupt_enable(level); rt_memory_info(&total,&used,&max_used); rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); rt_kprintf("\n memory info size \n"); rt_kprintf("------------------------- ------\n"); rt_kprintf("total memory: (%dKB)\n", total/1024); rt_kprintf("used memory : (%dKB)\n", used/1024); rt_kprintf("maximum allocated memory: (%dKB)\n\n", max_used/1024); rt_kprintf(" thread pri status sp stack addr stack size max used \n"); rt_kprintf("-------------------------------- --- ------- ---------- ---------- ---------- ---------- \n"); for (node = list->next; node != list; node = node->next) { thread = rt_list_entry(node, struct rt_thread, list); #if 0 rt_kprintf("%-32.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority); #else int priority = thread->current_priority; rt_kprintf("%-32.*s %03d", RT_NAME_MAX, thread->name, priority); #endif if (thread->stat == RT_THREAD_READY) rt_kprintf(" ready "); else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend"); else if (thread->stat == RT_THREAD_INIT) rt_kprintf(" init "); else if (thread->stat == RT_THREAD_CLOSE) rt_kprintf(" close "); ptr = (rt_uint8_t*)thread->stack_addr; while (*ptr == '#')ptr++; rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x \n", thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp), thread->stack_addr, thread->stack_size, thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr) ); } rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); }
/** * This function will release a mutex, if there are threads suspended on mutex, * it will be waked up. * * @param mutex the mutex object * * @return the error code */ rt_err_t rt_mutex_release(rt_mutex_t mutex) { register rt_base_t temp; struct rt_thread *thread; rt_bool_t need_schedule; need_schedule = RT_FALSE; /* get current thread */ thread = rt_thread_self(); /* disable interrupt */ temp = rt_hw_interrupt_disable(); RT_DEBUG_LOG(RT_DEBUG_IPC, ("mutex_release:current thread %s, mutex value: %d, hold: %d\n", thread->name, mutex->value, mutex->hold)); RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mutex->parent.parent))); /* mutex only can be released by owner */ if (thread != mutex->owner) { thread->error = -RT_ERROR; /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_ERROR; } /* decrease hold */ mutex->hold --; /* if no hold */ if (mutex->hold == 0) { /* change the owner thread to original priority */ if (mutex->original_priority != mutex->owner->current_priority) { rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY, &(mutex->original_priority)); } /* wakeup suspended thread */ if (!rt_list_isempty(&mutex->parent.suspend_thread)) { /* get suspended thread */ thread = rt_list_entry(mutex->parent.suspend_thread.next, struct rt_thread, tlist); RT_DEBUG_LOG(RT_DEBUG_IPC, ("mutex_release: resume thread: %s\n", thread->name)); /* set new owner and priority */ mutex->owner = thread; mutex->original_priority = thread->current_priority; mutex->hold ++; /* resume thread */ rt_ipc_list_resume(&(mutex->parent.suspend_thread)); need_schedule = RT_TRUE; } else {
/***************************************************************************//** * @brief * IIC slave mode RX data valid interrupt handler * * @details * * @note * * @param[in] dev * Pointer to device descriptor ******************************************************************************/ static void rt_hw_iic_slave_isr(rt_device_t dev) { struct efm32_iic_device_t *iic; struct efm32_iic_int_mode_t *int_rx; rt_uint32_t status; volatile rt_uint32_t temp; /* interrupt mode receive */ RT_ASSERT(dev->flag & RT_DEVICE_FLAG_INT_RX); iic = (struct efm32_iic_device_t*)dev->user_data; int_rx = iic->rx_buffer; status = iic->iic_device->IF; if (status & I2C_IF_ADDR) { /* Address Match */ /* Indicating that reception is started */ temp = iic->iic_device->RXDATA & 0xFFUL; if ((temp != 0x00) || (iic->state & IIC_STATE_BROADCAST)) { iic->state |= IIC_STATE_RX_BUSY; } } else if (status & I2C_IF_RXDATAV) { if (iic->state & IIC_STATE_RX_BUSY) { rt_base_t level; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* save character */ int_rx->data_ptr[int_rx->save_index] = \ (rt_uint8_t)(iic->iic_device->RXDATA & 0xFFUL); int_rx->save_index ++; if (int_rx->save_index >= IIC_RX_BUFFER_SIZE) int_rx->save_index = 0; /* if the next position is read index, discard this 'read char' */ if (int_rx->save_index == int_rx->read_index) { int_rx->read_index ++; if (int_rx->read_index >= IIC_RX_BUFFER_SIZE) { int_rx->read_index = 0; } } /* enable interrupt */ rt_hw_interrupt_enable(level); } else { temp = iic->iic_device->RXDATA; } } if(status & I2C_IF_SSTOP) { /* Stop received, reception is ended */ iic->state &= ~(rt_uint8_t)IIC_STATE_RX_BUSY; } }
static rt_size_t rt_serial_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size) { rt_uint8_t *ptr; rt_size_t write_nbytes = 0; struct rt_serial_device *serial; RT_ASSERT(dev != RT_NULL); serial = (struct rt_serial_device *)dev; ptr = (rt_uint8_t*)buffer; if (dev->flag & RT_DEVICE_FLAG_INT_TX) { /* warning: data will be discarded if buffer is full */ while (size) { if (serial_ringbuffer_putchar(serial->int_tx, *ptr) != -1) { ptr ++; size --; } else break; } } else if (dev->flag & RT_DEVICE_FLAG_DMA_TX) { const void *data_ptr = RT_NULL; rt_size_t data_size = 0; rt_base_t level; rt_err_t result; RT_ASSERT(0 == (dev->flag & RT_DEVICE_FLAG_STREAM)); result = rt_data_queue_push(&(serial->tx_dq), buffer, size, 20); if (result == RT_EOK) { level = rt_hw_interrupt_disable(); if (serial->dma_flag == RT_FALSE) { serial->dma_flag = RT_TRUE; rt_hw_interrupt_enable(level); if (RT_EOK == rt_data_queue_pop(&(serial->tx_dq), &data_ptr, &data_size, 0)) { serial->ops->dma_transmit(serial, data_ptr, data_size); } } else rt_hw_interrupt_enable(level); return size; } else { rt_set_errno(result); return 0; } } else { /* polling mode */ while (size) { /* * to be polite with serial console add a line feed * to the carriage return character */ if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM)) { serial->ops->putc(serial, '\r'); } serial->ops->putc(serial, *ptr); ++ ptr; -- size; } } write_nbytes = (rt_uint32_t)ptr - (rt_uint32_t)buffer; if (write_nbytes == 0) { rt_set_errno(-RT_EFULL); } return write_nbytes; }
/** * This function will take a semaphore, if the semaphore is unavailable, the * thread shall wait for a specified time. * * @param sem the semaphore object * @param time the waiting time * * @return the error code */ rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time) { register rt_base_t temp; struct rt_thread *thread; RT_ASSERT(sem != RT_NULL); RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(sem->parent.parent))); /* disable interrupt */ temp = rt_hw_interrupt_disable(); RT_DEBUG_LOG(RT_DEBUG_IPC, ("thread %s take sem:%s, which value is: %d\n", rt_thread_self()->name, ((struct rt_object *)sem)->name, sem->value)); if (sem->value > 0) { /* semaphore is available */ sem->value --; /* enable interrupt */ rt_hw_interrupt_enable(temp); } else { /* no waiting, return with timeout */ if (time == 0) { rt_hw_interrupt_enable(temp); return -RT_ETIMEOUT; } else { /* current context checking */ RT_DEBUG_NOT_IN_INTERRUPT; /* semaphore is unavailable, push to suspend list */ /* get current thread */ thread = rt_thread_self(); /* reset thread error number */ thread->error = RT_EOK; RT_DEBUG_LOG(RT_DEBUG_IPC, ("sem take: suspend thread - %s\n", thread->name)); /* suspend thread */ rt_ipc_list_suspend(&(sem->parent.suspend_thread), thread, sem->parent.parent.flag); /* has waiting time, start thread timer */ if (time > 0) { RT_DEBUG_LOG(RT_DEBUG_IPC, ("set thread:%s to timer list\n", thread->name)); /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(temp); /* do schedule */ rt_schedule(); if (thread->error != RT_EOK) { return thread->error; } } } RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(sem->parent.parent))); return RT_EOK; }
rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) { const struct pin_index *index; const struct pin_irq_map *irqmap; rt_base_t level; rt_int32_t irqindex = -1; GPIO_InitTypeDef GPIO_InitStruct; index = get_pin(pin); if (index == RT_NULL) { return RT_ENOSYS; } if (enabled == PIN_IRQ_ENABLE) { irqindex = bit2bitno(index->pin); if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) { return RT_ENOSYS; } level = rt_hw_interrupt_disable(); if (pin_irq_hdr_tab[irqindex].pin == -1) { rt_hw_interrupt_enable(level); return RT_ENOSYS; } irqmap = &pin_irq_map[irqindex]; /* GPIO Periph clock enable */ index->rcc(); /* Configure GPIO_InitStructure */ GPIO_InitStruct.Pin = index->pin; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; switch (pin_irq_hdr_tab[irqindex].mode) { case PIN_IRQ_MODE_RISING: GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; break; case PIN_IRQ_MODE_FALLING: GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; break; case PIN_IRQ_MODE_RISING_FALLING: GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; break; } HAL_GPIO_Init(index->gpio, &GPIO_InitStruct); HAL_NVIC_SetPriority(irqmap->irqno, 5, 0); HAL_NVIC_EnableIRQ(irqmap->irqno); rt_hw_interrupt_enable(level); } else if (enabled == PIN_IRQ_DISABLE) { irqmap = get_pin_irq_map(index->pin); if (irqmap == RT_NULL) { return RT_ENOSYS; } HAL_NVIC_DisableIRQ(irqmap->irqno); } else { return RT_ENOSYS; } return RT_EOK; }
/** * This function will start the timer * * @param timer the timer to be started * * @return the operation status, RT_EOK on OK, -RT_ERROR on error */ rt_err_t rt_timer_start(rt_timer_t timer) { int row_lvl; rt_list_t *timer_list; register rt_base_t level; rt_list_t *row_head[RT_TIMER_SKIP_LIST_LEVEL]; unsigned int tst_nr; static unsigned int random_nr; /* timer check */ RT_ASSERT(timer != RT_NULL); if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) return -RT_ERROR; RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent))); /* * get timeout tick, * the max timeout tick shall not great than RT_TICK_MAX/2 */ RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2); timer->timeout_tick = rt_tick_get() + timer->init_tick; /* disable interrupt */ level = rt_hw_interrupt_disable(); #ifdef RT_USING_TIMER_SOFT if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER) { /* insert timer to soft timer list */ timer_list = rt_soft_timer_list; } else #endif { /* insert timer to system timer list */ timer_list = rt_timer_list; } row_head[0] = &timer_list[0]; for (row_lvl = 0; row_lvl < RT_TIMER_SKIP_LIST_LEVEL; row_lvl++) { for (;row_head[row_lvl] != timer_list[row_lvl].prev; row_head[row_lvl] = row_head[row_lvl]->next) { struct rt_timer *t; rt_list_t *p = row_head[row_lvl]->next; /* fix up the entry pointer */ t = rt_list_entry(p, struct rt_timer, row[row_lvl]); /* If we have two timers that timeout at the same time, it's * preferred that the timer inserted early get called early. * So insert the new timer to the end the the some-timeout timer * list. */ if ((t->timeout_tick - timer->timeout_tick) == 0) { continue; } else if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX / 2) { break; } } if (row_lvl != RT_TIMER_SKIP_LIST_LEVEL - 1) row_head[row_lvl+1] = row_head[row_lvl]+1; } /* Interestingly, this super simple timer insert counter works very very * well on distributing the list height uniformly. By means of "very very * well", I mean it beats the randomness of timer->timeout_tick very easily * (actually, the timeout_tick is not random and easy to be attacked). */ random_nr++; tst_nr = random_nr; rt_list_insert_after(row_head[RT_TIMER_SKIP_LIST_LEVEL-1], &(timer->row[RT_TIMER_SKIP_LIST_LEVEL-1])); for (row_lvl = 2; row_lvl <= RT_TIMER_SKIP_LIST_LEVEL; row_lvl++) { if (!(tst_nr & RT_TIMER_SKIP_LIST_MASK)) rt_list_insert_after(row_head[RT_TIMER_SKIP_LIST_LEVEL - row_lvl], &(timer->row[RT_TIMER_SKIP_LIST_LEVEL - row_lvl])); else break; /* Shift over the bits we have tested. Works well with 1 bit and 2 * bits. */ tst_nr >>= (RT_TIMER_SKIP_LIST_MASK+1)>>1; } timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED; /* enable interrupt */ rt_hw_interrupt_enable(level); #ifdef RT_USING_TIMER_SOFT if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER) { /* check whether timer thread is ready */ if (timer_thread.stat != RT_THREAD_READY) { /* resume timer thread to check soft timer */ rt_thread_resume(&timer_thread); rt_schedule(); } } #endif return -RT_EOK; }
void usart_rx_thread_entry(void *p) { unsigned short max_interval,max_datalen; unsigned int current_mode; getFrameSplit(&max_interval,&max_datalen); current_mode = getWorkingMode(); while( rt_sem_take(&rx_sem,RT_WAITING_FOREVER) == RT_EOK ) { register rt_base_t temp; FEED_THE_DOG(); // if rj45 not connected, we should route data between 232 and 485. if( getLinkStatus() == 0 ) { // we split rx_buf to 2 parts in order to save space. int len1,len2; // Clear the semaphore. temp = rt_hw_interrupt_disable(); rx_sem.value = 0; rt_hw_interrupt_enable(temp); do { usart_led_flash(); // recv usart1 rt_sem_take(&tx2_sem,RT_WAITING_FOREVER); len1 = rt_device_read(dev_uart1,0,rx_buf,RX_BUF_SIZE/2); if( len1 ) dev_uart2->write(dev_uart2, 0, rx_buf, len1); else rt_sem_release(&tx2_sem); // recv usart2 rt_sem_take(&tx1_sem,RT_WAITING_FOREVER); len2 = rt_device_read(dev_uart2,0,rx_buf+RX_BUF_SIZE/2,RX_BUF_SIZE/2); if( len2 ) dev_uart1->write(dev_uart1, 0, rx_buf+RX_BUF_SIZE/2, len2); else rt_sem_release(&tx1_sem); }while( (len1 != 0) && (len2 != 0) ); continue; } else { // Clear the semaphore. temp = rt_hw_interrupt_disable(); rx_sem.value = 0; rt_hw_interrupt_enable(temp); while( 1 ) { int len; usart_led_flash(); // read data. len = rt_device_read(dev_uart1,0,rx_buf+rx_buf_offset,RX_BUF_SIZE-rx_buf_offset); if( len == 0 ) { len = rt_device_read(dev_uart2,0,rx_buf+rx_buf_offset,RX_BUF_SIZE-rx_buf_offset); } usart_bytes_recv += len; // If buffer is empty and we received data, start the timer. if( rx_buf_offset == 0 ) { if( len == 0 ) { break; } else { // if interval less than 10ms, we send data immediately. if( max_interval >= 10 ) rt_timer_start(&max_interval_timer); } } // move offset pointer. rx_buf_offset += len; // check if we should send data out. if( rx_buf_offset < max_datalen && max_interval_timer.parent.flag & RT_TIMER_FLAG_ACTIVATED ) { break; } // Send data out. if((current_mode == TCP_SERVER)|| (current_mode == TCP_CLIENT)|| (current_mode == TCP_AUTO)) { int i; // send data. for( i = 0 ; i < SOCKET_LIST_SIZE ; i++ ) { // we should not use RT_WAITING_FOREVER here. if( rt_mutex_take(&(socket_list[i].mu_sock),10) != RT_EOK ) continue; // slot not used. if( socket_list[i].used ) { // shall not blocking. if( lwip_send(socket_list[i].socket,rx_buf,rx_buf_offset,0) < 0 ) { // connection lost. lwip_close(socket_list[i].socket); socket_list[i].used = 0; rt_kprintf("Connection lost.\n"); } } rt_mutex_release(&(socket_list[i].mu_sock)); } } else if( (current_mode == UDP)|| (current_mode == UDP_MULTICAST) ) { if( rt_mutex_take(&(socket_list[0].mu_sock),10) == RT_EOK ) { if( socket_list[0].used ) { lwip_sendto(socket_list[0].socket,rx_buf,rx_buf_offset,0, (struct sockaddr*)&(socket_list[0].cliaddr), sizeof(struct sockaddr)); } rt_mutex_release(&(socket_list[0].mu_sock)); } } else { rt_kprintf("fatal error! rx thread exits.\n"); return; } rx_buf_offset = 0; } } } rt_kprintf("Error taking semaphore, usart rx exit!\n"); }
static void rt_console_isr(int vector, void* param) { char c; rt_bool_t ret; rt_base_t level; if(INTUART0_RX == vector) { c = rt_serial_getc(); ret = RT_TRUE; } else { rt_keyboard_isr(); ret = rt_keyboard_getc(&c); } if(ret == RT_FALSE) { /* do nothing */ } else { /* disable interrupt */ level = rt_hw_interrupt_disable(); /* save character */ rx_buffer[save_index] = c; save_index ++; if (save_index >= CONSOLE_RX_BUFFER_SIZE) save_index = 0; /* if the next position is read index, discard this 'read char' */ if (save_index == read_index) { read_index ++; if (read_index >= CONSOLE_RX_BUFFER_SIZE) read_index = 0; } /* enable interrupt */ rt_hw_interrupt_enable(level); } /* invoke callback */ if (console_device.rx_indicate != RT_NULL) { rt_size_t rx_length; /* get rx length */ rx_length = read_index > save_index ? CONSOLE_RX_BUFFER_SIZE - read_index + save_index : save_index - read_index; if(rx_length > 0) { console_device.rx_indicate(&console_device, rx_length); } } else { } }
/** * @brief This function processes received packet and forwards it * to kernel/upper layer * * @param priv A pointer to wlan_private * @param skb A pointer to skb which includes the received packet * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE */ void ProcessRxedPacket(WlanCard *cardinfo,u8 *data,u32 len) { struct pbuf* p = RT_NULL; RxPacketHdr_t *pRxPkt; RxPD *pRxPD; u32 pbuflen; int hdrChop; int minlen; EthII_Hdr_t *pEthHdr; Rx_Pbuf_List *RxNode = NULL; rt_base_t level; WlanCard *card = cardinfo; Rx_Pbuf_List *HeadNode = &card->RxList; const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; RxNode = rt_malloc(sizeof(RxNode)); if (RxNode == NULL) { WlanDebug(WlanErr,"RX packet Error: memory alloc failed\r\n"); goto done; } pRxPD = (RxPD *) data; pRxPkt = (RxPacketHdr_t *) ((u8 *) pRxPD + pRxPD->PktOffset); /*mac source address :6byte .mac destination address :6byte. length 2 bytes =14*/ minlen = (8 + 4 + (pRxPD->PktOffset)); if (len < minlen) { WlanDebug( WlanErr,"RX Error: packet length is too long\n"); rt_free(RxNode); goto done; } WlanDebug(WlanData, "RX Data:%d\n",len - pRxPD->PktOffset); WlanDebug(WlanData, "SNR: %d, NF: %d\n", pRxPD->SNR, pRxPD->NF); WlanDebug(WlanData,"RX Data Dest \r\n %x,%x,%x,%x,%x,%x\r\n", pRxPkt->eth803_hdr.dest_addr[0], pRxPkt->eth803_hdr.dest_addr[1], pRxPkt->eth803_hdr.dest_addr[2], pRxPkt->eth803_hdr.dest_addr[3], pRxPkt->eth803_hdr.dest_addr[4], pRxPkt->eth803_hdr.dest_addr[5]); WlanDebug(WlanData,"RX Data Src\r\n %x,%x,%x,%x,%x,%x\r\n", pRxPkt->eth803_hdr.src_addr[0], pRxPkt->eth803_hdr.src_addr[1], pRxPkt->eth803_hdr.src_addr[2], pRxPkt->eth803_hdr.src_addr[3], pRxPkt->eth803_hdr.src_addr[4], pRxPkt->eth803_hdr.src_addr[5]); if (rt_memcmp(&pRxPkt->rfc1042_hdr, rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) { /* * Replace the 803 header and rfc1042 header (llc/snap) with an * EthernetII header, keep the src/dst and snap_type (ethertype) * * The firmware only passes up SNAP frames converting * all RX Data from 802.11 to 802.2/LLC/SNAP frames. * * To create the Ethernet II, just move the src, dst address right * before the snap_type. */ pEthHdr = (EthII_Hdr_t *) ((u8 *) &pRxPkt->eth803_hdr + sizeof(pRxPkt->eth803_hdr) + sizeof(pRxPkt->rfc1042_hdr) - sizeof(pRxPkt->eth803_hdr.dest_addr) - sizeof(pRxPkt->eth803_hdr.src_addr) - sizeof(pRxPkt->rfc1042_hdr.snap_type)); rt_memcpy(pEthHdr->src_addr, pRxPkt->eth803_hdr.src_addr, sizeof(pEthHdr->src_addr)); rt_memcpy(pEthHdr->dest_addr, pRxPkt->eth803_hdr.dest_addr, sizeof(pEthHdr->dest_addr)); /* Chop off the RxPD + the excess memory from the 802.2/llc/snap header * that was removed */ hdrChop = (u8 *) pEthHdr - (u8 *) pRxPD; } else { hexdump("RX Data: LLC/SNAP", (u8 *) &pRxPkt->rfc1042_hdr, sizeof(pRxPkt->rfc1042_hdr)); /* Chop off the RxPD */ hdrChop = (u8 *) &pRxPkt->eth803_hdr - (u8 *) pRxPD; rt_free(RxNode); } /* Chop off the leading header bytes so the skb points to the start of * either the reconstructed EthII frame or the 802.2/llc/snap frame */ pbuflen = (len - hdrChop); if (pbuflen < 100) pbuflen = 100; p = pbuf_alloc(PBUF_LINK, pbuflen, PBUF_RAM); if (p == RT_NULL) { WlanDebug(WlanErr,"alloc pbuf failed length %d",pbuflen); rt_free(RxNode); return; } rt_memcpy(p->payload, (u8*) ((u32) pRxPD + hdrChop), pbuflen); RxNode->p = p; level = rt_hw_interrupt_disable(); if (HeadNode->next == HeadNode) { HeadNode->next = RxNode; HeadNode->pre = RxNode; RxNode->next = HeadNode; RxNode->pre = HeadNode; } else { HeadNode->pre->next = RxNode; RxNode->pre = HeadNode->pre; HeadNode->pre = RxNode; RxNode->next = HeadNode; } card->RxQueueCount++; rt_hw_interrupt_enable(level); done: return; }
/***************************************************************************//** * @brief * USART RX data valid interrupt handler * * @details * * @note * 9-bit SPI mode has not implemented yet and SPI slave mode is untested * * @param[in] dev * Pointer to device descriptor ******************************************************************************/ void rt_hw_usart_rx_isr(rt_device_t dev) { struct efm32_usart_device_t *usart; struct efm32_usart_int_mode_t *int_rx; rt_uint32_t flag; /* interrupt mode receive */ RT_ASSERT(dev->flag & RT_DEVICE_FLAG_INT_RX); usart = (struct efm32_usart_device_t *)(dev->user_data); int_rx = (struct efm32_usart_int_mode_t *)(usart->rx_mode); RT_ASSERT(int_rx->data_ptr != RT_NULL); #if defined(UART_PRESENT) if (usart->state & USART_STATE_ASYNC_ONLY) { flag = UART_STATUS_RXDATAV; } else #endif { flag = USART_STATUS_RXDATAV; } /* Set status */ usart->state |= USART_STATE_RX_BUSY; /* save into rx buffer */ while (usart->usart_device->STATUS & flag) { rt_base_t level; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* save character */ int_rx->data_ptr[int_rx->save_index] = \ (rt_uint8_t)(usart->usart_device->RXDATA & 0xFFUL); int_rx->save_index ++; if (int_rx->save_index >= USART_RX_BUFFER_SIZE) int_rx->save_index = 0; /* if the next position is read index, discard this 'read char' */ if (int_rx->save_index == int_rx->read_index) { int_rx->read_index ++; if (int_rx->read_index >= USART_RX_BUFFER_SIZE) { int_rx->read_index = 0; } } /* enable interrupt */ rt_hw_interrupt_enable(level); } /* invoke callback */ if (dev->rx_indicate != RT_NULL) { rt_size_t rx_length; /* get rx length */ rx_length = int_rx->read_index > int_rx->save_index ? USART_RX_BUFFER_SIZE - int_rx->read_index + int_rx->save_index : \ int_rx->save_index - int_rx->read_index; dev->rx_indicate(dev, rx_length); } }
/***************************************************************************//** * @brief * Read from USART device * * @details * * @note * 9-bit SPI mode and SPI slave mode is untested * * @param[in] dev * Pointer to device descriptor * * @param[in] pos * Offset * * @param[in] buffer * Poniter to the buffer * * @param[in] size * Buffer size in byte * * @return * Number of read bytes ******************************************************************************/ static rt_size_t rt_usart_read ( rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) { rt_err_t err_code; struct efm32_usart_device_t *usart; rt_size_t read_len, len; rt_uint8_t *ptr; rt_uint32_t rx_flag, tx_flag, b8_flag; usart = (struct efm32_usart_device_t *)(dev->user_data); #if defined(UART_PRESENT) if (usart->state & USART_STATE_ASYNC_ONLY) { rx_flag = UART_STATUS_RXDATAV; tx_flag = UART_STATUS_TXBL; b8_flag = UART_CTRL_BIT8DV; } else #endif { rx_flag = USART_STATUS_RXDATAV; tx_flag = USART_STATUS_TXBL; b8_flag = USART_CTRL_BIT8DV; } /* Lock device */ if (rt_hw_interrupt_check()) { err_code = rt_sem_take(usart->lock, RT_WAITING_NO); } else { err_code = rt_sem_take(usart->lock, RT_WAITING_FOREVER); } if (err_code != RT_EOK) { rt_set_errno(err_code); return 0; } if (dev->flag & RT_DEVICE_FLAG_INT_RX) { len = size; ptr = buffer; /* interrupt mode Rx */ while (len) { rt_base_t level; struct efm32_usart_int_mode_t *int_rx; int_rx = (struct efm32_usart_int_mode_t *)\ (((struct efm32_usart_device_t *)(dev->user_data))->rx_mode); /* disable interrupt */ level = rt_hw_interrupt_disable(); if (int_rx->read_index != int_rx->save_index) { /* read a character */ *ptr++ = int_rx->data_ptr[int_rx->read_index]; len--; /* move to next position */ int_rx->read_index ++; if (int_rx->read_index >= USART_RX_BUFFER_SIZE) { int_rx->read_index = 0; } } else { /* set error code */ err_code = -RT_EEMPTY; /* enable interrupt */ rt_hw_interrupt_enable(level); break; } /* enable interrupt */ rt_hw_interrupt_enable(level); } read_len = (rt_uint32_t)ptr - (rt_uint32_t)buffer; } else { if (usart->state & USART_STATE_SYNC) { /* SPI read */ rt_uint8_t inst_len = *((rt_uint8_t *)buffer); rt_uint8_t *inst_ptr = (rt_uint8_t *)(buffer + 1); rt_uint8_t *rx_buf = *((rt_uint8_t **)(buffer + inst_len + 1)); rt_off_t i; ptr = inst_ptr; len = inst_len; /* Write instructions */ if (len) { if (usart->state & USART_STATE_9BIT) { usart->usart_device->CTRL &= ~b8_flag; } while (len) { while (!(usart->usart_device->STATUS & tx_flag)); usart->usart_device->TXDATA = (rt_uint32_t)*(ptr++); len--; } if (usart->state & USART_STATE_9BIT) { usart->usart_device->CTRL |= b8_flag; } } /* Flushing RX */ usart->usart_device->CMD = USART_CMD_CLEARRX; /* Skip some bytes if necessary */ for (i = 0; i < pos; i++) { /* dummy write */ while (!(usart->usart_device->STATUS & tx_flag)); usart->usart_device->TXDATA = (rt_uint32_t)0xff; /* dummy read */ while (!(usart->usart_device->STATUS & rx_flag)); *((rt_uint32_t *)0x00) = usart->usart_device->RXDATA; } ptr = rx_buf; len = size; /* Read data */ while (len) { /* dummy write */ while (!(usart->usart_device->STATUS & tx_flag)); usart->usart_device->TXDATA = (rt_uint32_t)0xff; /* read a byte of data */ while (!(usart->usart_device->STATUS & rx_flag)); *(ptr++) = usart->usart_device->RXDATA & 0xff; len--; } } else { ptr = buffer; len = size; /* polling mode */ while (len) { while (usart->usart_device->STATUS & rx_flag) { *(ptr++) = usart->usart_device->RXDATA & 0xff; } len--; } } read_len = size - len; } /* Unlock device */ rt_sem_release(usart->lock); /* set error code */ rt_set_errno(err_code); return read_len; }
void rt_timer_check(void) { struct rt_timer *t; rt_tick_t current_tick; register rt_base_t level; #ifdef RT_TIMER_DEBUG rt_kprintf("timer check enter\n"); #endif current_tick = rt_tick_get(); /* disable interrupt */ level = rt_hw_interrupt_disable(); while (!rt_list_isempty(&rt_timer_list)) { t = rt_list_entry(rt_timer_list.next, struct rt_timer, list); /* * It supposes that the new tick shall less than the half duration of tick max. */ if ((current_tick - t->timeout_tick) < RT_TICK_MAX/2) { #ifdef RT_USING_HOOK if (rt_timer_timeout_hook != RT_NULL) rt_timer_timeout_hook(t); #endif /* remove timer from timer list firstly */ rt_list_remove(&(t->list)); /* call timeout function */ t->timeout_func(t->parameter); /* re-get tick */ current_tick = rt_tick_get(); #ifdef RT_TIMER_DEBUG rt_kprintf("current tick: %d\n", current_tick); #endif if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) { /* start it */ t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; rt_timer_start(t); } else { /* stop timer */ t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; } } else break; } /* enable interrupt */ rt_hw_interrupt_enable(level); /* increase soft timer tick */ #ifdef RT_USING_TIMER_SOFT rt_soft_timer_tick_increase ( ); #endif #ifdef RT_TIMER_DEBUG rt_kprintf("timer check leave\n"); #endif }
static void net_buf_do_job(struct net_buffer_job* job) { rt_uint32_t level; rt_size_t read_length, data_length; rt_uint8_t *ptr; ptr = rt_malloc(NETBUF_BLOCK_SIZE); while (1) { if (_netbuf.stat == NETBUF_STAT_STOPPING) { net_buf_do_stop(job); break; } /* fetch data buffer */ read_length = job->fetch(ptr, NETBUF_BLOCK_SIZE, job->parameter); if (read_length <= 0) { net_buf_do_stop(job); break; } else { /* got data length in the buffer */ data_length = _netbuf.data_length; /* check avaible buffer to save */ if ((_netbuf.size - data_length) < read_length) { rt_err_t result, level; /* no free space yet, suspend itself */ // rt_kprintf("stat[buffering] -> suspend, avaible room %d\n", data_length); level = rt_hw_interrupt_disable(); _netbuf.stat = NETBUF_STAT_SUSPEND; rt_hw_interrupt_enable(level); result = rt_sem_take(_netbuf.wait_resume, RT_WAITING_FOREVER); if (result != RT_EOK) { /* stop net buffer worker */ net_buf_do_stop(job); break; } } /* there are enough free space to fetch data */ if ((_netbuf.size - _netbuf.save_index) < read_length) { rt_memcpy(&_netbuf.buffer_data[_netbuf.save_index], ptr, _netbuf.size - _netbuf.save_index); rt_memcpy(&_netbuf.buffer_data[0], ptr + (_netbuf.size - _netbuf.save_index), read_length - (_netbuf.size - _netbuf.save_index)); /* move save index */ _netbuf.save_index = read_length - (_netbuf.size - _netbuf.save_index); } else { rt_memcpy(&_netbuf.buffer_data[_netbuf.save_index], ptr, read_length); /* move save index */ _netbuf.save_index += read_length; if (_netbuf.save_index >= _netbuf.size) _netbuf.save_index = 0; } level = rt_hw_interrupt_disable(); _netbuf.data_length += read_length; data_length = _netbuf.data_length; rt_hw_interrupt_enable(level); } if ((_netbuf.stat == NETBUF_STAT_BUFFERING) && (data_length >= _netbuf.ready_wm) && _netbuf.is_wait_ready == RT_TRUE) { /* notify the thread for waitting buffer ready */ rt_kprintf("resume wait buffer\n"); _netbuf.is_wait_ready = RT_FALSE; /* set buffer status to playing */ player_set_buffer_status(RT_FALSE); rt_sem_release(_netbuf.wait_ready); } } /* release fetch buffer */ rt_free(ptr); }
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) { rt_uint8_t *ptr; rt_err_t err_code; struct avr32_serial_device *uart; ptr = buffer; err_code = RT_EOK; uart = (struct avr32_serial_device *)dev->user_data; if (dev->flag & RT_DEVICE_FLAG_INT_RX) { /* interrupt mode Rx */ while (size) { rt_base_t level; /* disable interrupt */ level = rt_hw_interrupt_disable(); if (uart->int_rx->read_index != uart->int_rx->save_index) { /* read a character */ *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index]; size--; /* move to next position */ uart->int_rx->read_index ++; if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) uart->int_rx->read_index = 0; } else { /* set error code */ err_code = -RT_EEMPTY; /* enable interrupt */ rt_hw_interrupt_enable(level); break; } /* enable interrupt */ rt_hw_interrupt_enable(level); } } else { /* polling mode */ while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) { while (usart_test_hit(uart->uart_device)) { *ptr = uart->uart_device->rhr & 0xff; ptr ++; } } } /* set error code */ rt_set_errno(err_code); return (rt_uint32_t)ptr - (rt_uint32_t)buffer; }
/* netbuf worker public API */ rt_size_t net_buf_read(rt_uint8_t* buffer, rt_size_t length) { rt_size_t data_length, read_index; rt_uint32_t level; data_length = _netbuf.data_length; if ((data_length == 0) && (_netbuf.stat == NETBUF_STAT_BUFFERING || _netbuf.stat == NETBUF_STAT_SUSPEND)) { rt_err_t result; /* buffer is not ready. */ _netbuf.is_wait_ready = RT_TRUE; rt_kprintf("wait ready, data len: %d, stat %d\n", data_length, _netbuf.stat); /* set buffer status to buffering */ player_set_buffer_status(RT_TRUE); result = rt_sem_take(_netbuf.wait_ready, RT_WAITING_FOREVER); /* take semaphore failed, netbuf worker is stopped */ if (result != RT_EOK) return 0; } /* get read and save index */ read_index = _netbuf.read_index; /* re-get data legnth */ data_length = _netbuf.data_length; /* set the length */ if (length > data_length) length = data_length; // rt_kprintf("data len: %d, read idx %d\n", data_length, read_index); if (data_length > 0) { /* copy buffer */ if (_netbuf.size - read_index > length) { rt_memcpy(buffer, &_netbuf.buffer_data[read_index], length); _netbuf.read_index += length; } else { rt_memcpy(buffer, &_netbuf.buffer_data[read_index], _netbuf.size - read_index); rt_memcpy(&buffer[_netbuf.size - read_index], &_netbuf.buffer_data[0], length - (_netbuf.size - read_index)); _netbuf.read_index = length - (_netbuf.size - read_index); } /* update length of data in buffer */ level = rt_hw_interrupt_disable(); _netbuf.data_length -= length; data_length = _netbuf.data_length; if ((_netbuf.stat == NETBUF_STAT_SUSPEND) && data_length < _netbuf.resume_wm) { _netbuf.stat = NETBUF_STAT_BUFFERING; rt_hw_interrupt_enable(level); /* resume netbuf worker */ // rt_kprintf("stat[suspend] -> buffering\n"); rt_sem_release(_netbuf.wait_resume); } else { rt_hw_interrupt_enable(level); } } return length; }
static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { rt_uint8_t* ptr; rt_err_t err_code; struct serial_device* uart; ptr = buffer; err_code = RT_EOK; uart = (struct serial_device*)dev->user_data; if (ptr == RT_NULL) { err_code = -RT_ENOMEM; rt_set_errno(err_code); return -RT_ENOMEM; } if (dev->flag & RT_DEVICE_FLAG_INT_RX) { rt_base_t level; /* interrupt mode Rx */ while (size) { if (uart->int_rx->read_index != uart->int_rx->save_index) { *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index]; size --; /* disable interrupt */ level = rt_hw_interrupt_disable(); uart->int_rx->read_index ++; if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) uart->int_rx->read_index = 0; /* enable interrupt */ rt_hw_interrupt_enable(level); } else { /* set error code */ err_code = -RT_EEMPTY; break; } } } else { /* polling mode */ while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) { while (uart->uart_device->ustat & USTAT_RCV_READY) { *ptr = uart->uart_device->urxh & 0xff; ptr ++; } } } /* set error code */ rt_set_errno(err_code); return (rt_uint32_t)ptr - (rt_uint32_t)buffer; }
rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) { const struct pin_index *index; const struct pin_irq_map *irqmap; rt_base_t level; rt_int32_t hdr_index = -1; exti_trig_type_enum trigger_mode; index = get_pin(pin); if (index == RT_NULL) { return RT_EINVAL; } if (enabled == PIN_IRQ_ENABLE) { hdr_index = bit2bitno(index->pin); if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) { return RT_EINVAL; } level = rt_hw_interrupt_disable(); if (pin_irq_hdr_tab[hdr_index].pin == -1) { rt_hw_interrupt_enable(level); return RT_EINVAL; } irqmap = &pin_irq_map[hdr_index]; switch (pin_irq_hdr_tab[hdr_index].mode) { case PIN_IRQ_MODE_RISING: trigger_mode = EXTI_TRIG_RISING; break; case PIN_IRQ_MODE_FALLING: trigger_mode = EXTI_TRIG_FALLING; break; case PIN_IRQ_MODE_RISING_FALLING: trigger_mode = EXTI_TRIG_BOTH; break; default: rt_hw_interrupt_enable(level); return RT_EINVAL; } //rcu_periph_clock_enable(RCU_AF); /* enable and set interrupt priority */ nvic_irq_enable(irqmap->irqno, 5U); /* connect EXTI line to GPIO pin */ syscfg_exti_line_config(index->port_src, index->pin_src); /* configure EXTI line */ exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode); exti_interrupt_flag_clear((exti_line_enum)(index->pin)); rt_hw_interrupt_enable(level); } else if (enabled == PIN_IRQ_DISABLE) { irqmap = get_pin_irq_map(index->pin); if (irqmap == RT_NULL) { return RT_EINVAL; } nvic_irq_disable(irqmap->irqno); } else { return RT_EINVAL; } return RT_EOK; }
/** * This function will take a mutex, if the mutex is unavailable, the * thread shall wait for a specified time. * * @param mutex the mutex object * @param time the waiting time * * @return the error code */ rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time) { register rt_base_t temp; struct rt_thread *thread; /* this function must not be used in interrupt even if time = 0 */ RT_DEBUG_NOT_IN_INTERRUPT; RT_ASSERT(mutex != RT_NULL); /* disable interrupt */ temp = rt_hw_interrupt_disable(); /* get current thread */ thread = rt_thread_self(); RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mutex->parent.parent))); RT_DEBUG_LOG(RT_DEBUG_IPC, ("mutex_take: current thread %s, mutex value: %d, hold: %d\n", thread->name, mutex->value, mutex->hold)); /* reset thread error */ thread->error = RT_EOK; if (mutex->owner == thread) { /* it's the same thread */ mutex->hold ++; } else { /* in initialization status, the value is 1. Therefore, if the * value is great than 1, which indicates the mutex is avaible. */ if (mutex->value > 0) { /* mutex is available */ mutex->value --; /* set mutex owner and original priority */ mutex->owner = thread; mutex->original_priority = thread->current_priority; mutex->hold ++; } else { /* no waiting, return with timeout */ if (time == 0) { /* set error as timeout */ thread->error = -RT_ETIMEOUT; /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_ETIMEOUT; } else { /* mutex is unavailable, push to suspend list */ RT_DEBUG_LOG(RT_DEBUG_IPC, ("mutex_take: suspend thread: %s\n", thread->name)); /* change the owner thread priority of mutex */ if (thread->current_priority < mutex->owner->current_priority) { /* change the owner thread priority */ rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY, &thread->current_priority); } /* suspend current thread */ rt_ipc_list_suspend(&(mutex->parent.suspend_thread), thread, mutex->parent.parent.flag); /* has waiting time, start thread timer */ if (time > 0) { RT_DEBUG_LOG(RT_DEBUG_IPC, ("mutex_take: start the timer of thread:%s\n", thread->name)); /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(temp); /* do schedule */ rt_schedule(); if (thread->error != RT_EOK) { /* return error */ return thread->error; } else { /* the mutex is taken successfully. */ /* disable interrupt */ temp = rt_hw_interrupt_disable(); } } } } /* enable interrupt */ rt_hw_interrupt_enable(temp); RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mutex->parent.parent))); return RT_EOK; }
rt_err_t es32f0_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) { const struct pin_index *index; const struct pin_irq_map *irqmap; rt_base_t level; rt_int32_t irqindex = -1; /*Configure GPIO_InitStructure & EXTI_InitStructure*/ gpio_init_t gpio_initstruct; exti_init_t exti_initstruct; exti_initstruct.filter = DISABLE; exti_initstruct.cks = EXTI_FILTER_CLOCK_10K; exti_initstruct.filter_time = 0x0; index = get_pin(pin); if (index == RT_NULL) { return RT_ENOSYS; } if (enabled == PIN_IRQ_ENABLE) { /**pin no. convert to dec no.**/ for (irqindex = 0; irqindex < 16; irqindex++) { if ((0x01 << irqindex) == index->pin) { break; } } if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) { return RT_ENOSYS; } level = rt_hw_interrupt_disable(); if (pin_irq_hdr_tab[irqindex].pin == -1) { rt_hw_interrupt_enable(level); return RT_ENOSYS; } irqmap = &pin_irq_map[irqindex]; gpio_exti_init(index->gpio, index->pin, &exti_initstruct); /* Configure GPIO_InitStructure */ gpio_initstruct.mode = GPIO_MODE_INPUT; gpio_initstruct.func = GPIO_FUNC_1; switch (pin_irq_hdr_tab[irqindex].mode) { case PIN_IRQ_MODE_RISING: gpio_initstruct.pupd = GPIO_PUSH_DOWN; gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_RISING_EDGE, ENABLE); break; case PIN_IRQ_MODE_FALLING: gpio_initstruct.pupd = GPIO_PUSH_UP; gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_TRAILING_EDGE, ENABLE); break; case PIN_IRQ_MODE_RISING_FALLING: gpio_initstruct.pupd = GPIO_FLOATING; gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_BOTH_EDGE, ENABLE); break; } gpio_init(index->gpio, index->pin, &gpio_initstruct); NVIC_EnableIRQ(irqmap->irqno); rt_hw_interrupt_enable(level); } else if (enabled == PIN_IRQ_DISABLE) { irqmap = get_pin_irq_map(index->pin); if (irqmap == RT_NULL) { return RT_ENOSYS; } NVIC_DisableIRQ(irqmap->irqno); } else { return RT_ENOSYS; } return RT_EOK; }
/***************************************************************************//** * @brief * Read from IIC device * * @details * * @note * * @param[in] dev * Pointer to device descriptor * * @param[in] pos * Slave address * * @param[in] buffer * Poniter to the buffer * * @param[in] size * Buffer size in byte * * @return * Error code ******************************************************************************/ static rt_size_t rt_iic_read ( rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { rt_err_t err_code; rt_size_t read_size; struct efm32_iic_device_t* iic; I2C_TransferSeq_TypeDef seq; I2C_TransferReturn_TypeDef ret; if (!size) { return 0; } err_code = RT_EOK; read_size = 0; iic = (struct efm32_iic_device_t*)dev->user_data; /* Lock device */ if (rt_hw_interrupt_check()) { ret = rt_sem_take(iic->lock, RT_WAITING_NO); } else { ret = rt_sem_take(iic->lock, RT_WAITING_FOREVER); } if (ret != RT_EOK) { return ret; } if (iic->state & IIC_STATE_MASTER) { seq.addr = (rt_uint16_t)pos << 1; if (*(rt_uint8_t *)buffer == IIC_OP_READ_ONLY) { seq.flags = I2C_FLAG_READ; /* Set read buffer pointer and size */ seq.buf[0].data = (rt_uint8_t *)buffer; seq.buf[0].len = size; } else { seq.flags = I2C_FLAG_WRITE_READ; /* Set register to be read */ seq.buf[0].data = (rt_uint8_t *)buffer; seq.buf[0].len = 1; /* Set read buffer pointer and size */ seq.buf[1].data = (rt_uint8_t *)buffer; seq.buf[1].len = size; } /* Do a polled transfer */ iic->timeout = false; rt_timer_stop(iic->timer); rt_timer_start(iic->timer); ret = I2C_TransferInit(iic->iic_device, &seq); while ((ret == i2cTransferInProgress) && !iic->timeout) { ret = I2C_Transfer(iic->iic_device); } if (ret != i2cTransferDone) { iic_debug("IIC: read error %x\n", ret); iic_debug("IIC: read address %x\n", seq.addr); iic_debug("IIC: read data0 %x -> %x\n", seq.buf[0].data, *seq.buf[0].data); iic_debug("IIC: read len0 %x\n", seq.buf[0].len); iic_debug("IIC: read data1 %x -> %x\n", seq.buf[1].data, *seq.buf[1].data); iic_debug("IIC: read len1 %x\n", seq.buf[1].len); err_code = (rt_err_t)ret; } else { read_size = size; iic_debug("IIC: read size %d\n", read_size); } } else { rt_uint8_t* ptr; ptr = buffer; /* interrupt mode Rx */ while (size) { rt_base_t level; struct efm32_iic_int_mode_t *int_rx; int_rx = iic->rx_buffer; /* disable interrupt */ level = rt_hw_interrupt_disable(); if (int_rx->read_index != int_rx->save_index) { /* read a character */ *ptr++ = int_rx->data_ptr[int_rx->read_index]; size--; /* move to next position */ int_rx->read_index ++; if (int_rx->read_index >= IIC_RX_BUFFER_SIZE) { int_rx->read_index = 0; } } else { /* set error code */ err_code = -RT_EEMPTY; /* enable interrupt */ rt_hw_interrupt_enable(level); break; } /* enable interrupt */ rt_hw_interrupt_enable(level); } read_size = (rt_uint32_t)ptr - (rt_uint32_t)buffer; iic_debug("IIC: slave read size %d\n", read_size); } /* Unlock device */ rt_sem_release(iic->lock); /* set error code */ rt_set_errno(err_code); return read_size; }
/** * This function will perform one schedule. It will select one thread * with the highest priority level, then switch to it. */ void rt_schedule(void) { rt_base_t level; struct rt_thread *to_thread; struct rt_thread *from_thread; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* check the scheduler is enabled or not */ if (rt_scheduler_lock_nest == 0) { register rt_ubase_t highest_ready_priority; #if RT_THREAD_PRIORITY_MAX <= 32 highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1; #else register rt_ubase_t number; number = __rt_ffs(rt_thread_ready_priority_group) - 1; highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1; #endif /* get switch to thread */ to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next, struct rt_thread, tlist); /* if the destination thread is not the same as current thread */ if (to_thread != rt_current_thread) { rt_current_priority = (rt_uint8_t)highest_ready_priority; from_thread = rt_current_thread; rt_current_thread = to_thread; RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (from_thread, to_thread)); /* switch to new thread */ RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("[%d]switch to priority#%d " "thread:%.*s(sp:0x%p), " "from thread:%.*s(sp: 0x%p)\n", rt_interrupt_nest, highest_ready_priority, RT_NAME_MAX, to_thread->name, to_thread->sp, RT_NAME_MAX, from_thread->name, from_thread->sp)); #ifdef RT_USING_OVERFLOW_CHECK _rt_scheduler_stack_check(to_thread); #endif if (rt_interrupt_nest == 0) { extern void rt_thread_handle_sig(rt_bool_t clean_state); rt_hw_context_switch((rt_uint32_t)&from_thread->sp, (rt_uint32_t)&to_thread->sp); /* enable interrupt */ rt_hw_interrupt_enable(level); #ifdef RT_USING_SIGNALS /* check signal status */ rt_thread_handle_sig(RT_TRUE); #endif } else { RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interrupt\n")); rt_hw_context_switch_interrupt((rt_uint32_t)&from_thread->sp, (rt_uint32_t)&to_thread->sp); /* enable interrupt */ rt_hw_interrupt_enable(level); } } else { /* enable interrupt */ rt_hw_interrupt_enable(level); } } else {
/* ISR for serial interrupt */ void rt_hw_serial_isr(struct rt_serial_device *serial, int event) { switch (event & 0xff) { case RT_SERIAL_EVENT_RX_IND: { int ch = -1; rt_base_t level; struct rt_serial_rx_fifo* rx_fifo; /* interrupt mode receive */ rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx; RT_ASSERT(rx_fifo != RT_NULL); while (1) { ch = serial->ops->getc(serial); if (ch == -1) break; /* disable interrupt */ level = rt_hw_interrupt_disable(); rx_fifo->buffer[rx_fifo->put_index] = ch; rx_fifo->put_index += 1; if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0; /* if the next position is read index, discard this 'read char' */ if (rx_fifo->put_index == rx_fifo->get_index) { rx_fifo->get_index += 1; if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0; } /* enable interrupt */ rt_hw_interrupt_enable(level); } /* invoke callback */ if (serial->parent.rx_indicate != RT_NULL) { rt_size_t rx_length; /* get rx length */ level = rt_hw_interrupt_disable(); rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index): (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index)); rt_hw_interrupt_enable(level); serial->parent.rx_indicate(&serial->parent, rx_length); } break; } case RT_SERIAL_EVENT_TX_DONE: { struct rt_serial_tx_fifo* tx_fifo; tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx; rt_completion_done(&(tx_fifo->completion)); break; } case RT_SERIAL_EVENT_TX_DMADONE: { const void *data_ptr; rt_size_t data_size; const void *last_data_ptr; struct rt_serial_tx_dma* tx_dma; tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx; rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0); if (rt_data_queue_peak(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK) { /* transmit next data node */ tx_dma->activated = RT_TRUE; serial->ops->dma_transmit(serial, data_ptr, data_size, RT_SERIAL_DMA_TX); } else { tx_dma->activated = RT_FALSE; } /* invoke callback */ if (serial->parent.tx_complete != RT_NULL) { serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr); } break; } case RT_SERIAL_EVENT_RX_DMADONE: { int length; struct rt_serial_rx_dma* rx_dma; rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx; /* get DMA rx length */ length = (event & (~0xff)) >> 8; serial->parent.rx_indicate(&(serial->parent), length); rx_dma->activated = RT_FALSE; break; } } }
/* ISR for serial interrupt */ void rt_hw_serial_isr(rt_device_t device) { struct stm32_serial_device* uart = (struct stm32_serial_device*) device->user_data; static unsigned char checksum = 0; static uint16_t lenth; // static unsigned char gprmcbuf[400]; static unsigned char isgprmc=0; static unsigned short gprmccnt = 0; if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET) { /* interrupt mode receive */ RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX); /* save on rx buffer */ while (uart->uart_device->SR & USART_FLAG_RXNE) { rt_base_t level; /* disable interrupt */ level = rt_hw_interrupt_disable(); /* save character */ if((&uart2_device )== device) { uartcount++; uart->int_rx->rx_buffer[uart->int_rx->save_index] = uart->uart_device->DR & 0xff; rt_device_write(&uart2_device, 0,&(uart->int_rx->rx_buffer[uart->int_rx->save_index]), 1); checksum = checksum^(uart->int_rx->rx_buffer[uart->int_rx->save_index]); switch (Uart2PackStatus ) { case Get_sync_head: if ((uart->int_rx->rx_buffer[uart->int_rx->save_index])== 0xaa) { checksum = uart->int_rx->rx_buffer[uart->int_rx->save_index]; Uart2PackStatus = Start_head_end; } else { uart->int_rx->getcmd = 0x7f; } break; case Start_head_end: if((uart->int_rx->rx_buffer[uart->int_rx->save_index])== 0x75) { Uart2PackStatus = Get_the_Command; //rt_device_write(&uart2_device, 0,&(uart->int_rx->rx_buffer[uart->int_rx->save_index]), 1); } else { uart->int_rx->getcmd = 0x7f; Uart2PackStatus = Get_sync_head; } break; case Get_the_Command: if(((uart->int_rx->rx_buffer[uart->int_rx->save_index]) <0x16) ||((uart->int_rx->rx_buffer[uart->int_rx->save_index])>0x81 &&(uart->int_rx->rx_buffer[uart->int_rx->save_index])<0x85 ) ||((uart->int_rx->rx_buffer[uart->int_rx->save_index])>0x81 &&(uart->int_rx->rx_buffer[uart->int_rx->save_index])<0x85 ) ||((uart->int_rx->rx_buffer[uart->int_rx->save_index])>0xc1 &&(uart->int_rx->rx_buffer[uart->int_rx->save_index])<0xc5 )) { Uart2PackStatus = Get_the_lenth_high; } else { uart->int_rx->getcmd = 0x7f; Uart2PackStatus = Get_sync_head; } break; case Get_the_lenth_high: lenth = uart->int_rx->rx_buffer[uart->int_rx->save_index]; Uart2PackStatus = Get_the_lenth_low; break; case Get_the_lenth_low: lenth = ((lenth<<8)&0xff00)+(uart->int_rx->rx_buffer[uart->int_rx->save_index]); Uart2PackStatus = Get_the_reserve; break; case Get_the_reserve: if (lenth != 0) { Uart2PackStatus = Get_the_data; } else Uart2PackStatus = Get_the_checksum; break; case Get_the_data: if(lenth ) lenth--; if(lenth == 0) Uart2PackStatus = Get_the_checksum; break; case Get_the_checksum: if(checksum == 0) { uart->int_rx->getcmd ++; } else { uart->int_rx->getcmd = 0x7f; } Uart2PackStatus = Get_sync_head; break; default: break; } uart->int_rx->save_index ++; if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE) uart->int_rx->save_index = 0; /* if the next position is read index, discard this 'read char' */ if (uart->int_rx->save_index == uart->int_rx->read_index) { uart->int_rx->read_index ++; if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) uart->int_rx->read_index = 0; } } if((&uart3_device)== device) { if((uart->uart_device->DR & 0xff) == '$') { SectionID=0; isgprmc = 0; gprmccnt =0; uart3flag =1; } else if((uart->uart_device->DR & 0xff)==',') { if((isgprmc == 1)&&(SectionID== FIELD_NIGHT)) { //get the time GetGPSLocation3(gprmcbuf,gprmccnt); } else if((isgprmc == 2) &&(SectionID == FIELD_SEVEN )) { GetGPSSpeed(gprmcbuf,gprmccnt); } SectionID++; gprmccnt = 0; uart3flag =2; } else { if(gprmccnt == 400) { gprmccnt = 0; } gprmcbuf[gprmccnt] = uart->uart_device->DR & 0xff; gprmccnt++; switch(SectionID) { case FIELD_NONE: if(gprmccnt == 5) { uart3flag =2; gprmccnt =0 ; if ( (gprmcbuf[0] == 'G') &&(gprmcbuf[1] == 'P')&&(gprmcbuf[2] =='G') &&(gprmcbuf[3] =='G')&&(gprmcbuf[4] == 'A')) { isgprmc =1;//位置信息 } if ( (gprmcbuf[0] == 'G') &&(gprmcbuf[1] == 'P')&&(gprmcbuf[2] =='V') &&(gprmcbuf[3] == 'T')&&(gprmcbuf[4] == 'G')) { isgprmc =2;//速度信息 uart3flag =2; } } break; case FIELD_ONE://提取时间 uart3flag =1; if(isgprmc == 1) { if(gprmccnt == 10 ) { //get the time GetTheGPSTime(gprmcbuf); } } break; case FIELD_TWO: //判断数据是否可信(当GPS天线能接收到有3颗GPS卫星时为A,可信 if(isgprmc == 1) { if(gprmccnt == 9 ) { //get the time GetGPSLocation1(gprmcbuf); } } break; case FIELD_THREE://提取出纬度 break; case FIELD_FOUR://提取出速度 if(isgprmc == 1) { if(gprmccnt == 10 ) { //get the time GetGPSLocation2(gprmcbuf); } } break; case FIELD_FIVE://提取出经度 break; case FIELD_SEVEN: if(isgprmc == 1) { if(gprmccnt == 2 ) { //get the singal GettheSinaldata(gprmcbuf); } } break; case FIELD_NIGHT://提取高度 break; default: break; } } } if((&uart4_device )== device) { gprmcbuf[gprmccnt] = uart->uart_device->DR & 0xff; gprmccnt++; } /* enable interrupt */ rt_hw_interrupt_enable(level); } /* clear interrupt */ USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE); /* invoke callback */ if (device->rx_indicate != RT_NULL) { rt_size_t rx_length; /* get rx length */ rx_length = uart->int_rx->read_index > uart->int_rx->save_index ? UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index : uart->int_rx->save_index - uart->int_rx->read_index; device->rx_indicate(device, rx_length); } } if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET) { /* clear interrupt */ USART_ClearITPendingBit(uart->uart_device, USART_IT_TC); } }
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) { rt_uint8_t* ptr; rt_err_t err_code; struct stm32_serial_device* uart; err_code = RT_EOK; ptr = (rt_uint8_t*)buffer; uart = (struct stm32_serial_device*)dev->user_data; if (dev->flag & RT_DEVICE_FLAG_INT_TX) { /* interrupt mode Tx, does not support */ RT_ASSERT(0); } else if (dev->flag & RT_DEVICE_FLAG_DMA_TX) { /* DMA mode Tx */ /* allocate a data node */ struct stm32_serial_data_node* data_node = (struct stm32_serial_data_node*) rt_mp_alloc (&(uart->dma_tx->data_node_mp), RT_WAITING_FOREVER); if (data_node == RT_NULL) { /* set error code */ err_code = -RT_ENOMEM; } else { rt_uint32_t level; /* fill data node */ data_node->data_ptr = ptr; data_node->data_size = size; /* insert to data link */ data_node->next = RT_NULL; /* disable interrupt */ level = rt_hw_interrupt_disable(); data_node->prev = uart->dma_tx->list_tail; if (uart->dma_tx->list_tail != RT_NULL) uart->dma_tx->list_tail->next = data_node; uart->dma_tx->list_tail = data_node; if (uart->dma_tx->list_head == RT_NULL) { /* start DMA to transmit data */ uart->dma_tx->list_head = data_node; /* Enable DMA Channel */ rt_serial_enable_dma(uart->dma_tx->dma_channel, (rt_uint32_t)uart->dma_tx->list_head->data_ptr, uart->dma_tx->list_head->data_size); } /* enable interrupt */ rt_hw_interrupt_enable(level); } } else { /* polling mode */ if (dev->flag & RT_DEVICE_FLAG_STREAM) { /* stream mode */ while (size) { if (*ptr == '\n') { while (!(uart->uart_device->SR & USART_FLAG_TXE)); uart->uart_device->DR = '\r'; } while (!(uart->uart_device->SR & USART_FLAG_TXE)); uart->uart_device->DR = (*ptr & 0x1FF); ++ptr; --size; } } else { /* write data directly */ while (size) { while (!(uart->uart_device->SR & USART_FLAG_TXE)); uart->uart_device->DR = (*ptr & 0x1FF); ++ptr; --size; } } } /* set error code */ rt_set_errno(err_code); return (rt_uint32_t)ptr - (rt_uint32_t)buffer; }
rt_err_t rt_completion_wait(struct rt_completion *completion, rt_int32_t timeout) { rt_err_t result; rt_base_t level; rt_thread_t thread; RT_ASSERT(completion != RT_NULL); result = RT_EOK; thread = rt_thread_self(); level = rt_hw_interrupt_disable(); if (completion->flag != RT_COMPLETED) { /* only one thread can suspend on complete */ RT_ASSERT(rt_list_isempty(&(completion->suspended_list))); if (timeout == 0) { result = -RT_ETIMEOUT; goto __exit; } else { /* reset thread error number */ thread->error = RT_EOK; /* suspend thread */ rt_thread_suspend(thread); /* add to suspended list */ rt_list_insert_before(&(completion->suspended_list), &(thread->tlist)); /* current context checking */ RT_DEBUG_NOT_IN_INTERRUPT; /* start timer */ if (timeout > 0) { /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(level); /* do schedule */ rt_schedule(); /* thread is waked up */ result = thread->error; level = rt_hw_interrupt_disable(); /* clean completed flag */ completion->flag = RT_UNCOMPLETED; } } __exit: rt_hw_interrupt_enable(level); return result; }