当前位置: 首页>>代码示例>>C++>>正文


C++ rtems_fatal_error_occurred函数代码示例

本文整理汇总了C++中rtems_fatal_error_occurred函数的典型用法代码示例。如果您正苦于以下问题:C++ rtems_fatal_error_occurred函数的具体用法?C++ rtems_fatal_error_occurred怎么用?C++ rtems_fatal_error_occurred使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了rtems_fatal_error_occurred函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: qoriq_clock_handler_install

static void qoriq_clock_handler_install(void)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING) && !defined(RTEMS_SMP)
  {
    Processor_mask affinity;

    _Processor_mask_From_index(&affinity, ppc_processor_id());
    bsp_interrupt_set_affinity(CLOCK_INTERRUPT, &affinity);
  }
#endif

  sc = qoriq_pic_set_priority(
    CLOCK_INTERRUPT,
    QORIQ_PIC_PRIORITY_LOWEST,
    NULL
  );
  if (sc != RTEMS_SUCCESSFUL) {
    rtems_fatal_error_occurred(0xdeadbeef);
  }

  sc = rtems_interrupt_handler_install(
    CLOCK_INTERRUPT,
    "Clock",
    RTEMS_INTERRUPT_UNIQUE,
    Clock_isr,
    NULL
  );
  if (sc != RTEMS_SUCCESSFUL) {
    rtems_fatal_error_occurred(0xdeadbeef);
  }
}
开发者ID:gedare,项目名称:rtems,代码行数:33,代码来源:clock-config.c

示例2: rtems_filesystem_initialize

