Bar Logo Dual Active Bridge Development Board (Part-No. )
 
Content
     
Loading...
Searching...
No Matches
os_scheduler_100us.c
1
2//=======================================================================================================
3// @file os_scheduler_100us.c
4// @ingroup sched-layer
5// @brief contains the 100µs scheduler that calls all the tasks that need to be called regularly
6// two different timing priorities are available:
7// 1. 100µs and 1ms Tasks called from the scheduler interrupt
8// the jitter that you will have in the 100µs realtime tasks called by the interrupt depends
9// on other interrupts that have a higher interrupt priority
10// the jitter that you will have in the 1ms realtime tasks called by the interrupt depends
11// on other interrupts that have a higher interrupt priority amd by the duration of the
12// 100µs realtime task
13// 2. 100µs, 1ms, 10ms, 100ms, 1s Tasks called from the main loop
14// these tasks are for soft realtime and not for hard realtime
15// so in average they are called with the required timing but the jitter can be very huge,
16// depending on the calls before.
17// use this for your non-timing critical application state machines
18//
19// @note put your application specific code in main/main_scheduler.c
20//
21// @version v1.0
22// @date 2019-08-29
23// @author M52409
24//
25//=======================================================================================================
26
27#include <stdint.h>
28#include <xc.h>
29#include "os_config.h"
30#include "os/os_sys_time.h"
31#if OS_FEATURE_WATCHDOG_ENABLED == 1
32#include "os_watchdog.h"
33#endif
34
35#if OS_USE_SCHEDULER_100us == 1
36
37#ifndef OS_TIMER_NUMBER_OF_TIMERS
38#warning OS_TIMER_NUMBER_OF_TIMERS needs to be defined in main/project_setting.h
39#endif
40#ifndef OS_USE_SYSTIME
41#warning OS_USE_SYSTIME needs to be defined in main/project_setting.h
42#endif
43#include "os/os_scheduler.h"
44#include "timer/tmr1.h"
45
46//=======================================================================================================
47// The following extern Tasks_... functions should be placed in the file main/main_tasks.c
48// call OS_Scheduler_Run() in the main loop or call OS_Scheduler_RunForever() in main.c
49//=======================================================================================================
50//void Tasks_Realtime_100us(void);
51//void Tasks_Realtime_1ms(void);
52//void Tasks_100us(void);
53//void Tasks_1ms(void);
54//void Tasks_10ms(void);
55//void Tasks_100ms(void);
56//void Tasks_1s(void);
57//void Tasks_Background(void);
58
59void TMR1_CallBack(void);
60
61//=======================================================================================================
62//
63// put your application specific code in the file main/main_scheduler.c in the following functions:
64// choose wisely between real-time and non-realtime!
65//
66// Interrupt Realtime Functions:
67// Tasks_Realtime_100us: is called by the 100µs interrupt - for time critical low jitter stuff
68// Tasks_Realtime_1ms : is called by the interrupt every ms - for time critical low jitter stuff
69//
70//
71// Mainloop Non-Realtime Functions:
72// Tasks_100us : function is called by the main loop in average every 100µs
73// Tasks_1ms : function is called by the main loop in average every 1ms
74// Tasks_10ms : function is called by the main loop in average every 10ms
75// Tasks_100ms : function is called by the main loop in average every 100ms
76// Tasks_1s : function is called by the main loop in average every second
77//
78// @note there could be some jitter here because it is not called directly by a timer interrupt
79// the timing in average is exact (keep in mind: in average), the jitter depends on the
80// called functions before
81//=======================================================================================================
82
83#if OS_TIMER_NUMBER_OF_TIMERS > 0
84 void OS_Timer_Tick(void);
85#endif
86
87static volatile uint16_t scheduler_interrupt_leader_100us = 0;
88static volatile uint16_t scheduler_interrupt_follower_100us = 0;
89static volatile uint8_t scheduler_interrupt_realtime_counter_1ms = 0;
90
91#if OS_USE_MCC_TIMER1 == 0
92static inline void OS_Scheduler_Init_Timer1_100us(void)
93{
94 //Switch off Timer 1
95 T1CONbits.TON = 0; // Disable Timer1
96 IEC0bits.T1IE = 0; // Disable Timer1 interrupt
97
98 //Configure Timer 1
99 T1CONbits.TSIDL = 0; // Timer1 Stop in Idle Mode: Continues module operation in Idle mode
100 T1CONbits.TMWDIS = 0; // Asynchronous Timer1 Write Disable: Back-to-back writes are enabled in Asynchronous mode
101 T1CONbits.TMWIP = 0; // Asynchronous Timer1 Write in Progress: Write to the timer in Asynchronous mode is complete
102 T1CONbits.PRWIP = 0; // Asynchronous Period Write in Progress: Write to the Period register in Asynchronous mode is complete
103 T1CONbits.TECS = 0b11; // Timer1 Extended Clock Select: FRC clock
104 T1CONbits.TGATE = 0; // Timer1 Gated Time Accumulation Enable: Gated time accumulation is disabled when TCS = 0
105 T1CONbits.TCKPS = 0; // Timer1 Input Clock Prescale Select: 1:1
106 T1CONbits.TCKPS = 0; // Timer1 Input Clock Prescale Select: 1:1
107 T1CONbits.TSYNC = 0; // Timer1 External Clock Input Synchronization Select: Does not synchronize the External Clock input
108 T1CONbits.TCS = 0; // Timer1 Clock Source Select: Internal peripheral clock
109
110 TMR1 = 0x00; // Reset Timer Counter Register TMR to Zero;
111 PR1 = 9999; // Period = 0.0001 s; Frequency = 100000000 Hz; PR 9999
112
113 IPC0bits.T1IP = 1; // Set interrupt priority to one (cpu is running on ip zero)
114 IFS0bits.T1IF = 0; // Reset interrupt flag bit
115
116 //Switch on Timer 1
117 IEC0bits.T1IE = 1; // Enable Timer1 interrupt
118 T1CONbits.TON = 1; // Enable Timer1
119
120}
121#endif
122
123//=======================================================================================================
128//=======================================================================================================
129void OS_Scheduler_Init(void)
130{
131 #if OS_USE_MCC_TIMER1 == 0
132 OS_Scheduler_Init_Timer1_100us();
133 #endif
134#if OS_USE_SYSTIME == 1
135 OS_SysTime_ResetTime();
136#endif //OS_USE_SYSTIME
137 scheduler_interrupt_leader_100us = 0U; // reset directly before calling the Scheduler Loop
138 scheduler_interrupt_follower_100us = 0U; // reset directly before calling the Scheduler Loop
139
140 TMR1_TimeoutCallbackRegister (TMR1_CallBack); // melody breaks the naming convention, therefore manually registering the name.
141}
142
143
144//=======================================================================================================
150//=======================================================================================================
151#if defined (OS_USE_MCC_TIMER1) && (OS_USE_MCC_TIMER1 == true)
152/* TMR1_CallBack is a weak linked function in the tmr1.c */
153/* LDRA_EXCLUDE 34 D */
154void TMR1_CallBack(void)
155#else
156void __attribute__((__interrupt__,no_auto_psv)) _T1Interrupt(void)
157#endif
158{
159 scheduler_interrupt_leader_100us++; //increment our counter for the scheduler, no tick gets lost
160 _T1IF = 0; //clear Timer1 interrupt flag
161#if OS_TIMER_NUMBER_OF_TIMERS > 0
162 OS_Timer_Tick();
163#endif
164 Tasks_Realtime_100us();
165 scheduler_interrupt_realtime_counter_1ms += 1U;
166 if (scheduler_interrupt_realtime_counter_1ms >= 10U)
167 {
168#if OS_USE_SYSTIME == 1
169 OS_SysTime_IncrementTime_1ms();
170#endif //OS_USE_SYSTIME
172 scheduler_interrupt_realtime_counter_1ms = 0U;
173 }
174}
175
176
177//=======================================================================================================
184//=======================================================================================================
185/* OS_Scheduler_RunOnce() is not called in this application, but is
186 available to do so */
187/* LDRA_EXCLUDE 61 D */
188void OS_Scheduler_RunOnce(void)
189{
190 volatile static uint16_t scheduler_1ms_timer = 0U; // local counter for 1ms tasks
191 volatile static uint16_t scheduler_10ms_timer = 0U; // local counter for 10ms tasks
192 volatile static uint16_t scheduler_100ms_timer = 0U; // local counter for 100ms tasks
193 volatile static uint16_t scheduler_1s_timer = 0U; // local counter for 1s tasks
194
195 //TODO: should we implement a Watchdog that gets triggered in one of the Task-Routines?
196
197 if (scheduler_interrupt_follower_100us != scheduler_interrupt_leader_100us)
198 {
199 scheduler_interrupt_follower_100us += 1U;
200 Tasks_100us(); //call 100µs tasks
201 scheduler_1ms_timer += 1U;
202 if (scheduler_1ms_timer >= 10U)
203 {
204 scheduler_1ms_timer = 0U; //reset 1 ms timer
205 Tasks_1ms(); //call 1 ms tasks
206 scheduler_10ms_timer += 1U;
207 if (scheduler_10ms_timer >= 10U)
208 {
209 scheduler_10ms_timer = 0U; //reset 10 ms timer
210 Tasks_10ms(); //call 10 ms tasks
211 scheduler_100ms_timer += 1U;
212 if (scheduler_100ms_timer >= 10U)
213 {
214 scheduler_100ms_timer = 0U; //reset 100 ms timer
215 Tasks_100ms(); //call 100 ms tasks
216 scheduler_1s_timer += 1U;
217 if (scheduler_1s_timer >= 10U)
218 {
219 scheduler_1s_timer = 0U;
220 #if OS_FEATURE_WATCHDOG_ENABLED == 1
221 OS_Watchdog_KeepAlivePing();
222 #endif
223 Tasks_1s(); //call 1 s tasks
224 }
225 }
226 }
227 }
228 }
229 else
230 {
231 Tasks_Background(); // run the background tasks with their own timing
232 }
233}
234
235
236//=======================================================================================================
243void OS_Scheduler_RunForever(void)
244{
245 // do some initialization
246 scheduler_interrupt_leader_100us = 0U; // reset directly before calling the Scheduler Loop
247 scheduler_interrupt_follower_100us = 0U; // reset directly before calling the Scheduler Loop
248
249 /*The while loop below is intended to run forever therefore 28 D is
250 excluded */
251 /* LDRA_EXCLUDE 28 D */
252 while (1) // run that loop forever
253 {
254 OS_Scheduler_RunOnce();
255 }
256}
257
258#endif //OS_USE_SCHEDULER_100us
void __attribute__((weak))
Definition adc1.c:569
This is the generated driver header file for the TMR1 driver.
void Tasks_10ms(void)
Tasks_10ms gets called every 10ms, put your things in it that need to be called regularly.
Definition main_tasks.c:127
void Tasks_1ms(void)
Tasks_1ms gets called every millisecond, put your things in it that need to be called regularly.
Definition main_tasks.c:115
void Tasks_Realtime_1ms(void)
Tasks_Realtime_1ms gets called directly from the timer interrupt every millisecond.
Definition main_tasks.c:90
void Tasks_100ms(void)
Tasks_100ms gets called every 100 ms, put your things in it that need to be called regularly.
Definition main_tasks.c:141
void Tasks_Background(void)
Tasks_Background gets called all the time when no other of the above tasks are being called.
Definition main_tasks.c:170
void Tasks_1s(void)
Tasks_1s gets called every second, put your things in it that need to be called regularly.
Definition main_tasks.c:155
void TMR1_TimeoutCallbackRegister(void(*handler)(void))
This function can be used to override default callback and to define custom callback for TMR1 Timeout...
Definition tmr1.c:124