示例#1
0
文件: dfs_posix.c 项目: wuliaodew/RTT
/**
 * this function is a POSIX compliant version, which will open a file and return
 * a file descriptor.
 *
 * @param file the path name of file.
 * @param flags the file open flags.
 * @param mode
 *
 * @return the non-negative integer on successful open, others for failed.
 */
int open(const char *file, int flags, int mode)
{
	int fd, result;
	struct dfs_fd *d;

	/* allocate a fd */
	fd = fd_new();
	if (fd < 0)
	{
		rt_set_errno(-DFS_STATUS_ENOMEM);
		return -1;
	}
	d  = fd_get(fd);

	result = dfs_file_open(d, file, flags);
	if (result < 0)
	{
		/* release the ref-count of fd */
		fd_put(d);
		fd_put(d);
		
		rt_set_errno(result);

		return -1;
	}

	/* release the ref-count of fd */
	fd_put(d);
	return fd;
}
示例#2
0
/*
+------------------------------------------------------------------------------
| Function    : write
+------------------------------------------------------------------------------
| Description :
|
| Parameters  :
| Returns     :
|
+------------------------------------------------------------------------------
*/
int write(int fd, char *buf, int   len)
{
	int result;
	struct dfs_fd* d;

	/* get the fd */
	d  = fd_get(fd);
	if (d == RT_NULL)
	{
		rt_set_errno(-RT_ERROR);
		return -1;
	}

	result = dfile_raw_write(d, buf, len);
	if (result < 0)
	{
		rt_set_errno(result);
		fd_put(d);

		return -1;
	}

	/* release the ref-count of fd */
	fd_put(d);
	return result;
}
示例#3
0
/**
 * this function is a POSIX compliant version, which will close the open
 * file descriptor.
 *
 * @param fd the file descriptor.
 *
 * @return 0 on successful, -1 on failed.
 */
int close(int fd)
{
    int result;
    struct dfs_fd *d;

    d = fd_get(fd);
    if (d == RT_NULL)
    {
        rt_set_errno(-DFS_STATUS_EBADF);

        return -1;
    }

    result = dfs_file_close(d);
    fd_put(d);

    if (result < 0)
    {
        rt_set_errno(result);

        return -1;
    }

    fd_put(d);

    return 0;
}
rt_size_t rt_spi_transfer(struct rt_spi_device *device,
                          const void           *send_buf,
                          void                 *recv_buf,
                          rt_size_t             length)
{
    rt_err_t result;
    struct rt_spi_message message;

    RT_ASSERT(device != RT_NULL);
    RT_ASSERT(device->bus != RT_NULL);

    result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
    if (result == RT_EOK)
    {
        if (device->bus->owner != device)
        {
            /* not the same owner as current, re-configure SPI bus */
            result = device->bus->ops->configure(device, &device->config);
            if (result == RT_EOK)
            {
                /* set SPI bus owner */
                device->bus->owner = device;
            }
            else
            {
                /* configure SPI bus failed */
                rt_set_errno(-RT_EIO);
                result = 0;
                goto __exit;
            }
        }

        /* initial message */
        message.send_buf   = send_buf;
        message.recv_buf   = recv_buf;
        message.length     = length;
        message.cs_take    = 1;
        message.cs_release = 1;
        message.next       = RT_NULL;

        /* transfer message */
        result = device->bus->ops->xfer(device, &message);
        if (result == 0)
        {
            rt_set_errno(-RT_EIO);
            goto __exit;
        }
    }
    else
    {
        rt_set_errno(-RT_EIO);

        return 0;
    }

__exit:
    rt_mutex_release(&(device->bus->lock));

    return result;
}
/**
 * this function is a POSIX compliant version, which will read specified data buffer 
 * length for an open file descriptor.
 * 
 * @param fd the file descriptor.
 * @param buf the buffer to save the read data.
 * @param len the maximal length of data buffer
 *
 * @return the actual read data buffer length
 */