void rtems_filesystem_initialize( void )
{
  int rv = 0;
  const rtems_filesystem_mount_configuration *root_config =
    &rtems_filesystem_root_configuration;

  rv = mount(
    root_config->source,
    root_config->target,
    root_config->filesystemtype,
    root_config->options,
    root_config->data
  );
  if ( rv != 0 )
    rtems_fatal_error_occurred( 0xABCD0002 );

  /*
   *  Traditionally RTEMS devices are under "/dev" so install this directory.
   *
   *  If the mkdir() fails, we can't print anything so just fatal error.
   */

  rv = mkdir( "/dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
  if ( rv != 0 )
    rtems_fatal_error_occurred( 0xABCD0003 );

  /*
   *  You can't mount another filesystem properly until the mount point
   *  it will be mounted onto is created.  Moreover, if it is going to
   *  use a device, then it is REALLY unfair to attempt this
   *  before device drivers are initialized.  So we return via a base
   *  filesystem image and nothing auto-mounted at this point.
   */
}
开发者ID:AlexShiLucky,项目名称:rtems,代码行数:34,代码来源:base_fs.c

示例3: ReInstall_clock

void
ReInstall_clock(void (*new_clock_isr)(void *))
{
	uint32_t   isrlevel = 0;
	rtems_irq_connect_data clockIrqConnData;

	rtems_interrupt_disable(isrlevel);
	clockIrqConnData.name = BSP_PIT;
	if ( ! BSP_get_current_rtems_irq_handler(&clockIrqConnData)) {
		printk("Unable to stop system clock\n");
		rtems_fatal_error_occurred(1);
	}

	BSP_remove_rtems_irq_handler (&clockIrqConnData);
	clockIrqConnData.on   = ClockOn;
	clockIrqConnData.off  = ClockOff;
	clockIrqConnData.isOn = ClockIsOn;
	clockIrqConnData.name = BSP_PIT;
	clockIrqConnData.hdl  = new_clock_isr;
	if (!BSP_install_rtems_irq_handler (&clockIrqConnData)) {
		printk("Unable to connect Clock Irq handler\n");
		rtems_fatal_error_occurred(1);
	}
	rtems_interrupt_enable(isrlevel);
}
开发者ID:FullMentalPanic,项目名称:RTEMS_NEW_TOOL_CHAIN,代码行数:25,代码来源:clock_4xx.c

示例4: exceptionHandler

void exceptionHandler(int vector, void (*handler)(void))
{
  rtems_raw_irq_connect_data excep_raw_irq_data;

  excep_raw_irq_data.idtIndex = vector;

  if(!i386_get_current_idt_entry(&excep_raw_irq_data))
    {
      printk("GDB: cannot get idt entry\n");
      rtems_fatal_error_occurred(1);
    }

  if(!i386_delete_idt_entry(&excep_raw_irq_data))
    {
      printk("GDB: cannot delete idt entry\n");
      rtems_fatal_error_occurred(1);
    }

  excep_raw_irq_data.on = nop;
  excep_raw_irq_data.off = nop;
  excep_raw_irq_data.isOn = isOn;
  excep_raw_irq_data.hdl = handler;

  if (!i386_set_idt_entry (&excep_raw_irq_data)) {
      printk("GDB: raw exception handler connection failed\n");
      rtems_fatal_error_occurred(1);
    }
  return;
}
开发者ID:AoLaD,项目名称:rtems,代码行数:29,代码来源:i386-stub-glue.c

示例5: pipe_release

/*
 * Interface to file system close.
 *
 * *pipep points to pipe control structure. When the last user releases pipe,
 * it will be set to NULL.
 */
int pipe_release(
  pipe_control_t **pipep,
  rtems_libio_t *iop
)
{
  pipe_control_t *pipe = *pipep;
  uint32_t mode;

  rtems_status_code sc;
  sc = rtems_semaphore_obtain(pipe->Semaphore,
                              RTEMS_WAIT, RTEMS_NO_TIMEOUT);
  /* WARN pipe not released! */
  if(sc != RTEMS_SUCCESSFUL)
    rtems_fatal_error_occurred(sc);

  mode = LIBIO_ACCMODE(iop);
  if (mode & LIBIO_FLAGS_READ)
     pipe->Readers --;
  if (mode & LIBIO_FLAGS_WRITE)
     pipe->Writers --;

  sc = rtems_semaphore_obtain(rtems_pipe_semaphore,
                              RTEMS_WAIT, RTEMS_NO_TIMEOUT);
  /* WARN pipe not freed and pipep not set to NULL! */
  if(sc != RTEMS_SUCCESSFUL)
    rtems_fatal_error_occurred(sc);

  PIPE_UNLOCK(pipe);

  if (pipe->Readers == 0 && pipe->Writers == 0) {
#if 0
    /* To delete an anonymous pipe file when all users closed it */
    if (pipe->Anonymous)
      delfile = TRUE;
#endif
    pipe_free(pipe);
    *pipep = NULL;
  }
  else if (pipe->Readers == 0 && mode != LIBIO_FLAGS_WRITE)
    /* Notify waiting Writers that all their partners left */
    PIPE_WAKEUPWRITERS(pipe);
  else if (pipe->Writers == 0 && mode != LIBIO_FLAGS_READ)
    PIPE_WAKEUPREADERS(pipe);

  rtems_semaphore_release(rtems_pipe_semaphore);

#if 0
  if (! delfile)
    return 0;
  if (iop->pathinfo.ops->unlink_h == NULL)
    return 0;

  /* This is safe for IMFS, but how about other FSes? */
  iop->flags &= ~LIBIO_FLAGS_OPEN;
  if(iop->pathinfo.ops->unlink_h(&iop->pathinfo))
    return -errno;
#endif

  return 0;
}
开发者ID:epicsdeb,项目名称:rtems,代码行数:66,代码来源:fifo.c

示例6: open_dev_console

/*
 *  This is a replaceable stub which opens the console, if present.
 */
void open_dev_console(void)
{
  int      stdin_fd;
  int      stdout_fd;
  int      stderr_fd;

  /*
   * Attempt to open /dev/console.
   */
  if ((stdin_fd = open("/dev/console", O_RDONLY, 0)) == -1) {
    /*
     * There may not be a console driver so this is OK.
     */
    return;
  }

  /*
   *  But if we find /dev/console once, we better find it twice more
   *  or something is REALLY wrong.
   */
  if ((stdout_fd = open("/dev/console", O_WRONLY, 0)) == -1)
    rtems_fatal_error_occurred( 0x55544431 );  /* error STD1 */

  if ((stderr_fd = open("/dev/console", O_WRONLY, 0)) == -1)
    rtems_fatal_error_occurred( 0x55544432 );  /* error STD2 */
}
开发者ID:FullMentalPanic,项目名称:RTEMS_NEW_TOOL_CHAIN,代码行数:29,代码来源:open_dev_console.c

示例7: ide_controller_initialize

/*
 * ide_controller_initialize --
 *     Initializes all configured IDE controllers. Controllers configuration
 *     table is provided by BSP
 *
 * PARAMETERS:
 *     major     - device major number
 *     minor_arg - device minor number
 *     args      - arguments
 *
 * RETURNS:
 *     RTEMS_SUCCESSFUL on success, or error code if
 *     error occured
 */
rtems_device_driver
ide_controller_initialize(rtems_device_major_number  major,
                          rtems_device_minor_number  minor_arg,
                          void                      *args)
{
    unsigned long       minor;

    /* FIXME: may be it should be done on compilation phase */
    if (IDE_Controller_Count > IDE_CTRL_MAX_MINOR_NUMBER)
        rtems_fatal_error_occurred(RTEMS_TOO_MANY);

    for (minor=0; minor < IDE_Controller_Count; minor++)
    {
        IDE_Controller_Table[minor].status = IDE_CTRL_NON_INITIALIZED;

        if ((IDE_Controller_Table[minor].probe == NULL ||
             IDE_Controller_Table[minor].probe(minor)) &&
            (IDE_Controller_Table[minor].fns->ctrl_probe == NULL ||
             IDE_Controller_Table[minor].fns->ctrl_probe(minor)))
        {
            dev_t  dev;
            dev = rtems_filesystem_make_dev_t( major, minor );
            if (mknod(IDE_Controller_Table[minor].name,
                      0777 | S_IFBLK, dev ) < 0)
                rtems_fatal_error_occurred(errno);
            IDE_Controller_Table[minor].fns->ctrl_initialize(minor);
            IDE_Controller_Table[minor].status = IDE_CTRL_INITIALIZED;
        }
    }
    return RTEMS_SUCCESSFUL;
}
开发者ID:0871087123,项目名称:rtems,代码行数:45,代码来源:ide_controller.c

示例8: console

/*-------------------------------------------------------------------------+
| Console device driver INITIALIZE entry point.
+--------------------------------------------------------------------------+
| Initilizes the I/O console (keyboard + VGA display) driver.
+--------------------------------------------------------------------------*/
rtems_device_driver
console_initialize(rtems_device_major_number major,
                   rtems_device_minor_number minor,
                   void                      *arg)
{
  rtems_status_code status;

  /*
   * Set up TERMIOS
   */
  rtems_termios_initialize ();

  /*
   * Do device-specific initialization
   */

  /* 115200-8-N-1, without hardware flow control */
  BSP_uart_init(BSPConsolePort, 115200, CHR_8_BITS, 0, 0, 0);

  /* Set interrupt handler */
  if(BSPConsolePort == BSP_UART_COM1)
    {
      console_isr_data.name = BSP_UART_COM1_IRQ;
      console_isr_data.hdl  = BSP_uart_termios_isr_com1;

    }
  else
    {
      assert(BSPConsolePort == BSP_UART_COM2);
      console_isr_data.name = BSP_UART_COM2_IRQ;
      console_isr_data.hdl  = BSP_uart_termios_isr_com2;
    }

  status = BSP_install_rtems_irq_handler(&console_isr_data);

  if (!status){
    printk("Error installing serial console interrupt handler!\n");
    rtems_fatal_error_occurred(status);
  }
  /*
   * Register the device
   */
  status = rtems_io_register_name ("/dev/console", major, 0);
  if (status != RTEMS_SUCCESSFUL)
    {
      printk("Error registering console device!\n");
      rtems_fatal_error_occurred (status);
    }

  if(BSPConsolePort == BSP_UART_COM1)
    {
      printk("Initialized console on port COM1 115200-8-N-1\n\n");
    }
  else
    {
      printk("Initialized console on port COM2 115200-8-N-1\n\n");
    }

  return RTEMS_SUCCESSFUL;
} /* console_initialize */
开发者ID:FullMentalPanic,项目名称:RTEMS_NEW_TOOL_CHAIN,代码行数:65,代码来源:console.c

示例9: qoriq_clock_handler_install

static void qoriq_clock_handler_install(rtems_isr_entry *old_isr)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;

  *old_isr = NULL;

  sc = qoriq_pic_set_affinity(
    CLOCK_INTERRUPT,
    ppc_processor_id()
  );
  if (sc != RTEMS_SUCCESSFUL) {
    rtems_fatal_error_occurred(0xdeadbeef);
  }

  sc = qoriq_pic_set_priority(
    CLOCK_INTERRUPT,
    QORIQ_PIC_PRIORITY_LOWEST,
    NULL
  );
  if (sc != RTEMS_SUCCESSFUL) {
    rtems_fatal_error_occurred(0xdeadbeef);
  }

  sc = rtems_interrupt_handler_install(
    CLOCK_INTERRUPT,
    "Clock",
    RTEMS_INTERRUPT_UNIQUE,
    Clock_isr,
    NULL
  );
  if (sc != RTEMS_SUCCESSFUL) {
    rtems_fatal_error_occurred(0xdeadbeef);
  }
}
开发者ID:0871087123,项目名称:rtems,代码行数:34,代码来源:clock-config.c

