示例#1
0
文件: kernel.c 项目: wuxx/sos
s32 os_main(u32 sp)
{
    struct __os_task__ *ptask;

    int_init();
    uart_init();
    dram_init();
    timer_init();
    mmc_init();

    PRINT_INFO("%s\n", sys_banner);

    coretimer_init();
    task_init();
    semaphore_init();

    PRINT_INFO("cpu_mode: %s; lr: 0x%x; sp: 0x%x; cpsr: 0x%x\n",
            get_cpu_mode(NULL), __get_lr(), sp, __get_cpsr());

    gpio_set_function(GPIO_16, OUTPUT);
    gpio_set_output(GPIO_16, 0);

    /* set_log_level(LOG_DEBUG); */

    /* create idle task */
    if ((ptask = tcb_alloc()) == NULL) {
        panic();
    }

    tcb_init(ptask, idle_task, 0, 256);

    /*os_ready_insert(ptask);*/

    current_task = &tcb[IDLE_TASK_ID];  /* assume that this is idle_task */

    /* create main task */
    if ((ptask = tcb_alloc()) == NULL) {
        panic();
    }

    tcb_init(ptask, main_task, 0, 100);

    os_ready_insert(ptask);

    /* 'slip into idle task', cause the os_main() is not a task (it's the god code of system) */
    __set_sp(&(task_stack[0][TASK_STK_SIZE]));
    current_task->state = TASK_RUNNING;
    idle_task(0);

    kassert(0);
    return 0;
}
示例#2
0
/**
 * Get a tcb and initialize it with the entry and entry_arg.
 *
 * @param entry routine to call to start thread
 * @param entry_arg is the argument to pass to entry
 *
 * Return AC_NULL if an error, i.e. nono available
 */