int read(int fd, void *buf, size_t len)
{
	int result;
	struct dfs_fd *d;

	/* get the fd */
	d  = fd_get(fd);
	if (d == RT_NULL)
	{
		rt_set_errno(-RT_ERROR);
		return -1;
	}

	result = dfs_file_read(d, buf, len);
	if (result < 0)
	{
		fd_put(d);
		rt_set_errno(result);

		return -1;
	}

	/* release the ref-count of fd */
	fd_put(d);
	return result;
}
示例#6
0
文件: dfs_posix.c 项目: wuliaodew/RTT
/**
 * this function is a POSIX compliant version, which will write specified data buffer
 * length for an open file descriptor.
 *
 * @param fd the file descriptor
 * @param buf the data buffer to be written.
 * @param len the data buffer length.
 *
 * @return the actual written data buffer length.
 */
int write(int fd, const void *buf, size_t len)
{
	int result;
	struct dfs_fd *d;

	/* get the fd */
	d  = fd_get(fd);
	if (d == RT_NULL)
	{
		rt_set_errno(-DFS_STATUS_EBADF);
		return -1;
	}

	result = dfs_file_write(d, buf, len);
	if (result < 0)
	{
		fd_put(d);
		rt_set_errno(result);

		return -1;
	}

	/* release the ref-count of fd */
	fd_put(d);
	return result;
}
示例#7
0
/**
 * this function is a POSIX compliant version, which will seek the offset for
 * an open file descriptor.
 *
 * @param fd the file descriptor.
 * @param offset the offset to be seeked.
 * @param whence the directory of seek.
 *
 * @return the current file position, or -1 on failed.
 */