示例10: termios_test_driver_initialize

/*
 *  Test Device Driver Entry Points
 */
rtems_device_driver termios_test_driver_initialize(
  rtems_device_major_number  major,
  rtems_device_minor_number  minor,
  void                      *arg
)
{
  rtems_status_code status;

  rtems_termios_initialize();

  /*
   *  Register Device Names
   */
  (void) rtems_io_register_name( TERMIOS_TEST_DRIVER_DEVICE_NAME, major, 0 );

  status = rtems_timer_create(rtems_build_name('T', 'M', 'R', 'X'), &Rx_Timer);
  if ( status )
    rtems_fatal_error_occurred(1);;

  status = rtems_timer_create(rtems_build_name('T', 'M', 'T', 'X'), &Tx_Timer);
  if ( status )
    rtems_fatal_error_occurred(1);;

  return RTEMS_SUCCESSFUL;
}
开发者ID:medivhc,项目名称:rtems,代码行数:28,代码来源:termios_testdriver_intr.c

示例11: console_initialize

/* console_initialize --
 *     This routine initializes the console IO drivers and register devices
 *     in RTEMS I/O system.
 *
 * PARAMETERS:
 *     major - major console device number
 *     minor - minor console device number (not used)
 *     arg - device initialize argument
 *
 * RETURNS:
 *     RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly)
 */
