This article describes the (very) simple operating system I use in my small microcontroller projects. "Operating system" is a definitely exaggerated but this might be interesting for somebody anyway.
It is a cooperative multitasking os. This means, that each task currently controlling the cpu must give back control to the other tasks or the cpu freezes (or resets if the watchdog is enabled). This is implemented with state machines and software timers within the tasks and not scope of this article.
I used this principle on Motorola (now Freescale) HC12, Renesas R8C, M32C and Microchip 16Fx and never had the need for a pre-emptive os.
The following source code shows the main system loop and nine included tasks. I used it to measure the speed of the os without any load on the micro. In other words, the programm just toggles three ports and executes some 'nop' as fast as possible.
#include "mcc_generated_files/mcc.h"
#include "defs.h"
#include "swt.h"
void MAIN_TaskHighPrio0(void);
void MAIN_TaskHighPrio1(void);
void MAIN_TaskHighPrio2(void);
void MAIN_TaskMediumPrio0(void);
void MAIN_TaskMediumPrio1(void);
void MAIN_TaskMediumPrio2(void);
void MAIN_TaskLowPrio0(void);
void MAIN_TaskLowPrio1(void);
void MAIN_TaskLowPrio2(void);
typedef void (*T_FKTPTR)(void);
const T_FKTPTR MAIN_func_high[] = {&MAIN_TaskHighPrio0,&MAIN_TaskHighPrio1,
&MAIN_TaskHighPrio2};
const T_FKTPTR MAIN_func_medium[] = {&MAIN_TaskMediumPrio0,&MAIN_TaskMediumPrio1,
&MAIN_TaskMediumPrio2};
const T_FKTPTR MAIN_func_low[] = {&MAIN_TaskLowPrio0,&MAIN_TaskLowPrio1,
&MAIN_TaskLowPrio2};
const unsigned char MAIN_FUNC_HIGH_ENTRIES = sizeof (MAIN_func_high) / sizeof (T_FKTPTR);
const unsigned char MAIN_FUNC_MEDIUM_ENTRIES = sizeof (MAIN_func_medium) / sizeof (T_FKTPTR);
const unsigned char MAIN_FUNC_LOW_ENTRIES = sizeof (MAIN_func_low) / sizeof (T_FKTPTR);
void main(void)
{
// initialize the device
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
//INTERRUPT_GlobalInterruptDisable();
//INTERRUPT_PeripheralInterruptDisable();
//infinite system loop
static unsigned char low;
static unsigned char medium;
static unsigned char high;
while (1) {
for (low = 0; low < MAIN_FUNC_LOW_ENTRIES; low++) {
for (medium = 0; medium < MAIN_FUNC_MEDIUM_ENTRIES; medium++) {
for (high = 0; high < MAIN_FUNC_HIGH_ENTRIES; high++) {
MAIN_func_high[high]();
}
MAIN_func_medium[medium]();
}
MAIN_func_low[low]();
}
}
}
void MAIN_TaskHighPrio0(void) { LATC5 ^= 1; }
void MAIN_TaskHighPrio1(void) { asm("nop"); }
void MAIN_TaskHighPrio2(void) { asm("nop"); }
void MAIN_TaskMediumPrio0(void) { LATC6 ^= 1; }
void MAIN_TaskMediumPrio1(void) { asm("nop"); }
void MAIN_TaskMediumPrio2(void) { asm("nop"); }
void MAIN_TaskLowPrio0(void) { LATC7 ^= 1; }
void MAIN_TaskLowPrio1(void) { asm("nop"); }
void MAIN_TaskLowPrio2(void) { asm("nop"); }
These figures also include the system initialisation, interrupt manager, tmr0 interrupt, software timer and the pin manager.
The following screen shots show the measurements and a schematic overview of the timing of the source code above. There was as 1 ms timer interrupt running in the background, but that should not had to much impact on the measurement.
Other constraints:
Publish date: 2014-09-14
This tool lets you receive the hardcopy from a THS720 oscilloscope via the serial port and save it to a file. It is only tested with a THS720 but might work with others of this series too.
Publish date: 2014-06-29
This small Python program is a simple substitute for the Windows software that was shipped with my multimeter about 20 years ago. The program is written for Linux but should run on Windows too with some minor modifications concerning the serial port.
Since the technical support from BEHA/Fluke could not provide any software or technical specification of the communication protocol, I sat down and decoded the essential part of the communication protocol. That job was quite annoying but succeeded at last.
Please provide feedback if you use the program.
Publish date: 2014-06-23
This little accessory helps finding the right parameters for the timer modules 2/4/6 of Microchip PICs. Just type in the required time period for the timer and let the computer do the calculation. I "tested" it on a PIC16F1825.
Publish date: 2014-05-17
Last update: 2014-06-09
This g-code generator for milling is a Python program with focus on the use with LinuxCNC.
For hobbyist use only. Do not expect a perfect finish and simulate the generated g-code before milling!
Publish date: 2014-01-02
Last update: 2017-08-14
The command line tool pcb2gcode is used to generate G-code from Gerber files. This GUI intends to ease the use of the tool.
This is my first Python program, so please do not be too stern concerning the source code. Have a look into the source code header for details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Found a bug? Want to contribute? General feedback? Please let me know.
At this point, thanks for the useful feedback I got so far. Keep it up!
The complete version history is included in the header of the source code.
Publish date: 2013-02-03
Last update: 2014-04-06
FlatCAM - Free and Open-source PCB CAM
python.org - The Python programming language
Unicodetables - ASCII + Unicode tables
Last update: 2014-04-27