off_t lseek(int fd, off_t offset, int whence)
{
    int result;
    struct dfs_fd *d;

    d = fd_get(fd);
    if (d == RT_NULL)
    {
        rt_set_errno(-DFS_STATUS_EBADF);

        return -1;
    }

    switch (whence)
    {
    case DFS_SEEK_SET:
        break;

    case DFS_SEEK_CUR:
        offset += d->pos;
        break;

    case DFS_SEEK_END:
        offset += d->size;
        break;

    default:
        rt_set_errno(-DFS_STATUS_EINVAL);

        return -1;
    }

    if (offset < 0)
    {
        rt_set_errno(-DFS_STATUS_EINVAL);

        return -1;
    }
    result = dfs_file_lseek(d, offset);
    if (result < 0)
    {
        fd_put(d);
        rt_set_errno(result);

        return -1;
    }

    /* release the ref-count of fd */
    fd_put(d);

    return offset;
}
static rt_size_t _write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
    rt_err_t err;
    struct rt_vbus_dev *vdev = dev->user_data;

    RT_ASSERT(vdev->chnr != 0);

    if (rt_interrupt_get_nest() == 0)
    {
        /* Thread context. */
        err = rt_vbus_post(vdev->chnr, vdev->req.prio,
                           buffer, size, RT_WAITING_FOREVER);
    }
    else
    {
        /* Interrupt context. */
        err = rt_vbus_post(vdev->chnr, vdev->req.prio,
                           buffer, size, 0);
    }

    if (err)
    {
        rt_set_errno(err);
        return 0;
    }

    return size;
}
示例#9
0
int clock_settime (clockid_t clockid, const struct timespec *tp)
{
	int second;
	rt_tick_t tick;
	rt_device_t device;

	if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL)) {
		rt_set_errno(EINVAL);
		return -1;
	}

	/* get second */
	second = tp->tv_sec;
	/* get tick */
	tick = rt_tick_get();

	/* update timevalue */
	_timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
	_timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1;

	/* update for RTC device */
	device = rt_device_find("rtc");
	if (device != RT_NULL) {
		/* set realtime seconds */
		rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second);
	} else return -1;

	return 0;
}
rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
{
    rt_base_t level;
    rt_err_t result;
    struct rt_serial_tx_dma *tx_dma;

    tx_dma = (struct rt_serial_tx_dma*)(serial->serial_tx);
    
    result = rt_data_queue_push(&(tx_dma->data_queue), data, length, RT_WAITING_FOREVER); 
    if (result == RT_EOK)
    {
        level = rt_hw_interrupt_disable();
        if (tx_dma->activated != RT_TRUE)
        {
            tx_dma->activated = RT_TRUE;
            rt_hw_interrupt_enable(level);

            /* make a DMA transfer */
            serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_TX);
        }
        else
        {
            rt_hw_interrupt_enable(level);
        }

        return length;
    }
    else
    {
        rt_set_errno(result);
        return 0;
    }
}
示例#11
0
rt_err_t rt_spi_take_bus(struct rt_spi_device *device)
{
    rt_err_t result = RT_EOK;

    RT_ASSERT(device != RT_NULL);
    RT_ASSERT(device->bus != RT_NULL);

    result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
    if (result != RT_EOK)
    {
        rt_set_errno(-RT_EBUSY);

        return -RT_EBUSY;
    }

    /* reset errno */
    rt_set_errno(RT_EOK);

    /* configure SPI bus */
    if (device->bus->owner != device)
    {
        /* not the same owner as current, re-configure SPI bus */
        result = device->bus->ops->configure(device, &device->config);
        if (result == RT_EOK)
        {
            /* set SPI bus owner */
            device->bus->owner = device;
        }
        else
        {
            /* configure SPI bus failed */
            rt_set_errno(-RT_EIO);
            /* release lock */
            rt_mutex_release(&(device->bus->lock));

            return -RT_EIO;
        }
    }

    return result;
}
示例#12
0
static rt_size_t rt_serial_read(struct rt_device *dev,
                                rt_off_t          pos,
                                void             *buffer,
                                rt_size_t         size)
{
    rt_uint8_t *ptr;
    rt_uint32_t read_nbytes;
    struct rt_serial_device *serial;

    RT_ASSERT(dev != RT_NULL);

    if (size == 0)
        return 0;

    serial = (struct rt_serial_device *)dev;

    ptr = (rt_uint8_t *)buffer;

    if (dev->flag & RT_DEVICE_FLAG_INT_RX)
    {
        /* interrupt mode Rx */
        while (size)
        {
            int ch;

            ch = serial_ringbuffer_getc(serial->int_rx);
            if (ch == -1)
                break;

            *ptr = ch & 0xff;
            ptr ++;
            size --;
        }
    }
    else
    {
        /* polling mode */
        while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
        {
            *ptr = serial->ops->getc(serial);
            ptr ++;
        }
    }

    read_nbytes = (rt_uint32_t)ptr - (rt_uint32_t)buffer;
    /* set error code */
    if (read_nbytes == 0)
    {
        rt_set_errno(-RT_EEMPTY);
    }

    return read_nbytes;
}
示例#13
0
int clock_getres  (clockid_t clockid, struct timespec *res)
{
	if ((clockid != CLOCK_REALTIME) || (res == RT_NULL)) {
		rt_set_errno(EINVAL);
		return -1;
	}

	res->tv_sec = 0;
	res->tv_nsec = NANOSECOND_PER_SECOND/RT_TICK_PER_SECOND;

	return 0;
}
示例#14
0
static rt_size_t codec_write(rt_device_t dev, rt_off_t pos,
                             const void* buffer, rt_size_t size)
{
    struct codec_device* device;
    struct codec_data_node* node;
    rt_uint32_t level;
    rt_uint16_t next_index;

    device = (struct codec_device*) dev;
    RT_ASSERT(device != RT_NULL);

    next_index = device->put_index + 1;
    if (next_index >= DATA_NODE_MAX)
        next_index = 0;

    /* check data_list full */
    if (next_index == device->read_index)
    {
        rt_set_errno(-RT_EFULL);
        return 0;
    }

    level = rt_hw_interrupt_disable();
    node = &device->data_list[device->put_index];
    device->put_index = next_index;

    /* set node attribute */
    node->data_ptr = (rt_uint16_t*) buffer;
    node->data_size = size >> 1; /* size is byte unit, convert to half word unit */

    next_index = device->read_index + 1;
    if (next_index >= DATA_NODE_MAX)
        next_index = 0;

    /* check data list whether is empty */
    if (next_index == device->put_index)
    {
        DMA_Configuration((rt_uint32_t) node->data_ptr, node->data_size);

#if CODEC_MASTER_MODE
        if ((r06 & MS) == 0)
        {
            CODEC_I2S_PORT->I2SCFGR |= SPI_I2SCFGR_I2SE;
            r06 |= MS;
            codec_send(r06);
        }
#endif
    }
    rt_hw_interrupt_enable(level);

    return size;
}
示例#15
0
/*
+------------------------------------------------------------------------------
| Function    : lseek
+------------------------------------------------------------------------------
| Description :
|
| Parameters  :
| Returns     :
|
+------------------------------------------------------------------------------
*/
int lseek(int fd, int offset, int dir)
{
	int result;
	struct dfs_fd* d;

	d  = fd_get(fd);
	if (d == RT_NULL)
	{
		rt_set_errno(-RT_ERROR);
		return -1;
	}

	switch (dir)
	{
	case DFS_SEEK_SET:
		break;

	case DFS_SEEK_CUR:
		offset += d->pos;
		break;

	case DFS_SEEK_END:
		offset += d->size;
		break;
	}

	result = dfile_raw_lseek(d, offset);
	if (result < 0)
	{
		rt_set_errno(result);
		fd_put(d);
		return -1;
	}

	/* release the ref-count of fd */
	fd_put(d);
	return offset;
}
示例#16
0
/*
+------------------------------------------------------------------------------
| Function    : close
+------------------------------------------------------------------------------
| Description :
|
| Parameters  :
| Returns     :
|
+------------------------------------------------------------------------------
*/
int close(int fd)
{
	int result;
	struct dfs_fd* d;

	d = fd_get(fd);
	if (d == RT_NULL)
	{
		rt_set_errno(-RT_ERROR);
		return -1;
	}

	result = dfile_raw_close(d);
	fd_put(d);
	fd_put(d);

	if (result < 0)
	{
		rt_set_errno(result);
		return -1;
	}
	return 0;
}
示例#17
0
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 * serial = SERIAL_DEVICE(dev);

    ptr = buffer;
    err_code = RT_EOK;

    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 (serial->serial_rx.read_index != serial->serial_rx.save_index)
            {
                /* read a character */
                *ptr++ = serial->serial_rx.rx_buffer[serial->serial_rx.read_index];
                size--;

                /* move to next position */
                serial->serial_rx.read_index ++;
                if (serial->serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
                    serial->serial_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);
        }
    }


    /* set error code */
    rt_set_errno(err_code);
    return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