rtems_device_driver
console_initialize(rtems_device_major_number major,
        rtems_device_minor_number minor,
        void *arg)
{
    rtems_status_code status;

#ifdef SH4_WITH_IPL
    /* booting from flash we cannot have IPL console */
    if (boot_mode != SH4_BOOT_MODE_IPL && console_mode == CONSOLE_MODE_IPL)
        console_mode = CONSOLE_MODE_INT;

    /* break out from gdb if neccessary */
    if (boot_mode == SH4_BOOT_MODE_IPL && console_mode != CONSOLE_MODE_IPL)
        ipl_finish();
#endif

    /*
     * Set up TERMIOS
     */
    if ((console_mode != CONSOLE_MODE_RAW) &&
                    (console_mode != CONSOLE_MODE_IPL))
        rtems_termios_initialize ();

    /*
     * Register the devices
     */
    status = rtems_io_register_name ("/dev/console", major, 0);
    if (status != RTEMS_SUCCESSFUL)
        rtems_fatal_error_occurred (status);

    status = rtems_io_register_name ("/dev/aux", major, 1);
    if (status != RTEMS_SUCCESSFUL)
        rtems_fatal_error_occurred (status);

    if (console_mode == CONSOLE_MODE_RAW)
    {
        rtems_status_code sc;
        sc = sh4uart_init(&sh4_uarts[0],              /* uart */
                NULL,                  /* tty */
                1,                     /* UART channel number */
                0);                    /* Poll-mode */

        if (sc == RTEMS_SUCCESSFUL)
            sc = sh4uart_reset(&sh4_uarts[0]);

        sc = sh4uart_init(&sh4_uarts[1],              /* uart */
                NULL,                  /* tty */
                2,                     /* UART channel number */
                0);                    /* Poll-mode */

        if (sc == RTEMS_SUCCESSFUL)
            sc = sh4uart_reset(&sh4_uarts[1]);

        return sc;
    }

    return RTEMS_SUCCESSFUL;
}
开发者ID:AoLaD,项目名称:rtems,代码行数:71,代码来源:console.c

