2020-08-02

2020-07-31 Longan Nano GD32VF103 Chrono Class and Scheduler

>>>Longan Nano GD32VF103<<<

Longan Nano GD32VF103 Risc-V 108MHz 32b MCU toolchain, libraries and applications

>>>Longan Nano Chrono Class and Scheduler<<<


Chrono C++ Class uses the 64bit 27MHz systick timer to provide high resolution elapsed time and eaccumulate time HAL methods.

The Demo shows how to implement a fixed function scheduler with overrun and profiling using the Chrono C++ Class.



1Introduction

I use microcontrollers to perform fixed hard real time functions, in which a given list of tasks are executed always at the same rate in the same order, with little variation due to communication with the master.

With the AT4809 and previous microcontroller, I used an internal timer to issue the fast tick as an interrupt service routine, and from that tick, generate all the flags to execute slower tasks.

E.G. The PID running at 4KHz started by a fast tick at 4KHz, the LED running at 2Hz started by prescaling the 4KHz fast tick by 2000.

Illustration 1: Fast Tick issue execution of fixed tasks

With the Longan Nano I have a 64bit 27MHz fast tick timer at my disposal.


2Chrono Class

I decided to create an abstraction layer in class form since I'm practising with C++.

The class embeds two high resolution 64 bit timestamps.

The class uses scoped enums to encapsulate the configurations and definitions inside the namespace and class name e.g. the time unit is: Longan_nano::Chrono::Unit::microseconds


2.1Time Elapsed Mode

One of the core function of the class is to compute how much time has elapsed between two instants of time.

Use:

  • A timer has to be instantiated. Longan_nano::Chrono my_timer;

  • my_timer.start() followed by my_timer.stop() fill the timestamps. my_timer.get_elapsed( Unit ) returns the DeltaT between stop and start

  • my_timer.start() followed by my_timer.stop( Unit ) returns the DeltaT between stop and start


2.2Time Accumulation mode

Another thing the user may want to do is to integrate the time spent doing something to profile execution times or measure something happening in bursts.

The accumulation method has a special flag to use the internal 64 bit timestamps to do this integration at full sub microsecond resolution. This is much better than having the user integrate the rounded results of the elapsed time by hand.

NOTE: the 64bit operation needs a libc call. Use -fno-exceptions compile flag to avoid code size to blow up by 30KB for no reason.

Use:

  • A timer has to be instantiated. Longan_nano::Chrono my_timer;

  • my_timer.start() followed by my_timer.accumulate() fill the timestamps. my_timer.get_accumulator( Unit ) returns all the sum of all DeltaT occurred between start and accumulate

  • my_timer.start() followed by my_timer.accumulate ( Unit ) returns all the sum of all DeltaT occurred between start and accumulate




2.3Chrono Class Source Code






3Demo

This demo shows a practical implementation of an hardwired scheduler that issue the toggle of the RED led at 250mS, and the GREEN led at 750ms, by prescaling the fast tick for the RED led.

This scheduler monitors the overrun of tasks, and light a blue led if error occurs.



Illustration 2: Demo Tasks




Video 1: Demo Tasks


3.1Demo Source Code

Code for the demo to shows the hardwired scheduler, the prescaler, the overrun detection, the uptime measurement and the cpu time measurement.




4Conclusions

Time measurement and scheduling are fundamental to the operation of a fixed function hard real time microcontroller application.

In this document I laid out my solution and my implementation in the form of the Chrono class and fixed scheduler with execution flags. This solution does not use timer peripherals inside the microcontroller, perform unit conversion and works at full resolution and using C++ constructs.

This architecture will serve as the basis for all my applications based on the Longan nano GD32VF103.




No comments: