round robin scheduler, systick_attach_callback

Post your cool example code here.
Post Reply
ag123
Posts: 795
Joined: Thu Jul 21, 2016 4:24 pm

round robin scheduler, systick_attach_callback

Post by ag123 » Wed May 24, 2017 8:08 pm

recently i'm trying to use systick_attach_callback to insert a systick handler, i noted:
STM32F1/cores/maple/libmaple/systick.c

Code: Select all

...
/**
 * @brief Attach a callback to be called from the SysTick exception handler.
 *
 * To detach a callback, call this function again with a null argument.
 */
void systick_attach_callback(void (*callback)(void)) {
    systick_user_callback = callback;
}

/*
 * SysTick ISR
 */

void __exc_systick(void) {
    systick_uptime_millis++;
    if (systick_user_callback) {
        systick_user_callback();
    }
}
^^^ this is nice in that the original systick handler won't be affected
however, i found that the function prototype is missing from - fixed see roger's comment's in post below
STM32F1/system/libmaple/include/libmaple/systick.h

Code: Select all

extern void systick_attach_callback(void (*callback)(void));
systick_attach_callback() is very useful if you want to implement some kind of 'round robin scheduler' instead of say using a context-switching RTOS which has quite a bit of memory bulk as it needs the memory to save the states and stacks of the tasks and handle all the context switches.

i've implemented a little scheduler like this:

Code: Select all

int8 systick_fired;

void setup() {
	systick_attach_callback(systick_handler);
	systick_fired = 0;
}

void loop() {
	//interrupts();
	if(systick_fired) {
		systick_fired = 0;
		run_task1();
		run_task2();
		run_task3();
	}
	//noInterrupts();
	//wait for interrupts and events
	asm("wfe");
}

void systick_handler(void) {
	systick_fired++;
}
the trick here is that systick_handler call back which i register using systick_attach_callback() updates a variable systick_fired. then in the last statement in my arduino loop(), i called asm("wfe"); i.e. wait for events (and interrupts). the cpu would simply pause at asm("wfe"); and wait for interrupts. when systick interrupt or any other interrupt is received, "wfe" would wake and run the interrupt handler and later continue after "wfe".
then i check the variable systick_fired if systick has indeed fired. i find this a nice little nifty scheduler with arduino codes. it is (very) memory efficient compared to say usnig a context-switching RTOS.

note that one should not put lots of codes in systick_handler() as that function runs in the systick interrupt itself. the main loop() runs in 'thread' mode in which i used "wfe" to wait for that interrupt. this is so that all the processing would always happen in loop() (thread mode) even if i simply want to do something after the systick interrupt.

just 2 cents :)
Last edited by ag123 on Sat Jun 03, 2017 5:30 pm, edited 3 times in total.

victor_pv
Posts: 1734
Joined: Mon Apr 27, 2015 12:12 pm

Re: libmale core:STM32F1 systick_attach_callback

Post by victor_pv » Wed May 24, 2017 9:24 pm

That function is currently used by FreeRTOS and CoOS to hook the context switch handlers.
It is working in the current version of the repo, so I wonder if the prototype is in some other file.

Also remember if you decide to use our current versions of FreeRTOS or CoOs that they need their own handler attached there, so you would have to attach your function somewhere else, or use the OS timers for that.

User avatar
RogerClark
Posts: 7413
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: libmale core:STM32F1 systick_attach_callback

Post by RogerClark » Wed May 24, 2017 9:45 pm

I'm happy to add a prototype if needed.

But it sounds like we need to find out whether the prototype is defined elsewhere in case defining it again breaks RTOS etc

ag123
Posts: 795
Joined: Thu Jul 21, 2016 4:24 pm

Re: libmale core:STM32F1 systick_attach_callback

Post by ag123 » Thu May 25, 2017 5:07 am

at the moment if i did not declare the function prototype, i get

Code: Select all

error: 'systick_attach_callback' was not declared in this scope
but no worries, i've resolved it within my codes within my cpp/sketch file

Code: Select all

extern "C"{
	extern void systick_attach_callback(void (*callback)(void));
}
i did a text search but did not find the function prototype defined elsewhere. However, it is indeed used in FreeRTOS.
it looks like it may be my own setup as i'm working in eclipse.