示例#18
0
文件: device.c 项目: 1847123212/SFUD
/**
 * This function will write some data to a device.
 *
 * @param dev the pointer of device driver structure
 * @param pos the position of written
 * @param buffer the data buffer to be written to device
 * @param size the size of buffer
 *
 * @return the actually written size on successful, otherwise negative returned.
 *
 * @note since 0.4.0, the unit of size/pos is a block for block device.
 */
rt_size_t rt_device_write(rt_device_t dev,
                          rt_off_t    pos,
                          const void *buffer,
                          rt_size_t   size)
{
    RT_ASSERT(dev != RT_NULL);

    if (dev->ref_count == 0)
    {
        rt_set_errno(-RT_ERROR);
        return 0;
    }

    /* call device write interface */
    if (dev->write != RT_NULL)
    {
        return dev->write(dev, pos, buffer, size);
    }

    /* set error code */
    rt_set_errno(-RT_ENOSYS);

    return 0;
}
示例#19
0
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 avr32_serial_device *uart;

    err_code = RT_EOK;
    ptr = (rt_uint8_t *)buffer;
    uart = (struct avr32_serial_device *)dev->user_data;

    if (dev->flag & RT_DEVICE_FLAG_INT_TX)
    {
        /* interrupt mode Tx, does not support */
        RT_ASSERT(0);
    }
    else
    {
        /* polling mode */
        if (dev->flag & RT_DEVICE_FLAG_STREAM)
        {
            /* stream mode */
            while (size)
            {
                usart_putchar(uart->uart_device, (int) *ptr);

                ++ptr;
                --size;
            }
        }
        else
        {
            /* write data directly */
            while (size)
            {
                usart_bw_write_char(uart->uart_device, (int) *ptr);

                ++ptr;
                --size;
            }
        }
    }

    /* set error code */
    rt_set_errno(err_code);

    return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