示例12: sparse_disk_read_write

/*
 * Read/write handling
 */
static int sparse_disk_read_write(
  rtems_sparse_disk    *sparse_disk,
  rtems_blkdev_request *req,
  const bool            read )
{
  int                     rv = 0;
  uint32_t                req_buffer;
  rtems_blkdev_sg_buffer *scatter_gather;
  rtems_blkdev_bnum       block;
  uint8_t                *buff;
  size_t                  buff_size;
  unsigned int            bytes_handled;
  rtems_status_code       sc;

  sc = rtems_semaphore_obtain(sparse_disk->mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
  if (sc != RTEMS_SUCCESSFUL) {
      rtems_fatal_error_occurred( 0xdeadbeef );
  }

  for ( req_buffer = 0;
        ( 0 <= rv ) && ( req_buffer < req->bufnum );
        ++req_buffer ) {
    scatter_gather = &req->bufs[req_buffer];

    bytes_handled  = 0;
    buff           = (uint8_t *) scatter_gather->buffer;
    block          = scatter_gather->block;
    buff_size      = scatter_gather->length;

    while ( ( 0 <= rv ) && ( 0 < buff_size ) ) {
      if ( read )
        rv = sparse_disk_read_block( sparse_disk,
                                     block,
                                     &buff[bytes_handled],
                                     buff_size );
      else
        rv = sparse_disk_write_block( sparse_disk,
                                      block,
                                      &buff[bytes_handled],
                                      buff_size );

      ++block;
      bytes_handled += rv;
      buff_size     -= rv;
    }
  }

  sc = rtems_semaphore_release( sparse_disk->mutex );
  if (sc != RTEMS_SUCCESSFUL) {
      rtems_fatal_error_occurred( 0xdeadbeef );
  }

  if ( 0 > rv )
    rtems_blkdev_request_done( req, RTEMS_IO_ERROR );
  else
    rtems_blkdev_request_done( req, RTEMS_SUCCESSFUL );

  return 0;
}
开发者ID:AlexShiLucky,项目名称:rtems,代码行数:62,代码来源:sparse-disk.c

示例13: ns16550_initialize_interrupts

/*
 *  ns16550_initialize_interrupts
 *
 *  This routine initializes the port to operate in interrupt driver mode.
 */
NS16550_STATIC void ns16550_initialize_interrupts( int minor)
{
#if defined(BSP_FEATURE_IRQ_EXTENSION) || defined(BSP_FEATURE_IRQ_LEGACY)
  console_tbl *c = Console_Port_Tbl [minor];
#endif
  console_data *d = &Console_Port_Data [minor];

  d->bActive = false;

  #ifdef BSP_FEATURE_IRQ_EXTENSION
    {
      rtems_status_code sc = RTEMS_SUCCESSFUL;
      sc = rtems_interrupt_handler_install(
        c->ulIntVector,
        "NS16550",
        RTEMS_INTERRUPT_SHARED,
        ns16550_isr,
        (void *) minor
      );
      if (sc != RTEMS_SUCCESSFUL) {
        /* FIXME */
        printk( "%s: Error: Install interrupt handler\n", __func__);
        rtems_fatal_error_occurred( 0xdeadbeef);
      }
    }
  #elif defined(BSP_FEATURE_IRQ_LEGACY)
    {
      int rv = 0;
      #ifdef BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT
        rtems_irq_connect_data cd = {
          c->ulIntVector,
          ns16550_isr,
          (void *) minor,
          NULL,
          NULL,
          NULL,
          NULL
        };
        rv = BSP_install_rtems_shared_irq_handler( &cd);
      #else
        rtems_irq_connect_data cd = {
          c->ulIntVector,
          ns16550_isr,
          (void *) minor,
          NULL,
          NULL,
          NULL
        };
        rv = BSP_install_rtems_irq_handler( &cd);
      #endif
      if (rv == 0) {
        /* FIXME */
        printk( "%s: Error: Install interrupt handler\n", __func__);
        rtems_fatal_error_occurred( 0xdeadbeef);
      }
    }
  #endif
}
开发者ID:AndroidMarv,项目名称:rtems,代码行数:63,代码来源:ns16550.c

示例14: pipe_release

/*
 * Interface to file system close.
 *
 * *pipep points to pipe control structure. When the last user releases pipe,
 * it will be set to NULL.
 */
void pipe_release(
  pipe_control_t **pipep,
  rtems_libio_t *iop
)
{
  pipe_control_t *pipe = *pipep;
  uint32_t mode;

  #if defined(RTEMS_DEBUG)
    /* WARN pipe not freed and pipep not set to NULL! */
    if (pipe_lock())
      rtems_fatal_error_occurred(0xdeadbeef);

    /* WARN pipe not released! */
    if (!PIPE_LOCK(pipe))
      rtems_fatal_error_occurred(0xdeadbeef);
  #endif

  mode = LIBIO_ACCMODE(iop);
  if (mode & LIBIO_FLAGS_READ)
     pipe->Readers --;
  if (mode & LIBIO_FLAGS_WRITE)
     pipe->Writers --;

  PIPE_UNLOCK(pipe);

  if (pipe->Readers == 0 && pipe->Writers == 0) {
#if 0
    /* To delete an anonymous pipe file when all users closed it */
    if (pipe->Anonymous)
      delfile = TRUE;
#endif
    pipe_free(pipe);
    *pipep = NULL;
  }
  else if (pipe->Readers == 0 && mode != LIBIO_FLAGS_WRITE)
    /* Notify waiting Writers that all their partners left */
    PIPE_WAKEUPWRITERS(pipe);
  else if (pipe->Writers == 0 && mode != LIBIO_FLAGS_READ)
    PIPE_WAKEUPREADERS(pipe);

  pipe_unlock();

#if 0
  if (! delfile)
    return;
  if (iop->pathinfo.ops->unlink_h == NULL)
    return;

  /* This is safe for IMFS, but how about other FSes? */
  iop->flags &= ~LIBIO_FLAGS_OPEN;
  if(iop->pathinfo.ops->unlink_h(&iop->pathinfo))
    return;
#endif

}
开发者ID:0871087123,项目名称:rtems,代码行数:62,代码来源:fifo.c

示例15: IMFS_evaluate_sym_link

int IMFS_evaluate_sym_link(
  rtems_filesystem_location_info_t  *node,   /* IN/OUT */
  int                                flags   /* IN     */
)
{
  IMFS_jnode_t                     *jnode  = node->node_access;
  int                               result = 0;
  int                               i;

  /*
   * Check for things that should never happen.
   */

  if ( jnode->type != IMFS_SYM_LINK )
    rtems_fatal_error_occurred (0xABCD0000);

  if ( !jnode->Parent )
    rtems_fatal_error_occurred( 0xBAD00000 );


  /*
   * Move the node_access to either the symbolic links parent or
   * root depending on the symbolic links path.
   */

  node->node_access = jnode->Parent;

  rtems_filesystem_get_sym_start_loc(
    jnode->info.sym_link.name,
    &i,
    node
  );

  /*
   * Use eval path to evaluate the path of the symbolic link.
   */

  result = IMFS_eval_path(
    &jnode->info.sym_link.name[i],
    strlen( &jnode->info.sym_link.name[i] ),
    flags,
    node
  );

  IMFS_Set_handlers( node );

  /*
   * Verify we have the correct permissions for this node.
   */

  if ( !IMFS_evaluate_permission( node, flags ) )
    rtems_set_errno_and_return_minus_one( EACCES );

  return result;
}
开发者ID:epicsdeb,项目名称:rtems,代码行数:55,代码来源:imfs_eval.c


注:本文中的rtems_fatal_error_occurred函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。