Esempio n. 1
0
int init_sys(void)
{
    SCB->CCR |= SCB_CCR_STKALIGN_Msk; // enable double word stack alignment
 
    PSP_array[0] = ((unsigned int)task0_stack) + (sizeof task0_stack) - 16*4; // top of stack
    HW32_REG((PSP_array[0] + (14<<2))) = (unsigned long)task0; // initial Program Counter
    HW32_REG((PSP_array[0] + (15<<2))) = 0x01000000;           // initial PSR
 
    PSP_array[1] = ((unsigned int)task1_stack) + (sizeof task1_stack) - 16*4;
    HW32_REG((PSP_array[1] + (14<<2))) = (unsigned long)task1;
    HW32_REG((PSP_array[1] + (15<<2))) = 0x01000000;
 
    curr_task = 0;
    __set_PSP((PSP_array[curr_task] + 16*4)); // set PSP to top of stack
    NVIC_SetPriority(PendSV_IRQn, 0xFF);
    SysTick_Config(168000);
 
    __set_CONTROL(0x3);
 
    __ISB();
 
    task0();
 
    /*while(1) {
        stop_cpu;
    }; */
}
Esempio n. 2
0
int unused_addresses_test_single(unsigned int address)
{
  if (HW32_REG(address) != 0) return (1);
  HW32_REG(address) = 0xFFFFFFFF;
  if (HW32_REG(address) != 0) return (1);
  else return (0);
}
Esempio n. 3
0
/* Use ID value to detect if the system controller is present */
int sysctrl_id_check(void)
{ /* CMSDK SysCtrl part ID range from 826 to 829 */
#define HW32_REG(ADDRESS)  (*((volatile unsigned long  *)(ADDRESS)))
if ((HW32_REG(CMSDK_SYSCTRL_BASE + 0xFE0) < 0x26) ||
    (HW32_REG(CMSDK_SYSCTRL_BASE + 0xFE0) > 0x29) ||
    (HW32_REG(CMSDK_SYSCTRL_BASE + 0xFE4) != 0xB8))
  return 1; /* part ID does not match */
else
  return 0;
}
Esempio n. 4
0
int gpio0_id_check(void)
{
unsigned char gpio_id;

  gpio_id = HW8_REG(CMSDK_GPIO0_BASE  + 0xFE8) & 0x07;

  if ((HW32_REG(CMSDK_GPIO0_BASE + 0xFE0) != 0x20) ||
      (HW32_REG(CMSDK_GPIO0_BASE + 0xFE4) != 0xB8) ||
      (gpio_id != 0x03))
    return 1; /* part ID & ARM ID does not match */
  else
    return 0;
}
/*! 
    \brief C part of the SVC exception handler

     SVC 0 is initializing the OS and starting the scheduler.
     Each thread stack frame is initialized.
     
    \param svc_args Used to extract the SVC number 
*/
void SVC_Handler_C(unsigned int * svc_args)
{
  uint8_t svc_number;
  svc_number = ((char *) svc_args[6])[-2]; // Memory[(Stacked PC)-2]
	// marking kernel as busy
	kernel_busy = 1;
  switch(svc_number) {
		
		//************* SVC( 0 )   OS Start	
    case (0): // OS start		  
 	    // Starting the task scheduler
		  //TWP  playing a trick here!? by making curr = next, will make next's stack and current's stack the same stack!
		  //   will save (garbage) current register values, and then immediately restore them as next's initial values :-)
		curr_task = rtr_q_h; // Switch to head ready-to-run task (Current task)		
		//     when current task was put in RTRQ its state was set to RUNNING 
		  
		svc_exc_return = HW32_REG(( curr_task->stack_p )); // Return to thread with PSP
		__set_PSP(( (uint32_t) curr_task->stack_p + 10*4));  // Set PSP to @R0 of task 0 exception stack frame

		NVIC_SetPriority(PendSV_IRQn, 0xFF);       // Set PendSV to lowest possible priority
		if (SysTick_Config(os_sysTickTicks) != 0)  // 1000 Hz SysTick interrupt on 16MHz core clock
			{
				stop_cpu2;
				// Impossible SysTick_Config number of ticks
			}
		__set_CONTROL(0x3);                  // Switch to use Process Stack, unprivileged state
		__ISB();       // Execute ISB after changing CONTROL (architectural recommendation)			
		break;
		
		//************* SVC( 1 )	Thread Yield
    case (1): // Thread Yield
		if (curr_task != rtr_q_h)
			{ 
				// Context switching needed
				ScheduleContextSwitch();
			}		
		__ISB();       					
		break;
    
		//************* SVC( 2 )    Stack Frame Allocation for First Launch
		//TWPV6: no longer used!  Functionality moved to osThreadCreate ... case left here (for now) 
    case (2): // Stack Allocation
		__ISB();       			
		break;			
    default:
#if ((ENABLE_KERNEL_PRINTF) && (ENABLE_KERNEL_PRINTF == 1))
		printf("ERROR: Unknown SVC service number\n\r");
		printf("- SVC number 0x%x\n\r", svc_number);
#endif
		stop_cpu2;
		break;
  } // end switch
	
	// marking kernel as normal
	kernel_busy = 0;
}	
Esempio n. 6
0
int sram_test_word(unsigned int test_addr)
{
  int result=0; // This will only work if result and temp are not store in address being tested
  int temp;

  __disable_irq(); // Make sure interrupt will not affect the result of the test

  temp = HW32_REG(test_addr); // save data

  /* Use consistence memory access size in checking so that it work with
    both little endian and big endian configs */
  HW32_REG(test_addr)=0x00000000;
  if (HW32_REG(test_addr)!=0x00000000) result++;
  HW16_REG(test_addr)=0xFFFF;
  if (HW16_REG(test_addr)!=0xFFFF) result++;
  HW8_REG(test_addr+3)=0x12;
  HW8_REG(test_addr+2)=0xFF;
  if (HW8_REG(test_addr+3)!=0x12) result++;
  if (HW8_REG(test_addr+2)!=0xFF) result++;
  HW8_REG(test_addr  )=0x00;
  HW8_REG(test_addr+1)=0x00;
  if (HW8_REG(test_addr  )!=0x00) result++;
  if (HW8_REG(test_addr+1)!=0x00) result++;
  HW16_REG(test_addr+2)=0xFE00;
  if (HW16_REG(test_addr+2)!=0xFE00) result++;
  HW32_REG(test_addr)=0x00000000;
  if (HW32_REG(test_addr)!=0x00000000) result++;

  HW32_REG(test_addr) = temp; // restore data
  __enable_irq(); // re-enable IRQ
  if (result !=0) printf ("ERROR: Memory location test failed at %x\n", test_addr);
  return result;
}
Esempio n. 7
0
/* ----------------------------------------------------------------- */
void HardFault_Handler(void)
{
  unsigned int dummy; /* dummy variable for read that trigger hardfault */

  puts("[Hard fault handler]");
  puts("- trigger fault again to enter lockup");

  /* Trigger lockup */
  dummy=HW32_REG(BAD_ADDRESS);
  puts ("ERROR: Lockup not triggered");

  UartEndSimulation();
    /* Simulation stops in UartEndSimulation */
}
Esempio n. 8
0
/* Check the ID register value in offset 0xFC0 to 0xFFC (last 16 words, last 12 are IDs) */
int SysCtrl_ID_Check(const unsigned char id_array[], unsigned int offset)
{
  int i; /* loop counter */
  unsigned long expected_val, actual_val;
  unsigned long compare_mask;
  int           mismatch = 0;
  int           id_is_zero = 0;
  unsigned long test_addr;

  /* Check the peripheral ID and component ID */
  for (i=0;i<16;i++) {
    test_addr = offset + 4*i + 0xFC0;
    expected_val = (int) id_array[i];
    actual_val   = HW32_REG(test_addr);

    if (actual_val == 0) id_is_zero++; // Check if all ID are zero at the end

    /* create mask to ignore version numbers */
    if      (i==10) { compare_mask = 0xF0;}  // mask out version field
    else if (i==11) { compare_mask = 0xFF;}  // mask out ECO field and patch field
    else            { compare_mask = 0x00;}  // compare whole value

    if (i==8) {
      /* The part number of the example system controller in CMSDK can be
      26 to 29 */
      if ((actual_val<0x26)||(actual_val>0x29)) {
        printf ("Difference found: %x, expected 0x26 to 0x29, actual %x\n", test_addr, actual_val);
        mismatch++;
      }
    }
    else {
      if ((expected_val & (~compare_mask)) != (actual_val & (~compare_mask))) {
        printf ("Difference found: %x, expected %x, actual %x\n", test_addr, expected_val, actual_val);
        mismatch++;
      }
    } // end_if_i_eq_8
  } // end_for

  if (id_is_zero == 16) {
    puts ("  All ID values are 0   : device not present\n");
    return 2;
  } else if (mismatch> 0) {
    puts ("  ID value mismatch(es) : device unknown\n");
    return 1;
  } else {
    puts ("  All ID values matched : device present\n");
    return 0;
  }
}
Esempio n. 9
0
/* Second part of the main test program - execute after SYSRESETREQ reset */
void main_prog_part_2(void)
{
  int result=0;
  unsigned int read_data;

  puts("- Self reset completed");
  read_data = CMSDK_SYSCON->RSTINFO;
  printf ("  SYSCON->RSTINFO = %x\n", read_data);
  if (read_data != CMSDK_SYSCON_RSTINFO_SYSRESETREQ_Msk) result++;
  puts("- Clear reset info");
  CMSDK_SYSCON->RSTINFO = CMSDK_SYSCON_RSTINFO_SYSRESETREQ_Msk;
  read_data = CMSDK_SYSCON->RSTINFO;
  printf ("  SYSCON->RSTINFO = %x\n", read_data);
  if (read_data != 0) result++;
  if (result != 0) {
    puts ("ERROR: reset info register value incorrect.\n");
  } else {
    puts ("SYSRESETREQ test done\nNow test reset caused by lockup\n");
  }

  /* Test Lockup reset */
  CMSDK_SYSCON->RESETOP = CMSDK_SYSCON_LOCKUPRST_RESETOP_Msk;
  read_data = CMSDK_SYSCON->RESETOP;
  if (read_data != CMSDK_SYSCON_LOCKUPRST_RESETOP_Msk) {
    puts ("ERROR: reset option register value incorrect.\n");
    UartEndSimulation();
    }
  read_data = CMSDK_SYSCON->RSTINFO;
  if (read_data != 0) {
    puts ("ERROR: reset info register value incorrect.\n");
    UartEndSimulation();
    }

  /* Trigger hard fault */
  read_data=HW32_REG(BAD_ADDRESS);

  puts ("ERROR: Hard fault not triggered");

  UartEndSimulation();
    /* Simulation stops in UartEndSimulation */

  return;
}
Esempio n. 10
0
/*! 
    \brief C part of the SVC exception handler

     SVC 0 is initializing the OS and starting the scheduler.
     Each thread stack frame is initialized.
     
    \param svc_args Used to extract the SVC number 
*/
void SVC_Handler_C(unsigned int * svc_args)
{
  uint8_t svc_number, i;	
  svc_number = ((char *) svc_args[6])[-2]; // Memory[(Stacked PC)-2]
	// marking kernel as busy
	kernel_busy = 1;
  switch(svc_number) {
    case (0): // OS start		  
 	    // Starting the task scheduler
			// Update thread to be run based on priority
	    scheduler();
      curr_task = next_task; // Switch to head ready-to-run task (Current task)		
			th_q_h = curr_task;
			th_q[curr_task]->status = TH_RUNNING;
		  if (PSP_array[curr_task] == NULL)
			{
				// Stack not allocated for current task, allocating
				i = curr_task;
				th_q[i]->stack_p = (uint32_t) task_stack[i];
				PSP_array[i] = ((unsigned int) th_q[i]->stack_p) + (th_q[i]->stack_size) - 18*4;
				HW32_REG((PSP_array[i] + (16<<2))) = (unsigned long) th_q[i]->start_p; // initial Program Counter
				HW32_REG((PSP_array[i] + (17<<2))) = 0x01000000;            // initial xPSR
				HW32_REG((PSP_array[i]          )) = 0xFFFFFFFDUL;          // initial EXC_RETURN
				HW32_REG((PSP_array[i] + ( 1<<2))) = 0x3;// initial CONTROL : unprivileged, PSP	
				
				th_q[i]->stack_p = PSP_array[i];				
			}

			svc_exc_return = HW32_REG((PSP_array[curr_task])); // Return to thread with PSP
			__set_PSP((PSP_array[curr_task] + 10*4));  // Set PSP to @R0 of task 0 exception stack frame

      NVIC_SetPriority(PendSV_IRQn, 0xFF);       // Set PendSV to lowest possible priority
      if (SysTick_Config(os_sysTickTicks) != 0)  // 1000 Hz SysTick interrupt on 16MHz core clock
			{
				stop_cpu2;
				// Impossible SysTick_Config number of ticks
			}
      __set_CONTROL(0x3);                  // Switch to use Process Stack, unprivileged state
      __ISB();       // Execute ISB after changing CONTROL (architectural recommendation)			
		  break;
    case (1): // Thread Yield
			// Run scheduler to determine if a context switch is needed
			scheduler();		  
			if (curr_task != next_task)
			{ 
				// Context switching needed
				ScheduleContextSwitch();
		  }		
      __ISB();       					
			break;
    case (2): // Stack Allocation
      // Create stack frame for thread
		  i = svc_args[0];  

			th_q[i]->stack_p = (uint32_t) task_stack[i];
			PSP_array[i] = ((unsigned int) th_q[i]->stack_p) + (th_q[i]->stack_size) - 18*4;
			HW32_REG((PSP_array[i] + (16<<2))) = (unsigned long) th_q[i]->start_p; // initial Program Counter
			HW32_REG((PSP_array[i] + (17<<2))) = 0x01000000;            // initial xPSR
			HW32_REG((PSP_array[i]          )) = 0xFFFFFFFDUL;          // initial EXC_RETURN
			HW32_REG((PSP_array[i] + ( 1<<2))) = 0x3;// initial CONTROL : unprivileged, PSP		
			
			th_q[i]->stack_p = PSP_array[i];
      __ISB();       			
			break;			
    default:
#if ((ENABLE_KERNEL_PRINTF) && (ENABLE_KERNEL_PRINTF == 1))
      printf("ERROR: Unknown SVC service number\n\r");
      printf("- SVC number 0x%x\n\r", svc_number);
#endif
      stop_cpu2;
      break;
  } // end switch
	
	// marking kernel as normal
	kernel_busy = 0;
}	
Esempio n. 11
0
/* Simple test for APB test slave */
int APB_test_slave_Check(unsigned int offset)
{
  /*
  The APB test slave has got only one 32-bit register in
  the first four addresses. For each word, the wait state
  increase based on PADDR[3:2].

  The test slave is also able to generate error responses
  at offset 0x0F0 to 0xFC.
  */
  int  mismatch = 0;
  int  fault_err = 0;
  int  i;

  // Read/Write test to data_register
  HW32_REG(offset)   = 0xFFFFFFFF;
  if ((HW32_REG(offset))   !=0xFFFFFFFF) mismatch ++;
  HW32_REG(offset)   = 0x00000000;
  if ((HW32_REG(offset))   !=0x00000000) mismatch ++;
  HW32_REG(offset)   = 0x12345678;
  if ((HW32_REG(offset))   !=0x12345678) mismatch ++;
  HW16_REG(offset)   = 0x5678; /* Use consistent access size.
    This is required to allow the test to run in big endian */
  if ((HW16_REG(offset))   !=0x5678)     mismatch ++;
  HW16_REG(offset+2) = 0x1234; /* Use consistent access size.*/
  if ((HW16_REG(offset+2)) !=0x1234)     mismatch ++;
  HW8_REG(offset)   = 0x78; /* Use consistent access size between read and write.*/
  HW8_REG(offset+1) = 0x56;
  HW8_REG(offset+2) = 0x34;
  HW8_REG(offset+3) = 0x12;
  if ((HW8_REG(offset))    !=0x78)       mismatch ++;
  if ((HW8_REG(offset+1))  !=0x56)       mismatch ++;
  if ((HW8_REG(offset+2))  !=0x34)       mismatch ++;
  if ((HW8_REG(offset+3))  !=0x12)       mismatch ++;
  HW16_REG(offset+4) = 0xFFFF; // Value = 0x1234FFFF
  if ((HW16_REG(offset+8)) !=0xFFFF)     mismatch ++;
  HW16_REG(offset+6) = 0x0000; // Value = 0x0000FFFF
  if ((HW16_REG(offset+4))   !=0xFFFF)   mismatch ++;
  if ((HW16_REG(offset+6))   !=0x0000)   mismatch ++;
  HW8_REG(offset+8)   = 0xA5;  // Value = 0x0000FFA5
  if ((HW8_REG(offset+8))   !=0xA5)      mismatch ++;
  HW8_REG(offset+0xD) = 0xC3;  // Value = 0x0000C3A5
  if ((HW8_REG(offset+0xD)) !=0xC3)      mismatch ++;
  HW16_REG(offset+0xE)= 0xC53A;// Value = 0xC53AC3A5
  if ((HW16_REG(offset+0xE)) !=0xC53A)   mismatch ++;

  /* Testing of error response from APB test slave */
  for (i=0; i<4; i++) {
    temp_data=0;
    hardfault_expected = 1;
    hardfault_occurred = 0;
    address_test_write((offset + 0xF0 + (i<<2)), 0x0);
    if (hardfault_occurred==0) fault_err++;
    hardfault_occurred = 0;
    temp_data=address_test_read(offset + 0xF0 + (i<<2));
    if (hardfault_occurred==0) fault_err++;
    }

  hardfault_expected = 0;
  hardfault_occurred = 0;

  if (mismatch>0) { puts ("  Data mismatch in APB test slave\n");
                    return 1;}
  if (fault_err>0){ puts ("  Fault mismatch in APB test slave\n");
                    return 1;}
  else            puts ("  APB test slave test passed\n");

  return 0;
}