@victor
agreed if FreeRTOS is in use, we should not call systick_attach_callback as it would break FreeRTOS
in this case my sketch effectively takes over the role of the scheduler and hence won't work with FreeRTOS.
i've created this little 'round robin scheduler' as i run out of memmory on maple mini
As it turns out FreeRTOS allocates 8k of ram to keep the task stacks, states and context switching info, this is actually modest.
the only trouble would be if i try to allocate some rather large fifo buffer as a global variable, blocks of memory gets consumed rapidly and i run out of memory.

using my 'round robin scheduler' isn't all that simple actually. it relies on 'co-operative multitasking' and the individual tasks needs to keep its own states (as global variables) as those tasks are ordinary c functions or c++ methods that runs once (no infinite loops within). this is unlike freertos in which the task runs a loop that doesn't exit.

i had to say that using FreeRTOS is 'easier' as FreeRTOS handles the tasks and context switches much like desktop os, this is a major advantage and it is really good that it actually works on stm32f103. however, this comes at a cost of memory efficiency as FreeRTOS would need to keep the full execution stack (all the cascading calls) and various other state / context info and it would also need to pretty much pre-allocate these memory to run the tasks.

'round robin scheduler' in contrast needs an 'event loop' and all the tasks are c++ objects which needs to keep its own states. programming is 'harder' and dramatically different (it feels like a programming style of some network protocol stacks in which one needs to draw up a state transition diagram for each task). the memory efficiency is simply because as a result of this style, all the stacks are unwound between tasks and each task use its own small set of global variables, often just some integers, to keep state.

just 2 cents

User avatar
RogerClark
Posts: 7413
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: libmale core:STM32F1 systick_attach_callback

Post by RogerClark » Thu May 25, 2017 5:33 am

I can't find a prototype either. I only find the function and 4 places its used (including 1 macro)

Code: Select all