STATIC tcb_x86* get_tcb(void*(*entry)(void*), void* entry_arg) {
  tcb_x86* ptcb;

  // There must always be at least one ac_threads
  ac_debug_assert(pthreads != AC_NULL);

  // Search all of the ac_threads for an empty tcb
  ac_threads* pcur = pthreads;
  do {
    // Find an empty tcb;
    for (ac_u32 i = 0; i < pcur->max_count; i++) {
      ptcb = &pcur->tcbs[i];

      ac_u32 empty = AC_THREAD_ID_EMPTY;
      ac_s32* pthread_id = &ptcb->thread_id;
      ac_bool ok = __atomic_compare_exchange_n(pthread_id, &empty,
          AC_THREAD_ID_STARTING, AC_TRUE, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
      if (ok) {
        // Found an empty tcb, initialize and return it
        tcb_init(ptcb, i, entry, entry_arg);
        return ptcb;
      }
    }
    pcur = pcur->pnext;
  } while (pcur != pthreads);

  // No empty tcbs
  return AC_NULL;
}
示例#3
0
/**
 * Early initialization of this module
 */
void ac_thread_early_init() {
  // Initialize timer first, the main reason
  // is it set slice_default.
  init_timer();

  // Initialize reschedule isr
  set_intr_handler(RESCHEDULE_ISR_INTR, reschedule_isr);
  set_intr_handler(TIMER_RESCHEDULE_ISR_INTR, timer_reschedule_isr);

  // Allocate the initial array
  total_threads = 0;
  pthreads = AC_NULL;
  ac_thread_init(SYSTEM_THREAD_COUNT);
  ac_assert(pthreads != AC_NULL);

  pidle_tcb = &pthreads->tcbs[0];
  pmain_tcb = &pthreads->tcbs[1];

  // Initialize idle and main tcbs
  tcb_init(pidle_tcb, 0, idle, AC_NULL);
  tcb_init(pmain_tcb, 1, AC_NULL, AC_NULL);

  // Initialize idle's stack
  init_stack_frame(idle_stack, sizeof(idle_stack), DEFAULT_FLAGS, idle, pidle_tcb,
      &pidle_tcb->sp, &pidle_tcb->ss);

  // Add main as the initial pready list
  pmain_tcb->pnext_tcb = pmain_tcb;
  pmain_tcb->pprev_tcb = pmain_tcb;
  pready = pmain_tcb;
#ifdef SUPPORT_READY_LENGTH
  ready_length = 1;
#endif

  // Add idle to the pready list
  add_tcb_after(pidle_tcb, pready);

  // Initialize waiting tcbs data structures
  waiting_tcbs_init(SYSTEM_THREAD_COUNT);
  print_waiting_tcbs();

  ac_printf("ac_thread_early_init: pmain=0x%lx pidle=0x%lx rl=%d\n", pmain_tcb, pidle_tcb,
      get_ready_length());
  print_tcb_list("ac_thread_early_init:-ready: ", pready);
}
示例#4
0
文件: sched.c 项目: bujar/ARM-Gumstix
/**
 * @brief This function initializes the idle TCB and makes it runnable
 */
static void idle_init(void){
	task_t idle_task;
	idle_task.lambda = (void *) idle;
	idle_task.data = 0;
	idle_task.C = 0;
	idle_task.T = 0; 
	idle_task.stack_pos = (void *) idle_stack_high;
	tcb_init(&idle_task, &system_tcb[IDLE_PRIO], IDLE_PRIO);
	runqueue_add(&system_tcb[IDLE_PRIO], IDLE_PRIO);
}
/**
 * Initializes all the thread queues with
 * tqueue_init_at_id.
 */
void tqueue_init(unsigned int mbi_addr)
{
  // TODO: define your local variables here.
	unsigned int chid;
	tcb_init(mbi_addr);
	for (chid = 0; chid < NUM_IDS + 1; chid++) 
	{
		tqueue_init_at_id(chid);
	}
}
示例#6
0
文件: sched.c 项目: bujar/ARM-Gumstix
/**
 * @brief Creates the main user program as a main task
 * and sets it to run.
 *
 * This function is only called when the user program is
 * first run.
 *
 */
void sched_init(task_t* main_task)
{
	main_task->lambda =    (void *)0xa0000000;
	main_task->data = 0;
	main_task->stack_pos = (void *)0xa3000000;
	main_task->C = 1;
	main_task->T = 1; 
	tcb_init(main_task, &system_tcb[FIRST_MAIN_PRIO], FIRST_MAIN_PRIO);
	runqueue_add(&system_tcb[FIRST_MAIN_PRIO], FIRST_MAIN_PRIO);
	dispatch_init(&system_tcb[FIRST_MAIN_PRIO]);
}
示例#7
0
文件: sched.c 项目: bujar/ARM-Gumstix
/**
 * @brief Allocate user-stacks and initializes the kernel contexts of the
 * given threads.
 *
 * This function assumes that:
 * - num_tasks < number of tasks allowed on the system.
 * - the tasks have already been deemed schedulable and have been appropriately
 *   scheduled.  In particular, this means that the task list is sorted in order
 *   of priority -- higher priority tasks come first.
 *
 * @param tasks  A list of scheduled task descriptors.
 * @param size   The number of tasks is the list.
 */
void allocate_tasks(task_t** ptasks, size_t num_tasks)
{
	//set up system tcb for each task in 'tasks' - loop through each task
	uint8_t i;
	runqueue_init();
	dev_init();
	for(i = 1; i <= num_tasks; i++)
	{
		tcb_init(ptasks[i], &system_tcb[i], i);
		runqueue_add(&system_tcb[i], i);
	}

	/* add the idle task */
	idle_init();
}
示例#8
0
/**
 * Initialize this module
 */
void ac_thread_init(ac_u32 max_threads) {
  ac_assert(max_threads > 0);

  max_threads += SYSTEM_THREAD_COUNT;

  ac_uint flags = disable_intr();
  if (max_threads > total_threads) {
    // Create array of the threads
    ac_u32 count = max_threads - total_threads;
    ac_u32 size = sizeof(ac_threads) + (count * sizeof(tcb_x86));
    ac_threads* pnew = ac_malloc(size);
    ac_assert(pnew != AC_NULL);
    pnew->max_count = count;

    // Initialize new entries to AC_THREAD_EMPTY
    for (ac_u32 i = 0; i < count; i++) {
      tcb_init(&pnew->tcbs[i], AC_THREAD_ID_EMPTY, AC_NULL, AC_NULL);
    }

    if (pthreads == AC_NULL) {
      // Add frist set of threads
      pnew->pnext = pnew;
      pnew->pprev = pnew;
      pthreads = pnew;
    } else {
      // Add these new ones to the beginning of the list
      // by adding after the pthreads then move pthreads
      ac_threads* ptmp = pthreads->pnext;
      pnew->pnext = ptmp;
      pnew->pprev = pthreads;
      ptmp->pprev = pnew;
      pthreads->pnext = pnew;

      // Point pthreads at pnew to make it head of the list
      pthreads = pnew;
    }
    total_threads += max_threads;

    // Gurantee all threads can wait simultaneously
    waiting_tcbs_update_max(total_threads);
  }
  restore_intr(flags);
}
示例#9
0
int task_create(
    void (*task_function)(void), 
    stack_item *stack_bottom, int priority)
{
    mem_address task_sp;            /* a stack pointer */ 
    int task_id;            /* task id */ 
    task_control_block tcb; /* TCB to be installed */ 

#ifdef BUILD_ARM_BB
    int n_saved_registers = 14; 
    int n_bytes_per_register = 4; 
#endif
#ifdef BUILD_X86_HOST
    int n_saved_registers = 7; 
    int n_bytes_per_register = 4; 
#endif
#ifdef BUILD_X86_64_HOST
    int n_saved_registers = 5; 
    int n_bytes_per_register = 8; 
#endif
#ifdef BUILD_X86_MAC_HOST
    int n_saved_registers = 5; 
    int n_bytes_per_register = 8; 
#endif

    prepare_stack(stack_bottom, &task_sp, task_function, 
		  n_saved_registers, n_bytes_per_register); 

    /* initialise the tcb */ 
    tcb_init(&tcb, task_sp, priority); 

    /* install the tcb */ 
    task_id = tcb_storage_install_tcb(tcb); 

    /* return task id of created task */ 
    return task_id; 
}