Beispiel #1
0
error_t timer_start (timer_handle_t _handle, msecond_t _duration,
                     expiry_callback_t _cb, void *_arg)
{
    interrupt_level_t level;

    if (null == _cb) {
        return ERROR_T (ERROR_TIMER_ALLOC_INVCB);
    }
    level = global_interrupt_disable ();
    if (is_invalid_handle (_handle)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_START_INVHANDLE);
    }
    if (TIMER_STARTED == _handle->state_) {
        g_statistics.abnormal_ ++;
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_START_INVSTATE);
    }

    _handle->ticks_ = _duration / CONFIG_TICK_DURATION_IN_MSEC;
    if (0 == _handle->ticks_) {
        _handle->ticks_ ++;
    }
    _handle->callback_ = _cb;
    _handle->arg_ = _arg;
    global_interrupt_enable (level);
    timer_insert (_handle);
    return 0;
}
Beispiel #2
0
static bool mutex_callback_unlock (sync_object_handle_t _handle,
    error_t *_p_ecode)
{
    mutex_handle_t p_mutex = (mutex_handle_t) _handle;
    task_handle_t p_task = task_self ();

    // grab the mutex
    if (is_in_interrupt () || is_invalid_task (p_task)) {
        return ERROR_T (ERROR_MUTEX_INVCONTEXT);
    }
    if (p_mutex->owner_ != p_task) {
        *_p_ecode = ERROR_T (ERROR_MUTEX_NOTOWNER);
        return false;
    }
    if (p_mutex->reference_ > 0) {
        p_mutex->reference_ --;
        return true;
    }
    // restore owner's original priority
    if (p_mutex->inherited_) {
        p_mutex->inherited_ = false;
        task_priority_change (p_mutex->owner_, p_mutex->original_);
    }
    if (task_bitmap_is_empty (&p_mutex->object_.pending_bitmap_)) {
        // no task is pending on this mutex
        p_mutex->owner_ = null;
        return true;
    }
    return false;
}
Beispiel #3
0
error_t device_write (device_handle_t _handle, const void *_buf, usize_t _size)
{
    if (is_invalid_handle (_handle)) {
        return ERROR_T (ERROR_DEVICE_WRITE_INVHANDLE);
    }

    if (null == _handle->driver_->operation_.write_) {
        return ERROR_T (ERROR_DEVICE_WRITE_NOTSUPPORT);
    }
    return _handle->driver_->operation_.write_ (_handle, _buf, _size);
}
Beispiel #4
0
error_t device_read (device_handle_t _handle, void *_buf, usize_t _size)
{
    if (is_invalid_handle (_handle)) {
        return ERROR_T (ERROR_DEVICE_READ_INVHANDLE);
    }

    if (null == _handle->driver_->operation_.read_) {
        return ERROR_T (ERROR_DEVICE_READ_NOTSUPPORT);
    }
    return _handle->driver_->operation_.read_ (_handle, _buf, _size);
}
Beispiel #5
0
error_t device_control (device_handle_t _handle, control_option_t _option,
    int _int_arg, void *_ptr_arg)
{
    if (is_invalid_handle (_handle)) {
        return ERROR_T (ERROR_DEVICE_CONTROL_INVHANDLE);
    }

    if (null == _handle->driver_->operation_.control_) {
        return ERROR_T (ERROR_DEVICE_CONTROL_NOTSUPPORT);
    }
    return _handle->driver_->operation_.control_ (_handle, _option, _int_arg,
        _ptr_arg);
}
Beispiel #6
0
error_t timer_stop (timer_handle_t _handle, msecond_t *_p_remained)
{
    interrupt_level_t level;
    timer_handle_t next;
    bucket_t *p_bucket;

    level = global_interrupt_disable ();
    if (is_invalid_handle (_handle)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_STOP_INVHANDLE);
    }
    if (_handle->state_ != TIMER_STARTED) {
        g_statistics.abnormal_ ++;
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_STOP_INVSTATE);
    }

    if (g_timer_next == _handle) {
        g_timer_next = (timer_handle_t) dll_next (&g_bucket_firing->dll_,
                       &_handle->node_);
    }
    p_bucket = &g_buckets [_handle->bucket_index_];
    if (_p_remained != null) {
        timer_remained_t remained = {_handle, 0};

        (void) dll_traverse (&p_bucket->dll_, timer_calculate_remained, &remained);
        *_p_remained = remained.remained_round_ * CONFIG_MAX_BUCKET;
        if (g_cursor > _handle->bucket_index_) {
            *_p_remained = (*_p_remained) * CONFIG_MAX_BUCKET -
                           (g_cursor - _handle->bucket_index_);
        }
        else {
            *_p_remained = (*_p_remained - 1) * CONFIG_MAX_BUCKET +
                           (g_cursor - _handle->bucket_index_) + 1;
        }
        *_p_remained *= CONFIG_TICK_DURATION_IN_MSEC;
    }
    _handle->state_ = TIMER_STOPPED;
    next = (timer_handle_t)dll_next (&p_bucket->dll_, &_handle->node_);
    if (0 != next) {
        next->round_ += _handle->round_;
    }
    dll_remove (&p_bucket->dll_, &_handle->node_);
    dll_push_tail (&g_inactive_timer, &_handle->node_);
    if (p_bucket->reentrance_ > 0) {
        p_bucket->level_ ++;
    }
    global_interrupt_enable (level);

    return 0;
}
Beispiel #7
0
error_t event_send (task_handle_t _handle, event_set_t _sent)
{
    interrupt_level_t level;
    bool wakeup_needed = false;

    level = global_interrupt_disable ();
    if (is_invalid_task (_handle)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_EVENT_RECV_INVRECEIVER);
    }
    _handle->event_received_ |= _sent;
    if (0 == (int)_handle->event_option_) {
        global_interrupt_enable (level);
        return 0;
    }
    if (EVENT_WAIT_ALL == (_handle->event_option_ & EVENT_WAIT_ALL)) {
        if ((_handle->event_expected_ & _handle->event_received_) == 
            _handle->event_expected_) {
            wakeup_needed = true;
        }
    }
    else {
        if ((_handle->event_expected_ & _handle->event_received_) != 0) {
            wakeup_needed = true;
        }
    }
    if (!wakeup_needed) {
        global_interrupt_enable (level);
        return 0;
    }
    (void) task_state_change (_handle, TASK_STATE_READY);
    global_interrupt_enable (level);
    task_schedule (null);
    return 0;
}
Beispiel #8
0
error_t timer_free (timer_handle_t _handle)
{
    interrupt_level_t level;

    level = global_interrupt_disable ();
    if (is_invalid_handle (_handle)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_FREE_INVHANDLE);
    }
    if (TIMER_STARTED == _handle->state_) {
        timer_handle_t next;
        bucket_t *p_bucket = &g_buckets [_handle->bucket_index_];

        if (g_timer_next == _handle) {
            g_timer_next = (timer_handle_t) dll_next (&g_bucket_firing->dll_,
                           &_handle->node_);
        }
        next = (timer_handle_t)dll_next (&p_bucket->dll_, &_handle->node_);
        if (0 != next) {
            next->round_ += _handle->round_;
        }
        dll_remove (&p_bucket->dll_, &_handle->node_);
        if (p_bucket->reentrance_ > 0) {
            g_bucket_firing->level_ ++;
        }
    }
    else {
        dll_remove (&g_inactive_timer, &_handle->node_);
    }
    _handle->magic_number_ = 0;
    dll_push_tail (&g_free_timer, &_handle->node_);
    global_interrupt_enable (level);

    return 0;
}
Beispiel #9
0
error_t device_open (device_handle_t *_p_handle, const char _name [], 
    open_mode_t _mode)
{
    int idx;
    driver_handle_t p_driver = null;
    const char *p_name;
    device_handle_t handle;
    error_t ecode;

    if (null == _name) {
        return ERROR_T (ERROR_DEVICE_OPEN_INVNAME);
    }

    // find the driver for the device
    for (idx = 0; idx <= DRIVER_LAST_INDEX; idx ++) {
        if ((MAGIC_NUMBER_DRIVER == g_driver_pool [idx].magic_number_) &&
            (0 == strncmp (g_driver_pool [idx].name_, _name, 
            strlen (g_driver_pool [idx].name_)))) {
            p_driver = &g_driver_pool [idx];
            break;
        }
    }
    if (null == p_driver) {
        return ERROR_T (ERROR_DEVICE_OPEN_NODRV);
    }
    // strip the driver name from device name before passing it into the device
    // open () operation
    p_name = &_name [strlen (p_driver->name_)];
    // find the device
    handle = (device_handle_t) dll_traverse (&p_driver->devices_, 
        device_find, (void *)p_name);
    if (0 == handle) {
        return ERROR_T (ERROR_DEVICE_OPEN_NODEV);
    }
    // we don't need to consider race condition for calling driver's open ()
    // operation, intead, the specific device driver should be responsible.
    ecode = p_driver->operation_.open_ (handle, _mode);
    if (0 == ecode) {
        interrupt_level_t level = global_interrupt_disable ();
        p_driver->count_opened_ ++;
        global_interrupt_enable (level);
        *_p_handle = handle;
    }
    return ecode; 
}
Beispiel #10
0
error_t timer_alloc (timer_handle_t *_p_handle, const char *_name,
                     timer_type_t _type)
{
    interrupt_level_t level;
    static bool initialized = false;
    timer_handle_t handle;

    if (0 == _p_handle) {
        return ERROR_T (ERROR_TIMER_ALLOC_INVHANDLE);
    }

    *_p_handle = null;
    level = global_interrupt_disable ();
    if (!initialized) {
        timer_init ();
        initialized = true;
    }

    handle = (timer_handle_t)dll_pop_head (&g_free_timer);
    if (0 == handle) {
        g_statistics.notimer_ ++;
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_ALLOC_NOTIMER);
    }
    global_interrupt_enable (level);

    handle->type_ = _type;
    handle->magic_number_ = MAGIC_NUMBER_TIMER;
    handle->state_ = TIMER_CREATED;
    dll_node_init (&handle->node_);
    if (0 == _name) {
        handle->name_ [0] = 0;
    }
    else {
        strncpy (handle->name_, _name, (usize_t)sizeof (handle->name_));
        handle->name_ [sizeof (handle->name_) - 1] = 0;
    }

    level = global_interrupt_disable ();
    dll_push_tail (&g_inactive_timer, &handle->node_);
    global_interrupt_enable (level);

    *_p_handle = handle;
    return 0;
}
Beispiel #11
0
error_t driver_install (const char _name [], const device_operation_t *_p_operation, 
    device_mode_t _mode)
{
    int idx;
    driver_handle_t p_driver = null;
    const char *dev_root = "/dev/";

    if ((null == _name) || (strncmp (_name, dev_root, strlen (dev_root)) != 0)) {
        // a driver has no name?
        return ERROR_T (ERROR_DRIVER_INVNAME);
    }
    if (null == _p_operation || null == _p_operation->open_ ||
        null == _p_operation->close_) {
        return ERROR_T (ERROR_DRIVER_INVOPT);
    }
    // a driver only can be installed before system is UP
    if (system_state () > STATE_INITIALIZING) {
        return ERROR_T (ERROR_DRIVER_INVSTATE);
    }
    // check whether the driver is already installed
    for (idx = 0; idx <= DRIVER_LAST_INDEX; idx ++) {
        if ((MAGIC_NUMBER_DRIVER == g_driver_pool [idx].magic_number_) &&
            (0 == strncmp (g_driver_pool [idx].name_, _name, strlen (_name)))) {
            return ERROR_T (ERROR_DRIVER_INSTALLED);
        }
    }

    for (idx = 0; idx <= DRIVER_LAST_INDEX; idx ++) {
        if (g_driver_pool [idx].magic_number_ != MAGIC_NUMBER_DRIVER) {
            p_driver = &g_driver_pool [idx];
            break;
        }
    }
    if (null == p_driver) {
        return ERROR_T (ERROR_DRIVER_NODRV);
    }
    p_driver->magic_number_ = MAGIC_NUMBER_DRIVER;
    p_driver->operation_ = *_p_operation;
    p_driver->mode_ = _mode;
    strncpy (p_driver->name_, _name, sizeof (p_driver->name_) - 1);
    p_driver->name_ [sizeof (p_driver->name_) - 1] = 0;
    dll_init (&p_driver->devices_);
    return 0;
}
Beispiel #12
0
error_t timer_restart (timer_handle_t _handle)
{
    interrupt_level_t level;

    level = global_interrupt_disable ();
    if (is_invalid_handle (_handle)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_RESTART_INVHANDLE);
    }
    if (TIMER_STOPPED != _handle->state_) {
        g_statistics.abnormal_ ++;
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_RESTART_INVSTATE);
    }
    global_interrupt_enable (level);

    timer_insert (_handle);
    return 0;
}
Beispiel #13
0
error_t device_register (const char _name [], device_handle_t _handle)
{
    int idx;
    driver_handle_t p_driver = null;
    const char *p_name;
    
    if (null == _name) {
        // a device has no name?
        return ERROR_T (ERROR_DEVICE_REGISTER_INVNAME);
    }
    if (null == _handle) {
        return ERROR_T (ERROR_DEVICE_REGISTER_INVHANDLE);
    }
    // a device only can be registered before system is UP
    if (system_state () > STATE_INITIALIZING) {
        return ERROR_T (ERROR_DRIVER_INVSTATE);
    }
    
    // find the driver for the device
    for (idx = 0; idx <= DRIVER_LAST_INDEX; idx ++) {
        if ((MAGIC_NUMBER_DRIVER == g_driver_pool [idx].magic_number_) &&
            (0 == strncmp (g_driver_pool [idx].name_, _name, 
            strlen (g_driver_pool [idx].name_)))) {
            p_driver = &g_driver_pool [idx];
            break;
        }
    }
    if (null == p_driver) {
        return ERROR_T (ERROR_DEVICE_REGISTER_NODRV);
    }
    if (_handle->interrupt_vector_ != INTERRUPT_NONE) {
        g_interrupt_map [_handle->interrupt_vector_] = _handle;
    }
    _handle->driver_ = p_driver;
    // strip the driver name from device name before passing it into the device
    // open () operation
    p_name = &_name [strlen (p_driver->name_)];
    strncpy (_handle->name_, p_name, sizeof (_handle->name_) - 1);
    _handle->name_ [sizeof (_handle->name_) - 1] = 0;
    _handle->magic_number_ = MAGIC_NUMBER_DEVICE;
    dll_push_tail (&p_driver->devices_, &_handle->node_);
    return 0;
}
Beispiel #14
0
static error_t clock_open (device_handle_t _handle, open_mode_t _mode)
{
    clock_handle_t handle = (clock_handle_t)_handle;

    UNUSED (_mode);
    
    if (handle->is_opened_) {
        return ERROR_T (ERROR_CLOCK_OPEN_OPENED);
    }

    handle->is_opened_ = true;
    return 0;
}
Beispiel #15
0
error_t event_clear ()
{
    interrupt_level_t level;
    task_handle_t p_task = task_self ();

    level = global_interrupt_disable ();
    if (is_invalid_task (p_task)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_EVENT_CLEAR_INVCONTEXT);
    }
    p_task->event_received_ = 0;
    global_interrupt_enable (level);
    return 0;
}
Beispiel #16
0
static error_t ctrlc_open (device_handle_t _handle, open_mode_t _mode)
{
    ctrlc_handle_t handle = (ctrlc_handle_t)_handle;

    UNUSED (_mode);
    
    if (handle->is_opened_) {
        return ERROR_T (ERROR_CTRLC_OPEN_OPENED);
    }

    handle->is_opened_ = true;
    interrupt_enable (_handle->interrupt_vector_);
    console_print ("\nInfo: press Ctrl+C to terminate!\n");
    return 0;
}
Beispiel #17
0
error_t device_close (device_handle_t _handle)
{
    error_t ecode;
    
    if (is_invalid_handle (_handle)) {
        return ERROR_T (ERROR_DEVICE_CLOSE_INVHANDLE);
    }

    ecode = _handle->driver_->operation_.close_ (_handle);
    if (0 == ecode) {
        interrupt_level_t level = global_interrupt_disable ();
        _handle->driver_->count_opened_ --;
        global_interrupt_enable (level);
    }
    return ecode;
}
Beispiel #18
0
//lint -e{818}
static error_t clock_control (device_handle_t _handle, 
    control_option_t _option, int _int_arg, void *_ptr_arg)
{
    clock_handle_t handle = (clock_handle_t)_handle;
    
    switch (_option)
    {
    case OPTION_TICK_START:
        {
            struct itimerval tv;
            
            //lint -e{611}
            handle->tick_process_ = (interrupt_handler_t) _ptr_arg;
            
            tv.it_value.tv_sec = 0;
            tv.it_value.tv_usec = (long) _int_arg*1000; // msec to usec
            tv.it_interval.tv_sec = 0;
            tv.it_interval.tv_usec = (long) _int_arg*1000; // msec to usec
            (void) setitimer (ITIMER_REAL, &tv, 0);

            interrupt_enable (_handle->interrupt_vector_);
        }
        break;
    case OPTION_TICK_STOP:
        {
            struct itimerval  tv;
            struct sigaction  act;

            interrupt_disable (_handle->interrupt_vector_);
            
            memset (&act, 0, sizeof(act));
            act.sa_handler = SIG_IGN;
            (void) sigaction (SIGALRM, &act, 0);

            memset (&tv, 0, sizeof(tv));
            (void) setitimer (ITIMER_REAL, &tv, 0);
        }
        break;
    default:
        return ERROR_T (ERROR_CLOCK_CONTROL_INVOPT);
    }
    return 0;
}
Beispiel #19
0
error_t event_receive (event_set_t _expected, event_set_handle_t _received, 
    msecond_t _timeout, event_option_t _option)
{
    interrupt_level_t level;
    event_option_t wait_option = EVENT_WAIT_ALL | EVENT_WAIT_ANY;
    event_option_t return_option = EVENT_RETURN_ALL | EVENT_RETURN_EXPECTED;
    task_handle_t p_task;

    if (is_in_interrupt ()) {
        return ERROR_T (ERROR_EVENT_RECV_INVCONTEXT);
    }
    if (0 == _expected) {
        return 0;
    }
    if (null == _received) {
        return ERROR_T (ERROR_EVENT_RECV_INVPTR);
    }
    if ((wait_option == (wait_option & _option)) ||
        (0 == (int)(wait_option & _option)) ||
        (return_option == (return_option & _option)) ||
        (0 == (int)(return_option & _option))) {
        return ERROR_T (ERROR_EVENT_RECV_INVOPT);
    }
    
    level = global_interrupt_disable ();
    p_task = task_self ();
    if (is_invalid_task (p_task)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_EVENT_RECV_INVCONTEXT);
    }