Search "systick_attach_callback" (5 hits in 5 files)
  D:\Documents\Arduino\hardware\Arduino_STM32\STM32F1\cores\maple\libmaple\systick.c (1 hit)
	Line 75: void systick_attach_callback(void (*callback)(void)) {
  D:\Documents\Arduino\hardware\Arduino_STM32\STM32F1\libraries\FreeRTOS\utility\port.c (1 hit)
	Line 178: 	systick_attach_callback(&xPortSysTickHandler);
  D:\Documents\Arduino\hardware\Arduino_STM32\STM32F1\libraries\FreeRTOS821\utility\port.c (1 hit)
	Line 345: 	systick_attach_callback(&xPortSysTickHandler);
  D:\Documents\Arduino\hardware\Arduino_STM32\STM32F1\libraries\MapleCoOS\utility\OsCore.c (1 hit)
	Line 179: 	systick_attach_callback(&CoSysTick_Handler);
  D:\Documents\Arduino\hardware\Arduino_STM32\STM32F1\libraries\MapleCoOS116\utility\OsArch.h (1 hit)
	Line 52: #define InitSysTick()		systick_attach_callback(&CoSysTick_Handler)
I think the best thing to do is to add the prototype as described by @ag123 and then see if FreeRTOS has any compile problems

ag123
Posts: 795
Joined: Thu Jul 21, 2016 4:24 pm

Re: libmale core:STM32F1 systick_attach_callback

Post by ag123 » Thu May 25, 2017 5:43 am

i think it may be a 'good thing' to declare this function prototype in the header file. as it stands it isn't even part of the original leaflabs documentation
http://docs.leaflabs.com/static.leaflab ... le-systick
i'm guessing if this may be after all victor's invention :lol:

the only catch may be that the other apps which is using the function currently, hopefully won't run into compile errors. notably the RTOSes

victor_pv
Posts: 1734
Joined: Mon Apr 27, 2015 12:12 pm

Re: libmale core:STM32F1 systick_attach_callback

Post by victor_pv » Thu May 25, 2017 6:05 am

ag123 wrote:at the moment if i did not declare the function prototype, i get

Code: Select all

error: 'systick_attach_callback' was not declared in this scope
but no worries, i've resolved it within my codes within my cpp/sketch file

Code: Select all

extern "C"{
	extern void systick_attach_callback(void (*callback)(void));
}
i did a text search but did not find the function prototype defined elsewhere. However, it is indeed used in FreeRTOS.
it looks like it may be my own setup as i'm working in eclipse.

@victor
agreed if FreeRTOS is in use, we should not call systick_attach_callback as it would break FreeRTOS
in this case my sketch effectively takes over the role of the scheduler and hence won't work with FreeRTOS.
i've created this little 'round robin scheduler' as i run out of memmory on maple mini
As it turns out FreeRTOS allocates 8k of ram to keep the task stacks, states and context switching info, this is actually modest.
the only trouble would be if i try to allocate some rather large fifo buffer as a global variable, blocks of memory gets consumed rapidly and i run out of memory.

using my 'round robin scheduler' isn't all that simple actually. it relies on 'co-operative multitasking' and the individual tasks needs to keep its own states (as global variables) as those tasks are ordinary c functions or c++ methods that runs once (no infinite loops within). this is unlike freertos in which the task runs a loop that doesn't exit.

i had to say that using FreeRTOS is 'easier' as FreeRTOS handles the tasks and context switches much like desktop os, this is a major advantage and it is really good that it actually works on stm32f103. however, this comes at a cost of memory efficiency as FreeRTOS would need to keep the full execution stack (all the cascading calls) and various other state / context info and it would also need to pretty much pre-allocate these memory to run the tasks.

'round robin scheduler' in contrast needs an 'event loop' and all the tasks are c++ objects which needs to keep its own states. programming is 'harder' and dramatically different (it feels like a programming style of some network protocol stacks in which one needs to draw up a state transition diagram for each task). the memory efficiency is simply because as a result of this style, all the stacks are unwound between tasks and each task use its own small set of global variables, often just some integers, to keep state.

just 2 cents
Yeah the 20KB are pretty tight, but on the other hand the FreeRTOS doesn't use that much of the 8KB, so if you only have a few tasks, and few or no semaphores, queues, etc, you can reduce the size. There is a option for FreeRTOS to keep a low water mark of how much stack each task uses, so you can also adjust each task stak to what's needed.

In any case, the round robin scheduler seems definitely useful for small tasks that wont block each other. Thanks for sharing it.

About the prototype, I wonder how FreeRTOS just works, but could be that the prototype is being added automatically when missing?
I have used FreeRTOS with the Eclipse Arduino plugin and all worked. But we get so many warnings that I just skip thru anything that's not an "error", I bet one of those hundred warnings is one saying it can't find the prototype :lol:

ag123
Posts: 795
Joined: Thu Jul 21, 2016 4:24 pm

Re: libmale core:STM32F1 systick_attach_callback

Post by ag123 » Thu May 25, 2017 6:26 am

actually it isn't new, the inspiration comes from 'the one line rtos' :lol:
http://scitechconnect.elsevier.com/the-one-line-rtos/

User avatar
RogerClark
Posts: 7413
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: libmale core:STM32F1 systick_attach_callback

Post by RogerClark » Thu May 25, 2017 8:04 am

ag123 wrote:actually it isn't new, the inspiration comes from 'the one line rtos' :lol:
http://scitechconnect.elsevier.com/the-one-line-rtos/
I've committed the change to add the prototype to systick.h (as per your example)

I've tested with the FreeRTOS blink exmaple and it compiles and runs fine for me.

I can't test on COOS as the demo's in the repo don't seem to compile any more due to unrelated problems.

I will add the COOS demo issue to the issues list on github

ag123
Posts: 795
Joined: Thu Jul 21, 2016 4:24 pm

Re: libmale core:STM32F1 systick_attach_callback

Post by ag123 » Thu May 25, 2017 8:26 am

thanks roger, i just did a rebuild with FreeRTOS 9 with the function prototype declared in systick.h and i'm observing the same. no errors.

i think it should be ok to declare the function prototype as after all all the (RTOS) libraries are calling the same function, and there isn't any other definitions.

just 2 cents

Post Reply