示例#20
0
int clock_gettime (clockid_t clockid, struct timespec *tp)
{
	rt_tick_t tick;

	if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL)) {
		rt_set_errno(EINVAL);
		return -1;
	}

	/* get tick */
	tick = rt_tick_get();

	tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
	tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * NANOSECOND_PER_TICK) * 1000;

	return 0;
}
示例#21
0
static rt_size_t rt_console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
    rt_uint8_t* ptr = buffer;
    rt_err_t err_code = RT_EOK;

    /* interrupt mode Rx */
    while (size)
    {
        rt_base_t level;

        /* disable interrupt */
        level = rt_hw_interrupt_disable();

        if (read_index != save_index)
        {
            /* read a character */
            *ptr++ = rx_buffer[read_index];
            size--;

            /* move to next position */
            read_index ++;
            if (read_index >= CONSOLE_RX_BUFFER_SIZE)
                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);
    }

    /* set error code */
    rt_set_errno(err_code);
    return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
示例#22
0
文件: sdcard.c 项目: xianjimli/misc
static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
	int i;
	struct dfs_partition *part = (struct dfs_partition *)dev->user_data;

	if ( dev == RT_NULL )
	{
		rt_set_errno(-DFS_STATUS_EINVAL);
		return 0;
	}

	/* read all sectors */
	for (i = 0; i < size; i++)
	{
		rt_sem_take(part->lock, RT_WAITING_FOREVER);
		sd_writeblock((part->offset + i + pos)*SECTOR_SIZE,
			(rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE));
		rt_sem_release(part->lock);
	}

	/* the length of reading must align to SECTOR SIZE */
	return size;
}
示例#23
0
void luminaryif_isr(void)
{
    unsigned long ulTemp;

    //
    // Read and Clear the interrupt.
    //
    ulTemp = EthernetIntStatus(ETH_BASE, false);
    EthernetIntClear(ETH_BASE, ulTemp);

    //
    // Check to see if an RX Interrupt has occured.
    //
    if(ulTemp & ETH_INT_RX)
    {
        //
        // Indicate that a packet has been received.
        //
        rt_err_t result;
		
        /* a frame has been received */
        result = eth_device_ready((struct eth_device*)&(luminaryif_dev->parent));

		if(result != RT_EOK) rt_set_errno(-RT_ERROR);

        //
        // Disable Ethernet RX Interrupt.
        //
        EthernetIntDisable(ETH_BASE, ETH_INT_RX);
    }
    if(ulTemp & ETH_INT_TX)
    {
        /* A frame has been transmitted. */
        rt_sem_release(&tx_sem);
    }
	
}
/*
 * Serial DMA routines
 */
rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
{
    rt_base_t level;
    int result = RT_EOK;
    struct rt_serial_rx_dma *rx_dma;

    RT_ASSERT((serial != RT_NULL) && (data != RT_NULL));
    rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
    RT_ASSERT(rx_dma != RT_NULL);

    level = rt_hw_interrupt_disable();
    if (rx_dma->activated != RT_TRUE)
    {
        rx_dma->activated = RT_TRUE;
        serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX);
    }
    else result = -RT_EBUSY;
    rt_hw_interrupt_enable(level);

    if (result == RT_EOK) return length;

    rt_set_errno(result);
    return 0;
}
void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
{
    rt_err_t result;
    rt_size_t oldsize;
    struct rt_memheap_item *header_ptr;
    struct rt_memheap_item *new_ptr;

    if (newsize == 0)
    {
        rt_memheap_free(ptr);

        return RT_NULL;
    }
    /* align allocated size */
    newsize = RT_ALIGN(newsize, RT_ALIGN_SIZE);
    if (newsize < RT_MEMHEAP_MINIALLOC)
        newsize = RT_MEMHEAP_MINIALLOC;

    if (ptr == RT_NULL)
    {
        return rt_memheap_alloc(heap, newsize);
    }

    /* get memory block header and get the size of memory block */
    header_ptr = (struct rt_memheap_item *)
                 ((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);
    oldsize = MEMITEM_SIZE(header_ptr);
     /* re-allocate memory */
    if (newsize > oldsize)
    {
        void* new_ptr;
        struct rt_memheap_item *next_ptr;

        /* lock memheap */
        result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
        if (result != RT_EOK)
        {
            rt_set_errno(result);
            return RT_NULL;
        }

        next_ptr = header_ptr->next;

        /* header_ptr should not be the tail */
        RT_ASSERT(next_ptr > header_ptr);

        /* check whether the following free space is enough to expand */
        if (!RT_MEMHEAP_IS_USED(next_ptr))
        {
            rt_int32_t nextsize;

            nextsize = MEMITEM_SIZE(next_ptr);
            RT_ASSERT(next_ptr > 0);

            /* Here is the ASCII art of the situation that we can make use of
             * the next free node without alloc/memcpy, |*| is the control
             * block:
             *
             *      oldsize           free node
             * |*|-----------|*|----------------------|*|
             *         newsize          >= minialloc
             * |*|----------------|*|-----------------|*|
             */
            if (nextsize + oldsize > newsize + RT_MEMHEAP_MINIALLOC)
            {
                /* decrement the entire free size from the available bytes count. */
                heap->available_size = heap->available_size - (newsize - oldsize);
                if (heap->pool_size - heap->available_size > heap->max_used_size)
                    heap->max_used_size = heap->pool_size - heap->available_size;

                /* remove next_ptr from free list */
                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
                             ("remove block: block[0x%08x], next_free 0x%08x, prev_free 0x%08x",
                              next_ptr,
                              next_ptr->next_free,
                              next_ptr->prev_free));

                next_ptr->next_free->prev_free = next_ptr->prev_free;
                next_ptr->prev_free->next_free = next_ptr->next_free;
                next_ptr->next->prev = next_ptr->prev;
                next_ptr->prev->next = next_ptr->next;

                /* build a new one on the right place */
                next_ptr = (struct rt_memheap_item*)((char*)ptr + newsize);

                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
                             ("new free block: block[0x%08x] nextm[0x%08x] prevm[0x%08x]",
                              next_ptr,
                              next_ptr->next,
                              next_ptr->prev));

                /* mark the new block as a memory block and freed. */
                next_ptr->magic = RT_MEMHEAP_MAGIC;

                /* put the pool pointer into the new block. */
                next_ptr->pool_ptr = heap;

                next_ptr->prev          = header_ptr;
                next_ptr->next          = header_ptr->next;
                header_ptr->next->prev = next_ptr;
                header_ptr->next       = next_ptr;

                /* insert next_ptr to free list */
                next_ptr->next_free = heap->free_list->next_free;
                next_ptr->prev_free = heap->free_list;
                heap->free_list->next_free->prev_free = next_ptr;
                heap->free_list->next_free            = next_ptr;
                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: next_free 0x%08x, prev_free 0x%08x",
                                                next_ptr->next_free,
                                                next_ptr->prev_free));

                /* release lock */
                rt_sem_release(&(heap->lock));

                return ptr;
            }
        }

        /* release lock */
        rt_sem_release(&(heap->lock));

        /* re-allocate a memory block */
        new_ptr = (void*)rt_memheap_alloc(heap, newsize);
        if (new_ptr != RT_NULL)
        {
            rt_memcpy(new_ptr, ptr, oldsize < newsize ? oldsize : newsize);
            rt_memheap_free(ptr);
        }

        return new_ptr;
    }

    /* don't split when there is less than one node space left */
    if (newsize + RT_MEMHEAP_SIZE + RT_MEMHEAP_MINIALLOC >= oldsize)
        return ptr;

    /* lock memheap */
    result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
    if (result != RT_EOK)
    {
        rt_set_errno(result);

        return RT_NULL;
    }

    /* split the block. */
    new_ptr = (struct rt_memheap_item *)
              (((rt_uint8_t *)header_ptr) + newsize + RT_MEMHEAP_SIZE);

    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
                 ("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]\n",
                  header_ptr,
                  header_ptr->next,
                  header_ptr->prev,
                  new_ptr));

    /* mark the new block as a memory block and freed. */
    new_ptr->magic = RT_MEMHEAP_MAGIC;
    /* put the pool pointer into the new block. */
    new_ptr->pool_ptr = heap;

    /* break down the block list */
    new_ptr->prev          = header_ptr;
    new_ptr->next          = header_ptr->next;
    header_ptr->next->prev = new_ptr;
    header_ptr->next       = new_ptr;

    /* determine if the block can be merged with the next neighbor. */
    if (!RT_MEMHEAP_IS_USED(new_ptr->next))
    {
        struct rt_memheap_item *free_ptr;

        /* merge block with next neighbor. */
        free_ptr = new_ptr->next;
        heap->available_size = heap->available_size - MEMITEM_SIZE(free_ptr);

        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
                     ("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x\n",
                      header_ptr, header_ptr->next_free, header_ptr->prev_free));

        free_ptr->next->prev = new_ptr;
        new_ptr->next   = free_ptr->next;

        /* remove free ptr from free list */
        free_ptr->next_free->prev_free = free_ptr->prev_free;
        free_ptr->prev_free->next_free = free_ptr->next_free;
    }

    /* insert the split block to free list */
    new_ptr->next_free = heap->free_list->next_free;
    new_ptr->prev_free = heap->free_list;
    heap->free_list->next_free->prev_free = new_ptr;
    heap->free_list->next_free            = new_ptr;
    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new free ptr: next_free 0x%08x, prev_free 0x%08x\n",
                                    new_ptr->next_free,
                                    new_ptr->prev_free));

    /* increment the available byte count.  */
    heap->available_size = heap->available_size + MEMITEM_SIZE(new_ptr);

    /* release lock */
    rt_sem_release(&(heap->lock));

    /* return the old memory block */
    return ptr;
}
示例#26
0
/* Write */
rt_size_t luminaryif_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
	rt_set_errno(-RT_ENOSYS);
	return 0;
}	
示例#27
0
/* Read */
rt_size_t luminaryif_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
	rt_set_errno(-RT_ENOSYS);
	return 0;
}
示例#28
0
static rt_size_t rt_skeleton_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
    rt_set_errno(-RT_ENOSYS);
    return 0;
}
示例#29
0
文件: emac.c 项目: 54chenjq/rt-thread
static rt_size_t rt_cme_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
    rt_set_errno(-RT_ENOSYS);
    return 0;
}
void rt_memheap_free(void *ptr)
{
    rt_err_t result;
    struct rt_memheap *heap;
    struct rt_memheap_item *header_ptr, *new_ptr;
    rt_uint32_t insert_header;

	/* NULL check */
	if (ptr == RT_NULL) return;

    /* set initial status as OK */
    insert_header = 1;
    new_ptr       = RT_NULL;
    header_ptr    = (struct rt_memheap_item *)
                    ((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);

    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: memory[0x%08x], block[0x%08x]\n",
                                    ptr, header_ptr));

    /* check magic */
    RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);

    /* get pool ptr */
    heap = header_ptr->pool_ptr;

    /* lock memheap */
    result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
    if (result != RT_EOK)
    {
        rt_set_errno(result);

        return ;
    }

    /* Mark the memory as available. */
    header_ptr->magic &= ~RT_MEMHEAP_USED;
    /* Adjust the available number of bytes. */
    heap->available_size = heap->available_size + MEMITEM_SIZE(header_ptr);

    /* Determine if the block can be merged with the previous neighbor. */
    if (!RT_MEMHEAP_IS_USED(header_ptr->prev))
    {
        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x\n",
                                        header_ptr->prev));

        /* adjust the available number of bytes. */
        heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;

        /* yes, merge block with previous neighbor. */
        (header_ptr->prev)->next = header_ptr->next;
        (header_ptr->next)->prev = header_ptr->prev;

        /* move header pointer to previous. */
        header_ptr = header_ptr->prev;
        /* don't insert header to free list */
        insert_header = 0;
    }

    /* determine if the block can be merged with the next neighbor. */
    if (!RT_MEMHEAP_IS_USED(header_ptr->next))
    {
        /* adjust the available number of bytes. */
        heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;

        /* merge block with next neighbor. */
        new_ptr = header_ptr->next;

        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
                     ("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x\n",
                      new_ptr, new_ptr->next_free, new_ptr->prev_free));

        new_ptr->next->prev = header_ptr;
        header_ptr->next    = new_ptr->next;

        /* remove new ptr from free list */
        new_ptr->next_free->prev_free = new_ptr->prev_free;
        new_ptr->prev_free->next_free = new_ptr->next_free;
    }

    if (insert_header)
    {
        /* no left merge, insert to free list */
        header_ptr->next_free = heap->free_list->next_free;
        header_ptr->prev_free = heap->free_list;
        heap->free_list->next_free->prev_free = header_ptr;
        heap->free_list->next_free            = header_ptr;

        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
                     ("insert to free list: next_free 0x%08x, prev_free 0x%08x\n",
                      header_ptr->next_free, header_ptr->prev_free));
    }

    /* release lock */
    rt_sem_release(&(heap->lock));
}