again:
    // if expected event(s) is/are available, return it
    if (EVENT_WAIT_ALL == (_option & EVENT_WAIT_ALL)) {
        if ((_expected & p_task->event_received_) == _expected) {
            if (EVENT_RETURN_ALL == (_option & EVENT_RETURN_ALL)) {
                *_received = p_task->event_received_;
            }
            else {
                *_received = _expected;
                p_task->event_received_ &= ~(*_received);
            }
            global_interrupt_enable (level);
            return 0;
        }
    }
    else {
        if ((_expected & p_task->event_received_) != 0) {
            if (EVENT_RETURN_ALL == (_option & EVENT_RETURN_ALL)) {
                *_received = p_task->event_received_;
            }
            else {
                *_received = _expected & p_task->event_received_;
                p_task->event_received_ &= ~(*_received);
            }
            global_interrupt_enable (level);
            return 0;
        }
    }
    // run here it means we need to block the task
    p_task->timeout_ = _timeout;
    (void) task_state_change (p_task, TASK_STATE_WAITING);
    p_task->ecode_ = 0;
    p_task->event_expected_ = _expected;
    p_task->event_option_ = _option;
    global_interrupt_enable (level);
    task_schedule (null);
    level = global_interrupt_disable ();
    p_task->event_option_ = (event_option_t) 0;
    if (0 == p_task->ecode_) {
        // event(s) has/have received and need to return the event(s) expected
        goto again;
    }
    global_interrupt_enable (level);
    //lint -e{650}
    if (ERROR_TASK_WAIT_TIMEOUT == MODULE_ERROR (p_task->ecode_)) {
        p_task->ecode_ = ERROR_T (ERROR_EVENT_RECV_TIMEOUT);
    }
    return p_task->ecode_;
}
Beispiel #20
0
static err_t gpio_init(Drive_Gpio *t)
{
	Drive_Gpio 		*cthis = ( Drive_Gpio *)t ;
	uint32_t		tmp_reg = 0;
	gpio_cfg 		*config = cthis->config;
	int 			i = 0;

	 assert( config->intr_line < 2);

	cthis->gpio_vbase = mmap_device_io( AM335X_GPIO_SIZE, GpioBase[ config->pin_group]);
#ifdef DEBUG_GPIO
	TRACE_INFO("Drive Piling :%s-%s-%d \r\n", __FILE__, __func__, __LINE__);
	TRACE_INFO("pin config 0x%04x \r\n", rd_pin_conf( config->pin_ctrl_off));
	return EXIT_SUCCESS;
#else
	if (cthis->gpio_vbase == MAP_DEVICE_FAILED)
	{

		return ERROR_T( gpio_init_mapio_fail);
	}
	gpioModuleConfig[ config->pin_group]();
	GPIOModuleEnable( cthis->gpio_vbase);

	//配置引脚方向为输入
	tmp_reg = in32( cthis->gpio_vbase + GPIO_OE );
	tmp_reg |= 1 << config->pin_number;
	out32( cthis->gpio_vbase + GPIO_OE, tmp_reg );


	//使能消抖
	tmp_reg=in32( cthis->gpio_vbase + GPIO_DEBOUNCENABLE);
	tmp_reg &=~( 1 << config->pin_number);
	tmp_reg |= ( 1 << config->pin_number);
	out32( cthis->gpio_vbase + GPIO_DEBOUNCENABLE, tmp_reg);

	//消抖时间
	out32( cthis->gpio_vbase + GPIO_DEBOUNCINGTIME, ( config->debou_time ));

	//配置中断监测类型
	for( i = 0; i < 4; i ++)
	{
		if( ( ( 1 << i) & config->intr_type) )
		{
			//使能该类型
			tmp_reg = in32( cthis->gpio_vbase + GPIO_DETECT(i));
			tmp_reg |= 1 << config->pin_number;
			out32(cthis->gpio_vbase + GPIO_DETECT(i), tmp_reg);
		}
		else
		{
			//禁止其他类型
			tmp_reg = in32( cthis->gpio_vbase + GPIO_DETECT(i));
			tmp_reg &= ~(1 << config->pin_number);
			out32(cthis->gpio_vbase + GPIO_DETECT(i), tmp_reg);
		}
	}

	//使能引脚中断
//	tmp_reg = in32( cthis->gpio_vbase + GPIO_IRQSTATUS_SET( config->intr_line));
//	tmp_reg |= 1 << config->pin_number;
//	out32(cthis->gpio_vbase + GPIO_IRQSTATUS_SET( config->intr_line), tmp_reg);
#ifdef DEBUG_GPIO
	dump_gpio_reg( cthis->gpio_vbase);
#endif
	SIGEV_INTR_INIT( &cthis->isr_event );
	cthis->irq_id = InterruptAttach_r ( GpioIntNum[ config->intr_line][ config->pin_group], gpioExtInteIsr, cthis, 1, _NTO_INTR_FLAGS_END );
	return EXIT_SUCCESS;

#endif
}