mwf_common
mwf_common
Defines common definitions and base classes for peripheral classes.
Macros
BEGIN_CRITICAL
, END_CRITICAL
(Disable Interrupts)
#define BEGIN_CRITICAL { uint32_t __TWENET_regPrimask = DisableGlobalIRQ();
#define END_CRITICAL() EnableGlobalIRQ(__TWENET_regPrimask); }
// Example
extern volatile int critical_value;
void some_func() {
...
// The following is a critical section
BEGIN_CRITICAL
{
critical_value++;
}
END_CRITICAL();
}
These macros are used to set a disabled interrupt section. While they simply call DisableGlobalIRQ()
and EnableGlobalIRQ()
, they are defined as a macro similar to the do {...} while()
construct to simplify the syntax, which can seem complex due to the need for a local variable.
In the example above, if critical_value
is a value that might be changed by an interrupt handler, this procedure safely updates the value within the application’s processing.
- This macro can only be used in C++ code.
Constants, Enumerations, etc.
enum class ID_SYSHAND
Defines IDs to identify peripheral class objects.
class sys_ev_handler
A high-level (abstract) class that defines an interface to standardize procedures for sleep and wake-up.
on_sleep()
Describes the peripheral’s procedures before sleep.
on_wakeup(bool init_2nd)
Describes the peripheral’s procedures to restore its pre-sleep state upon wake-up. This function is expected to be called twice.
- When
init_end
isfalse
, it is called at a very early stage after wake-up. It is primarily used for variable initialization, but no device re-initialization is performed here. The second time it is called, withtrue
, it re-initializes devices and restores the pre-sleep state. - In TWENET, this is handled during the
vAHI_OnWakeup_MW()
call. The call order is as follows. For details, refer totwenet_main.c
in TWENETmcu.- Call of the
WarmMain()
function (the first function called upon wake-up)vAHI_OnWakeup_MW(FALSE)
- The
on_wakeup(false)
of the mwf library object is called here
- The
ToCoNet_vInit_Warm_Pre()
cbAppWarmStart(FALSE)
(orinit_warm()
in mwx)
ToCoNet_vBoard_Init()
- Initialization of the wireless microcontroller hardware (clock, etc.)
vAHI_OnWakeup_MW(TRUE)
- The
on_wakeup(true)
of the mwf library object is called here
- The
ToCoNet_vInit_Warm()
cbAppWarmStart(TRUE)
(orsetup()
in mwx)
- TWENET initialization
- TWENET application loop
- Call of the
class sys_global_resource_handler<T>
A high-level class for managing initialization and destruction procedures when multiple instances of the same function are defined, such as I2C and PWM.
It is used when there are procedures that need to be performed only once upon initialization and procedures that need to be destroyed only after all instances have been used. (Even with these peripherals, this class may or may not be used depending on the implementation.)
The initialization and destruction procedures are performed based on a reference counter (passed from the constructor) that is updated whenever an object is created or destroyed.
sys_ev_handler
is an abstract class, but this class uses CRTP.
init()
When the reference counter becomes 1
(i.e., when initialization is needed), T::global_init()
is called.
- This member function must be explicitly called from the peripheral class constructor.
deinit()
When the reference counter becomes 0
, T::global_deinit()
is called.
- This member function must be explicitly called from the peripheral class destructor.
class sys_ev_manager
A collection class for managing peripheral class objects in a single place. However, it does not own the objects; it stores sys_ev_handler
class pointers in a fixed array, using the ID specified by the ID_SYSHAND
enumeration as an index.
Its main purpose is to perform on_sleep()
and on_wake()
procedures in a batch.
Since which peripheral class objects are created depends on the user’s program, calling if(the_pwm1) the_pwm1->on_sleep();
for every class object would be inefficient and link unnecessary code. Instead, it stores them as abstract objects of type sys_ev_handler
and calls their virtual
methods.
global_init_sysevmgr()
Creates the the_sys_ev_manager
instance.
global_deinit_sysevmgr()
Destroys the the_sys_ev_manager
instance.
reg_obj()
Registers a peripheral class object.
unreg_obj()
Deregisters a peripheral class object.
on_wakeup(bool init_2nd)
Executes on_wake()
for all registered objects.
void on_sleep()
Executes on_sleep()
for all registered objects.
Peripheral Class Definition Example
class timer_n_pwm :
public mwf::sys_ev_handler // Base class
, public mwf::sys_global_resource_handler<timer_n_pwm> // Base class (only if needed)
{
using global_hdr = mwf::sys_global_resource_handler<timer_n_pwm>;
// Define a shorthand because the name is long
static uint32_t _global_init_ct;
// Reference counter for sys_global_resource_handler
public:
static void global_init_pwm(uint8_t u8_pwm_id, ...) { ... }
static void global_deinit_pwm_manager(uint8_t u8_pwm_id) { ... }
// Procedures for creating and destroying the actual instance of the_pwm?.
public:
// Constructor
timer_n_pwm(/* Constructor arguments */)
: mwf::sys_ev_handler(/*ID*/ ,static_cast<sys_ev_handler*>(this))
, mwf::sys_global_resource_handler<timer_n_pwm>(_global_init_ct)
{
global_hdr::init(); // Procedure for creating sys_global_resource_handler<>
}
// Destructor (defined as virtual because it inherits from an abstract class)
virtual ~timer_n_pwm()
{
global_hdr::deinit(); // Procedure for destroying sys_global_resource_handler<>
}
// Implementation of the sys_ev_handler class
virtual void on_sleep() { ... } // Called before sleep
virtual void on_wakeup() { ... } // Called after waking up from sleep
// Implementation of sys_global_resource_handler<>. Static member function.
static void global_init(); // The very first initialization procedure
static void global_deinit(); // The very last destruction procedure
};
...
uint32_t mwf::periph::timer_n_pwm::_global_init_ct; // The actual reference counter
The above is an excerpt from the definition of the PWM (mwf_periph_pwm.hpp
) peripheral class. Most other classes do not use sys_global_resource_handler<>
.