#include "./os_cpu.h" #include "./os_cfg.h" #include "./ucos_ii.h" #include "nios_peripherals.h" #ifdef ONT_GLOBALS #define ONT_EXT #else #define ONT_EXT extern #endif typedef struct { char TaskName[30]; INT16U TaskCtr; INT16U TaskExecTime; INT32U TaskTotExecTime; } TASK_USER_DATA; ONT_EXT TASK_USER_DATA TaskUserData[10]; //Function Prototypes #define STACKSIZE 2048 OS_STK Stack1[STACKSIZE]; OS_STK Stack2[STACKSIZE]; OS_EVENT *Sem1; OS_EVENT *Sem2; OS_EVENT *Sem3; OS_EVENT *Sem4; OS_EVENT *Sem5; OS_EVENT *PrintSem; void controller(void *i) { INT8U Reply; //Enable interrupts here, must be after OSstart() for(;;) { OSSemPend(Sem1,0,&Reply); //wait indefinitely for Sem1 //Sem1 is decremented if Sem1 is avaiable . . . //read sensor outputs //calculate control values //output control values to actuators //assume all work above is done within 2 seconds } } void alarms(void *i) { INT8U Reply; for(;;) { OSSemPend(Sem2,0,&Reply); . . . //do work } } void hourly_log(void *i) { INT8U Reply; for(;;) { OSSemPend(Sem4,0,&Reply); . .OSSemPend(PrintSem, 0, &Reply); //use printer OSSemPost(PrintSem); . } } void ten_minute_log(void *i) { INT8U Reply; for(;;) { OSSemPend(Sem3,0,&Reply); . . OSSemPend(PrintSem, 0, &Reply); //use printer OSSemPost(PrintSem); } } //Handle interrupt generated on interrupt from operator device Void Operator_ISR_Handle() { OSIntEnter() clear the interrupting device; Re-enable interrupts OSSemPost(Sem5); OSIntExit(); } void operator_interface(void *i) { INT8U Reply; for(;;) { OSSemPend(Sem5,0,&Reply); //the max rate at which this task is executed in between //the controller task active states //If printer is necessary OSSemPend(PrintSem, 0, &Reply); //use printer OSSemPost(PrintSem); { } int main(int argc,char**argv) { char Id1 = '1'; char Id2 = '2'; char Id3 = '3'; char Id4 = '4'; char Id5 = '5'; #if NIOS_GDB nios_gdb_install(1); nios_gdb_breakpoint(); #endif OSInit(); Sem1=OSSemCreate(1); Sem2=OSSemCreate(1); Sem3=OSSemCreate(1); Sem4=OSSemCreate(1); Sem5=OSSemCreate(1); PrintSem = OSSemCreate(1); OSTaskCreate(controller, (void *)&Id1,(void *)&Stack1[STACKSIZE-1],1); OSTaskCreate(alarms, (void *)&Id2,(void *)&Stack2[STACKSIZE-1],2); OSTaskCreate(hourly_log, (void *)&Id3,(void *)&Stack3[STACKSIZE-1],4); OSTaskCreate(ten_minute_log, (void *)&Id4,(void *)&Stack4[STACKSIZE-1],3); OSTaskCreate(operator_interface, (void *)&Id5,(void *)&Stack5[STACKSIZE-1],5); OSStart(); } //modify OSTimeTickHook() in OS_CPU_C.c void OSTimeTickHook (void) { //controller must run every 2 seconds (2*200=400 ticks), //assuming OS has been configured for 200 OS clock //ticks per second. static int controller_ticks = 400; //Do the same for the other time critical tasks static int alarms_ticks = 800; static int ten_log_ticks = 120000; //assume int is four bytes; static int hour_log_ticks = 720000; controller_ticks--; if (!controller_ticks) { OSSemPost(Sem1); controller_ticks = 400; } alarms_ticks--; if (!alarms_ticks) { OSSemPost(Sem2); alarms_ticks = 800; } ten_log_ticks--; if (!ten_log_ticks) { OSSemPost(Sem3); ten_log_ticks = 120000; } hour_log_ticks--; if (!hour_log_ticks) { OSSemPost(Sem4); hour_log_ticks = 720000; } }